| Trees | Indices | Help |
|
|---|
|
|
1 """
2 DBus related functionality including the DBus interface and utility
3 functions
4
5 Copyright: John Stowers, 2006
6 License: GPLv2
7 """
8 import os.path
9 import dbus
10 import dbus.service
11 import logging
12 log = logging.getLogger("DBus")
13
14 import conduit
15 import conduit.utils as Utils
16 import conduit.Conduit as Conduit
17 import conduit.SyncSet as SyncSet
18
19 ERROR = -1
20 SUCCESS = 0
21
22 DEBUG_ALL_CALLS = True
23
24 APPLICATION_DBUS_IFACE="org.conduit.Application"
25 SYNCSET_DBUS_IFACE="org.conduit.SyncSet"
26 CONDUIT_DBUS_IFACE="org.conduit.Conduit"
27 EXPORTER_DBUS_IFACE="org.conduit.Exporter"
28 DATAPROVIDER_DBUS_IFACE="org.conduit.DataProvider"
29
30 ################################################################################
31 # DBus API Docs
32 ################################################################################
33 #
34 # ==== Main Application ====
35 # Service org.conduit.Application
36 # Interface org.conduit.Application
37 # Object path /
38 #
39 # Methods:
40 # BuildConduit(source, sink)
41 # BuildExporter(self, sinkKey)
42 # ListAllDataProviders
43 # GetDataProvider
44 # NewSyncSet
45 # Quit
46 #
47 # Signals:
48 # DataproviderAvailable(key)
49 # DataproviderUnavailable(key)
50 #
51 # ==== SyncSet ====
52 # Service org.conduit.SyncSet
53 # Interface org.conduit.SyncSet
54 # Object path /syncset/{dbus, gui, UUID}
55 #
56 # Methods:
57 # AddConduit
58 # DeleteConduit
59 # SaveToXml
60 # RestoreFromXml
61 #
62 # Signals:
63 # ConduitAdded(key)
64 # ConduitRemoved(key)
65 #
66 # ==== Conduit ====
67 # Service org.conduit.Conduit
68 # Interface org.conduit.Conduit
69 # Object path /conduit/{some UUID}
70 #
71 # Methods:
72 # EnableTwoWaySync
73 # DisableTwoWaySync
74 # IsTwoWay
75 # AddDataprovider
76 # DeleteDataprovider
77 # Sync
78 # Refresh
79 #
80 # Signals:
81 # SyncStarted
82 # SyncCompleted(aborted, error, conflict)
83 # SyncConflict
84 # SyncProgress(progress, completedUIDs)
85 # DataproviderAdded
86 # DataproviderRemoved
87 #
88 # ==== Exporter Conduit ====
89 # Service org.conduit.Conduit
90 # Interface org.conduit.Exporter
91 # Object path /conduit/{some UUID}
92 #
93 # Methods:
94 # AddData
95 # SinkConfigure
96 # SinkGetInformation
97 # SinkGetConfigurationXml
98 # SinkSetConfigurationXml
99 #
100 # ==== DataProvider ====
101 # Service org.conduit.DataProvider
102 # Interface org.conduit.DataProvider
103 # Object path /dataprovider/{some UUID}
104 #
105 # Methods:
106 # IsPending
107 # IsConfigured
108 # SetConfigurationXML
109 # GetConfigurationXML
110 # Configure
111 # GetInformation
112 # AddData
113 #
114 # Signals:
115
116 #All objects currently exported over the bus
117 EXPORTED_OBJECTS = {}
118
120 _dbus_error_name = 'org.conduit.ConduitException'
121
124 bus_name = dbus.service.BusName(iface, bus=dbus.SessionBus())
125 dbus.service.Object.__init__(self, bus_name, path)
126
127 log.debug("DBus Exported: %s" % self.get_path())
128
131
135
138 DBusItem.__init__(self, iface=CONDUIT_DBUS_IFACE, path="/conduit/%s" % uuid)
139
140 self.sync_manager = sync_manager
141 self.conduit = conduit
142
143 self.conduit.connect("sync-started", self._on_sync_started)
144 self.conduit.connect("sync-completed", self._on_sync_completed)
145 self.conduit.connect("sync-conflict", self._on_sync_conflict)
146 self.conduit.connect("sync-progress", self._on_sync_progress)
147
151
155
159
163
164 #
165 # org.conduit.Conduit
166 #
167 @dbus.service.method(CONDUIT_DBUS_IFACE, in_signature='', out_signature='')
171
172 @dbus.service.method(CONDUIT_DBUS_IFACE, in_signature='', out_signature='')
176
177 @dbus.service.method(CONDUIT_DBUS_IFACE, in_signature='', out_signature='b')
181
182 @dbus.service.method(CONDUIT_DBUS_IFACE, in_signature='ob', out_signature='')
184 self._print("AddDataprovider: %s" % dp)
185
186 #get the actual dps from their object paths
187 try:
188 dpw = EXPORTED_OBJECTS[str(dp)].dataprovider
189 except KeyError, e:
190 raise ConduitException("Could not locate dataprovider: %s" % e)
191
192 if not self.conduit.add_dataprovider(dpw):
193 raise ConduitException("Could not add dataprovider: %s" % e)
194
195 @dbus.service.method(CONDUIT_DBUS_IFACE, in_signature='o', out_signature='')
197 self._print("DeleteDataprovider: %s" % dp)
198
199 #get the actual dps from their object paths
200 try:
201 dpw = EXPORTED_OBJECTS[str(dp)].dataprovider
202 except KeyError, e:
203 raise ConduitException("Could not locate dataprovider: %s" % e)
204
205 if not self.conduit.delete_dataprovider(dpw):
206 raise ConduitException("Could not delete dataprovider: %s" % e)
207
208
209 @dbus.service.method(CONDUIT_DBUS_IFACE, in_signature='', out_signature='')
213
214 @dbus.service.method(CONDUIT_DBUS_IFACE, in_signature='', out_signature='')
218
219 @dbus.service.signal(CONDUIT_DBUS_IFACE, signature='')
221 self._print("SyncStarted")
222
223 @dbus.service.signal(CONDUIT_DBUS_IFACE, signature='bbb')
225 self._print("SyncCompleted (abort:%s error:%s conflict:%s)" % (aborted,error,conflict))
226
227 @dbus.service.signal(CONDUIT_DBUS_IFACE, signature='')
229 self._print("SyncConflict")
230
231 @dbus.service.signal(CONDUIT_DBUS_IFACE, signature='das')
233 self._print("SyncProgress %s%%\n\t%s" % ((progress*100.0), UIDs))
234
235 #
236 # org.conduit.Exporter
237 #
238 @dbus.service.method(EXPORTER_DBUS_IFACE, in_signature='s', out_signature='')
240 self._print("SinkSetConfigurationXml: %s" % xml)
241 if len(self.conduit.datasinks) != 1:
242 raise ConduitException("Simple exporter must only have one sink")
243 self.conduit.datasinks[0].set_configuration_xml(xml)
244
245 @dbus.service.method(EXPORTER_DBUS_IFACE, in_signature='', out_signature='')
247 self._print("SinkConfigure")
248 if len(self.conduit.datasinks) != 1:
249 raise ConduitException("Simple exporter must only have one sink")
250 self.conduit.datasinks[0].configure(None)
251
252 @dbus.service.method(EXPORTER_DBUS_IFACE, in_signature='s', out_signature='b')
254 self._print("AddData: %s" % uri)
255 if self.conduit.datasource == None:
256 raise ConduitException("Simple exporter must have a source")
257
258 return self.conduit.datasource.module.add(uri)
259
260 @dbus.service.method(EXPORTER_DBUS_IFACE, in_signature='', out_signature='a{ss}')
262 self._print("SinkGetInformation")
263 if len(self.conduit.datasinks) != 1:
264 raise ConduitException("Simple exporter must only have one sink")
265
266 #Need to call get_icon so that the icon_name/path is loaded
267 try:
268 self.conduit.datasinks[0].get_icon()
269 except:
270 log.warn("DBus could not lookup dp icon")
271
272 info = {}
273 info["name"] = self.conduit.datasinks[0].name
274 info["description"] = self.conduit.datasinks[0].description
275 info["module_type"] = self.conduit.datasinks[0].module_type
276 info["category"] = self.conduit.datasinks[0].category.name
277 info["in_type"] = self.conduit.datasinks[0].get_input_type()
278 info["out_type"] = self.conduit.datasinks[0].get_output_type()
279 info["classname"] = self.conduit.datasinks[0].classname
280 info["key"] = self.conduit.datasinks[0].get_key()
281 info["enabled"] = str( self.conduit.datasinks[0].enabled)
282 info["UID"] = self.conduit.datasinks[0].get_UID()
283 info["icon_name"] = self.conduit.datasinks[0].icon_name
284 info["icon_path"] = self.conduit.datasinks[0].icon_path
285 return info
286
287 @dbus.service.method(EXPORTER_DBUS_IFACE, in_signature='', out_signature='s')
289 self._print("SinkGetConfigurationXml")
290 if len(self.conduit.datasinks) != 1:
291 raise ConduitException("Simple exporter must only have one sink")
292 return self.conduit.datasinks[0].get_configuration_xml()
293
296 DBusItem.__init__(self, iface=DATAPROVIDER_DBUS_IFACE, path="/dataprovider/%s" % uuid)
297
298 self.dataprovider = dataprovider
299
300 @dbus.service.method(DATAPROVIDER_DBUS_IFACE, in_signature='', out_signature='b')
304
305 @dbus.service.method(DATAPROVIDER_DBUS_IFACE, in_signature='bb', out_signature='b')
307 self._print("IsConfigured")
308 if self.dataprovider.module != None:
309 return self.dataprovider.module.is_configured(isSource, isTwoWay)
310 return False
311
312 @dbus.service.method(DATAPROVIDER_DBUS_IFACE, in_signature='', out_signature='a{ss}')
314 self._print("GetInformation")
315 #Need to call get_icon so that the icon_name/path is loaded
316 try:
317 self.dataprovider.get_icon()
318 except:
319 log.warn("DBus could not lookup dp icon")
320
321 info = {}
322 info["name"] = self.dataprovider.name
323 info["description"] = self.dataprovider.description
324 info["module_type"] = self.dataprovider.module_type
325 info["category"] = self.dataprovider.category.name
326 info["in_type"] = self.dataprovider.get_input_type()
327 info["out_type"] = self.dataprovider.get_output_type()
328 info["classname"] = self.dataprovider.classname
329 info["key"] = self.dataprovider.get_key()
330 info["enabled"] = str(self.dataprovider.enabled)
331 info["UID"] = self.dataprovider.get_UID()
332 info["icon_name"] = self.dataprovider.icon_name
333 info["icon_path"] = self.dataprovider.icon_path
334
335 return info
336
337 @dbus.service.method(DATAPROVIDER_DBUS_IFACE, in_signature='', out_signature='s')
341
342 @dbus.service.method(DATAPROVIDER_DBUS_IFACE, in_signature='s', out_signature='')
346
347 @dbus.service.method(DATAPROVIDER_DBUS_IFACE, in_signature='', out_signature='')
351
352 @dbus.service.method(DATAPROVIDER_DBUS_IFACE, in_signature='s', out_signature='b')
356
359 DBusItem.__init__(self, iface=SYNCSET_DBUS_IFACE, path="/syncset/%s" % name)
360
361 self.syncSet = syncSet
362 self.syncSet.connect("conduit-added", self._on_conduit_added)
363 self.syncSet.connect("conduit-removed", self._on_conduit_removed)
364
366 self.ConduitAdded()
367
369 self.ConduitRemoved()
370
371 @dbus.service.signal(SYNCSET_DBUS_IFACE, signature='')
373 self._print("Emmiting DBus signal ConduitAdded")
374
375 @dbus.service.signal(SYNCSET_DBUS_IFACE, signature='')
377 self._print("Emmiting DBus signal ConduitRemoved")
378
379 @dbus.service.method(SYNCSET_DBUS_IFACE, in_signature='o', out_signature='')
381 self._print("AddConduit: %s" % cond)
382
383 try:
384 c = EXPORTED_OBJECTS[str(cond)].conduit
385 except KeyError, e:
386 raise ConduitException("Could not locate Conduit: %s" % e)
387
388 self.syncSet.add_conduit(c)
389
390 @dbus.service.method(SYNCSET_DBUS_IFACE, in_signature='o', out_signature='')
392 self._print("DeleteConduit: %s" % cond)
393
394 try:
395 c = EXPORTED_OBJECTS[str(cond)].conduit
396 except KeyError, e:
397 raise ConduitException("Could not locate Conduit: %s" % e)
398
399 self.syncSet.remove_conduit(c)
400
401 @dbus.service.method(SYNCSET_DBUS_IFACE, in_signature='s', out_signature='')
405
406 @dbus.service.method(SYNCSET_DBUS_IFACE, in_signature='s', out_signature='')
408 self._print("RestoreFromXml: %s" % path)
409 self.syncSet.restore_from_xml(os.path.abspath(path))
410
412 - def __init__(self, conduitApplication, moduleManager, typeConverter, syncManager, guiSyncSet, dbusSyncSet):
413 DBusItem.__init__(self, iface=APPLICATION_DBUS_IFACE, path="/")
414
415 self.conduitApplication = conduitApplication
416
417 #setup the module manager
418 self.moduleManager = moduleManager
419 self.moduleManager.connect("dataprovider-available", self._on_dataprovider_available)
420 self.moduleManager.connect("dataprovider-unavailable", self._on_dataprovider_unavailable)
421
422 #type converter and sync manager
423 self.type_converter = typeConverter
424 self.sync_manager = syncManager
425
426
427 #export the syncsets
428 if guiSyncSet != None:
429 new = SyncSetDBusItem(guiSyncSet, "gui")
430 EXPORTED_OBJECTS[new.get_path()] = new
431
432 if dbusSyncSet != None:
433 new = SyncSetDBusItem(dbusSyncSet, "dbus")
434 EXPORTED_OBJECTS[new.get_path()] = new
435
436 #export myself
437 EXPORTED_OBJECTS[self.get_path()] = self
438
440 datasources = self.moduleManager.get_modules_by_type("source")
441 datasinks = self.moduleManager.get_modules_by_type("sink")
442 twoways = self.moduleManager.get_modules_by_type("twoway")
443 return datasources + datasinks + twoways
444
446 ss = SyncSet.SyncSet(
447 moduleManager=self.moduleManager,
448 syncManager=self.sync_manager
449 )
450 i = Utils.uuid_string()
451 new = SyncSetDBusItem(ss, i)
452 EXPORTED_OBJECTS[new.get_path()] = new
453 return new
454
456 """
457 Instantiates a new dataprovider (source or sink), storing it
458 appropriately.
459 @param key: Key of the DP to create
460 @returns: The new DP
461 """
462 dpw = self.moduleManager.get_module_wrapper_with_instance(key)
463 if dpw == None:
464 raise ConduitException("Could not find dataprovider with key: %s" % key)
465
466 i = Utils.uuid_string()
467 new = DataProviderDBusItem(dpw, i)
468 EXPORTED_OBJECTS[new.get_path()] = new
469 return new
470
472 """
473 Instantiates a new dataprovider (source or sink), storing it
474 appropriately.
475 @param key: Key of the DP to create
476 @returns: The new DP
477 """
478 if sender == None:
479 raise ConduitException("Invalid DBus Caller")
480
481 cond = Conduit.Conduit(self.sync_manager)
482 if source != None:
483 if not cond.add_dataprovider(dataprovider_wrapper=source, trySourceFirst=True):
484 raise ConduitException("Error adding source to conduit")
485 if sink != None:
486 if not cond.add_dataprovider(dataprovider_wrapper=sink, trySourceFirst=False):
487 raise ConduitException("Error adding source to conduit")
488
489 i = Utils.uuid_string()
490 new = ConduitDBusItem(self.sync_manager, cond, i)
491 EXPORTED_OBJECTS[new.get_path()] = new
492 return new
493
496
499
500 @dbus.service.signal(APPLICATION_DBUS_IFACE, signature='s')
502 self._print("Emmiting DBus signal DataproviderAvailable %s" % key)
503
504 @dbus.service.signal(APPLICATION_DBUS_IFACE, signature='s')
507
508 @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='o')
512
513 @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='as')
517
518 @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='s', out_signature='o')
522
523 @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='oo', out_signature='o', sender_keyword='sender')
525 self._print("BuildConduit (sender: %s:) %s --> %s" % (sender, source, sink))
526
527 #get the actual dps from their object paths
528 try:
529 source = EXPORTED_OBJECTS[str(source)].dataprovider
530 sink = EXPORTED_OBJECTS[str(sink)].dataprovider
531 except KeyError, e:
532 raise ConduitException("Could not find dataprovider with key: %s" % e)
533
534 return self._get_conduit(source, sink, sender)
535
536 @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='s', out_signature='o', sender_keyword='sender')
538 self._print("BuildExporter (sender: %s:) --> %s" % (sender,key))
539
540 source = self._get_dataprovider("FileSource")
541 sink = self._get_dataprovider(key)
542
543 return self._get_conduit(source.dataprovider, sink.dataprovider, sender)
544
545 @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='')
549
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0beta1 on Sat Aug 2 22:18:46 2008 | http://epydoc.sourceforge.net |