16
16
# You should have received a copy of the GNU General Public License along
17
17
# with this program. If not, see <http://www.gnu.org/licenses/>.
18
18
""" DBUS interface module """
19
from itertools import groupby, chain
19
21
import dbus.service
21
23
from ubuntuone.syncdaemon.event_queue import EVENTS
46
48
logger = logging.getLogger("ubuntuone.SyncDaemon.DBus")
50
def get_classname(thing):
52
Get the clasname of the thing.
53
If we could forget 2.5, we could do attrgetter('__class__.__name__')
54
Alas, we can't forget it yet.
56
return thing.__class__.__name__
49
59
class DBusExposedObject(dbus.service.Object):
50
60
""" Base class that provides some helper methods to
195
205
""" Fire a D-BUS signal, notifying a download has started. """
198
@dbus.service.signal(DBUS_IFACE_STATUS_NAME)
199
def DownloadFinished(self, path):
208
@dbus.service.signal(DBUS_IFACE_STATUS_NAME,
210
def DownloadFinished(self, path, info):
200
211
""" Fire a D-BUS signal, notifying a download has finished. """
205
216
""" Fire a D-BUS signal, notifying an upload has started. """
208
@dbus.service.signal(DBUS_IFACE_STATUS_NAME)
209
def UploadFinished(self, path):
219
@dbus.service.signal(DBUS_IFACE_STATUS_NAME,
221
def UploadFinished(self, path, info):
210
222
""" Fire a D-BUS signal, notifying an upload has finished. """
232
@dbus.service.signal(DBUS_IFACE_STATUS_NAME, signature='a{sa{ss}}')
233
def ContentQueueChanged(self, message):
235
Fire a D-BUS signal, notifying that the content queue has
239
def emit_content_queue_changed(self, head, waiting):
247
waiting = chain((head,), waiting)
248
head_cmd = get_classname(head)
250
if IMarker.providedBy(head.node_id):
251
# it's a marker! so it's the mdid :)
252
relpath = self.fs_manager.get_by_mdid(head.node_id).path
254
relpath = self.fs_manager.get_by_node_id(head.share_id,
259
head_path = self.fs_manager.get_abspath(head.share_id, relpath)
261
(k, {'size': '0', 'count': str(len(tuple(v)))})
262
for (k, v) in groupby(sorted(map(get_classname, waiting))))
263
message['head'] = {'path': head_path,
266
self.ContentQueueChanged(message)
220
268
def emit_status_changed(self, state):
221
269
""" Emits the signal """
222
270
state_dict = {'name':state.name,
230
278
""" Emits the signal """
231
279
self.DownloadStarted(download)
233
def emit_download_finished(self, download):
281
def emit_download_finished(self, download, **info):
234
282
""" Emits the signal """
235
self.DownloadFinished(download)
283
for k, v in info.copy().items():
284
info[str(k)] = str(v)
285
self.DownloadFinished(download, info)
237
287
def emit_upload_started(self, upload):
238
288
""" Emits the signal """
239
289
self.UploadStarted(upload)
241
def emit_upload_finished(self, upload):
291
def emit_upload_finished(self, upload, **info):
242
292
""" Emits the signal """
243
self.UploadFinished(upload)
293
for k, v in info.copy().items():
294
info[str(k)] = str(v)
295
self.UploadFinished(upload, info)
246
298
class Events(DBusExposedObject):
337
393
node_id=str(node_id))
338
394
self.dbus_iface.status.emit_signal_error('DownloadFinished', args)
396
def handle_AQ_DOWNLOAD_ERROR(self, share_id, node_id, server_hash, error):
397
""" handle AQ_DOWNLOAD_ERROR """
398
self.handle_default('AQ_DOWNLOAD_ERROR', share_id, node_id,
401
mdobj = self.dbus_iface.fs_manager.get_by_node_id(share_id, node_id)
404
path = self.dbus_iface.fs_manager.get_abspath(share_id, mdobj.path)
405
self.dbus_iface.status.emit_download_finished(path, error=error)
407
# file is gone before we got this
408
args = dict(message='The md is gone before sending '
409
'DownloadFinished signal',
411
share_id=str(share_id),
412
node_id=str(node_id),
413
download_error=str(error))
414
self.dbus_iface.status.emit_signal_error('DownloadFinished', args)
340
416
def handle_AQ_UPLOAD_STARTED(self, share_id, node_id, hash):
341
417
""" handle AQ_UPLOAD_STARTED """
342
418
self.handle_default('AQ_UPLOAD_STARTED', share_id, node_id, hash)
344
420
mdobj = self.dbus_iface.fs_manager.get_by_node_id(share_id, node_id)
345
423
path = self.dbus_iface.fs_manager.get_abspath(share_id, mdobj.path)
346
424
self.dbus_iface.status.emit_upload_started(path)
347
425
except KeyError, e:
357
435
self.handle_default('AQ_UPLOAD_FINISHED', share_id, node_id, hash)
359
437
mdobj = self.dbus_iface.fs_manager.get_by_node_id(share_id, node_id)
360
440
path = self.dbus_iface.fs_manager.get_abspath(share_id, mdobj.path)
361
441
self.dbus_iface.status.emit_upload_finished(path)
362
442
except KeyError, e:
368
448
node_id=str(node_id))
369
449
self.dbus_iface.status.emit_signal_error('UploadFinished', args)
451
def handle_AQ_UPLOAD_ERROR(self, share_id, node_id, error, hash):
452
""" handle AQ_UPLOAD_ERROR """
453
self.handle_default('AQ_UPLOAD_ERROR', share_id, node_id, error, hash)
455
mdobj = self.dbus_iface.fs_manager.get_by_node_id(share_id, node_id)
458
path = self.dbus_iface.fs_manager.get_abspath(share_id, mdobj.path)
459
self.dbus_iface.status.emit_upload_finished(path, error=error)
461
# file is gone before we got this
462
args = dict(message='The metadata is gone before sending '
463
'UploadFinished signal',
465
share_id=str(share_id),
466
node_id=str(node_id),
467
upload_error=str(error))
468
self.dbus_iface.status.emit_signal_error('UploadFinished', args)
371
470
def handle_SYS_STATE_CHANGED(self, state):
372
471
""" handle SYS_STATE_CHANGED """
373
472
self.handle_default('SYS_STATE_CHANGED', state)