20
20
"""A backend for the Ubuntu One Control Panel."""
22
from collections import defaultdict
22
24
from twisted.internet.defer import inlineCallbacks, returnValue
24
26
from ubuntuone.controlpanel import dbus_client
62
64
class ControlBackend(object):
63
65
"""The control panel backend."""
70
NAME_NOT_SET = u'ENAMENOTSET'
65
72
def __init__(self):
66
73
"""Initialize the webclient."""
67
74
self.wc = WebClient(dbus_client.get_credentials)
68
75
self._status_changed_handler = None
69
76
self.status_changed_handler = lambda *a: None
78
self._volumes = {} # cache last known volume info
71
80
def _process_file_sync_status(self, status):
72
81
"""Process raw file sync status into custom format.
329
338
def volumes_info(self):
330
339
"""Get the volumes info."""
331
342
account = yield self.account_info()
332
343
root_dir = yield dbus_client.get_root_dir()
344
shares_dir = yield dbus_client.get_shares_dir()
345
shares_dir_link = yield dbus_client.get_shares_dir_link()
333
346
folders = yield dbus_client.get_folders()
347
shares = yield dbus_client.get_shares()
335
349
free_bytes = int(account['quota_total']) - int(account['quota_used'])
336
350
root_volume = {u'volume_id': u'', u'path': root_dir,
337
u'subscribed': 'True', u'type': u'ROOT'}
351
u'subscribed': 'True', u'type': self.ROOT_TYPE}
352
self._volumes[u''] = root_volume
354
# group shares by the offering user
355
shares_result = defaultdict(list)
357
share[u'type'] = self.SHARE_TYPE
359
vid = share['volume_id']
360
assert vid not in self._volumes
361
self._volumes[vid] = share
363
if not bool(share['accepted']):
366
nicer_path = share[u'path'].replace(shares_dir, shares_dir_link)
367
share[u'path'] = nicer_path
369
username = share['other_visible_name']
371
username = u'%s (%s)' % (share['other_username'],
374
shares_result[username].append(share)
376
for folder in folders:
377
folder[u'type'] = self.FOLDER_TYPE
379
vid = folder['volume_id']
380
assert vid not in self._volumes
381
self._volumes[vid] = folder
339
383
result = [(u'', unicode(free_bytes), [root_volume] + folders)]
341
# later, we may request shares info as well
385
for other_username, shares in shares_result.iteritems():
386
result.append((other_username, shares[0][u'free_bytes'], shares))
342
388
returnValue(result)
344
390
@log_call(logger.debug)
360
406
def subscribe_volume(self, volume_id):
361
407
"""Subscribe to 'volume_id'."""
362
# when dealing with shares, we need to check if 'volume_id'
363
# is a folder or a share
364
yield dbus_client.subscribe_folder(volume_id)
408
if self._volumes[volume_id][u'type'] == self.FOLDER_TYPE:
409
yield dbus_client.subscribe_folder(volume_id)
410
elif self._volumes[volume_id][u'type'] == self.SHARE_TYPE:
411
yield dbus_client.subscribe_share(volume_id)
367
414
def unsubscribe_volume(self, volume_id):
368
415
"""Unsubscribe from 'volume_id'."""
369
# when dealing with shares, we need to check if 'volume_id'
370
# is a folder or a share
371
yield dbus_client.unsubscribe_folder(volume_id)
416
if self._volumes[volume_id][u'type'] == self.FOLDER_TYPE:
417
yield dbus_client.unsubscribe_folder(volume_id)
418
elif self._volumes[volume_id][u'type'] == self.SHARE_TYPE:
419
yield dbus_client.unsubscribe_share(volume_id)
373
421
@log_call(logger.debug)