Merge lp:~nataliabidart/ubuntuone-control-panel/improve-volume-retrieval into lp:ubuntuone-control-panel

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 50
Merged at revision: 49
Proposed branch: lp:~nataliabidart/ubuntuone-control-panel/improve-volume-retrieval
Merge into: lp:ubuntuone-control-panel
Diff against target: 308 lines (+134/-46)
7 files modified
ubuntuone/controlpanel/backend.py (+10/-1)
ubuntuone/controlpanel/dbus_client.py (+8/-0)
ubuntuone/controlpanel/dbus_service.py (+15/-1)
ubuntuone/controlpanel/integrationtests/test_dbus_client_sd.py (+28/-0)
ubuntuone/controlpanel/integrationtests/test_dbus_service.py (+4/-20)
ubuntuone/controlpanel/tests/__init__.py (+49/-23)
ubuntuone/controlpanel/tests/test_backend.py (+20/-1)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-control-panel/improve-volume-retrieval
Reviewer Review Type Date Requested Status
Alejandro J. Cura (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+46916@code.launchpad.net

Commit message

- Backend provides a richer list of volumes, including the root info (LP: #705444).

Description of the change

The backend provides a richer volumes list info as per the new doc:

volumes_info
This is called by the gui to find out the volumes info for the current logged in user. The signals returned are:

       * VolumesInfoReady with a list of volume information. Each volume is represented by a tuple with 3 fields: the volume owner (empty string for current user), the amount of free bytes in the volume, and a list of "volumes_dict". Each "volumes_dict" has (at least) the following values (depending on the type, there might be extra parameters):
          o "volume_id" (unicode representation of an uuid)
          o “path” (unicode)
          o "suggested_path" (unicode)
          o "subscribed" (boolean, same convention as before)
          o "type" (unicode, either ROOT, UDF or SHARE)
    * VolumesInfoError with the error

To post a comment you must log in.
Revision history for this message
Roberto Alsina (ralsina) wrote :

+1 but I only looked at the code.

Revision history for this message
Roberto Alsina (ralsina) wrote :

And I forgot to approve in the previous comment ;-)

review: Approve
Revision history for this message
Alejandro J. Cura (alecu) wrote :

Code looks good, all tests pass.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ubuntuone/controlpanel/backend.py'
2--- ubuntuone/controlpanel/backend.py 2011-01-18 21:24:31 +0000
3+++ ubuntuone/controlpanel/backend.py 2011-01-20 17:38:08 +0000
4@@ -327,7 +327,16 @@
5 @inlineCallbacks
6 def volumes_info(self):
7 """Get the volumes info."""
8- result = yield dbus_client.get_folders()
9+ account = yield self.account_info()
10+ root_dir = yield dbus_client.get_root_dir()
11+ folders = yield dbus_client.get_folders()
12+
13+ free_bytes = int(account['quota_total']) - int(account['quota_used'])
14+ root_volume = {u'volume_id': u'', u'path': root_dir,
15+ u'subscribed': 'True', u'type': u'ROOT'}
16+
17+ result = [(u'', unicode(free_bytes), [root_volume] + folders)]
18+
19 # later, we may request shares info as well
20 returnValue(result)
21
22
23=== modified file 'ubuntuone/controlpanel/dbus_client.py'
24--- ubuntuone/controlpanel/dbus_client.py 2011-01-18 13:42:12 +0000
25+++ ubuntuone/controlpanel/dbus_client.py 2011-01-20 17:38:08 +0000
26@@ -213,6 +213,14 @@
27 return d
28
29
30+def get_root_dir():
31+ """Retrieve the root information from syncdaemon."""
32+ d = defer.Deferred()
33+ proxy = get_syncdaemon_proxy("/", sd_dbus_iface.DBUS_IFACE_SYNC_NAME)
34+ proxy.get_rootdir(reply_handler=d.callback, error_handler=d.errback)
35+ return d
36+
37+
38 def get_folders():
39 """Retrieve the folders information from syncdaemon."""
40 d = defer.Deferred()
41
42=== modified file 'ubuntuone/controlpanel/dbus_service.py'
43--- ubuntuone/controlpanel/dbus_service.py 2011-01-18 20:35:47 +0000
44+++ ubuntuone/controlpanel/dbus_service.py 2011-01-20 17:38:08 +0000
45@@ -19,6 +19,8 @@
46
47 """Export the control backend thru DBus."""
48
49+from functools import wraps
50+
51 import dbus.service
52 import gobject
53
54@@ -93,6 +95,18 @@
55 return inner
56
57
58+def debug(f):
59+ """Debug the call to 'f'."""
60+
61+ @wraps(f)
62+ def inner(self, *args, **kwargs):
63+ """Fake the call to 'f'."""
64+ print '\n===', self, f, args, kwargs
65+ return f(self, *args, **kwargs)
66+
67+ return inner
68+
69+
70 class ControlPanelBackend(dbus.service.Object):
71 """Export the Control Panel backend thru DBus."""
72
73@@ -413,7 +427,7 @@
74 d.addErrback(transform_failure(self.VolumesInfoError))
75
76 @log_call(logger.debug)
77- @signal(dbus_interface=DBUS_PREFERENCES_IFACE, signature="aa{ss}")
78+ @signal(dbus_interface=DBUS_PREFERENCES_IFACE, signature="a(ssaa{ss})")
79 def VolumesInfoReady(self, info):
80 """The info for the volumes is available right now."""
81
82
83=== modified file 'ubuntuone/controlpanel/integrationtests/test_dbus_client_sd.py'
84--- ubuntuone/controlpanel/integrationtests/test_dbus_client_sd.py 2011-01-18 13:42:12 +0000
85+++ ubuntuone/controlpanel/integrationtests/test_dbus_client_sd.py 2011-01-20 17:38:08 +0000
86@@ -543,3 +543,31 @@
87 yield dbus_client.stop_file_sync()
88
89 self.assertEqual(self._called, ((), {}))
90+
91+
92+class MockDBusSyncDaemon(dbus.service.Object):
93+ """A mock object that mimicks syncdaemon."""
94+
95+ ROOT_DIR = u'/yadda/yoda/Test me'
96+
97+ @dbus.service.method(sd_dbus_iface.DBUS_IFACE_SYNC_NAME,
98+ in_signature='', out_signature='s')
99+ def get_rootdir(self):
100+ """Return the root dir/mount point."""
101+ return self.ROOT_DIR
102+
103+
104+class BasicTestCase(DBusClientTestCase):
105+ """Test for the basic dbus client methods."""
106+
107+ def setUp(self):
108+ super(BasicTestCase, self).setUp()
109+ self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
110+ "/", MockDBusSyncDaemon)
111+
112+ @inlineCallbacks
113+ def test_get_root_dir(self):
114+ """Retrieve current syncdaemon root dir."""
115+ root = yield dbus_client.get_root_dir()
116+
117+ self.assertEqual(MockDBusSyncDaemon.ROOT_DIR, root)
118
119=== modified file 'ubuntuone/controlpanel/integrationtests/test_dbus_service.py'
120--- ubuntuone/controlpanel/integrationtests/test_dbus_service.py 2011-01-18 20:35:47 +0000
121+++ ubuntuone/controlpanel/integrationtests/test_dbus_service.py 2011-01-20 17:38:08 +0000
122@@ -27,7 +27,8 @@
123
124 from ubuntuone.controlpanel import dbus_service
125 from ubuntuone.controlpanel import (DBUS_BUS_NAME, DBUS_PREFERENCES_PATH,
126- DBUS_PREFERENCES_IFACE)
127+ DBUS_PREFERENCES_IFACE)
128+from ubuntuone.controlpanel.tests import SAMPLE_FOLDERS
129 from ubuntuone.controlpanel.integrationtests import TestCase
130
131
132@@ -64,24 +65,7 @@
133 ]
134
135 SAMPLE_VOLUMES_INFO = [
136- {
137- "volume_id": "volume-0",
138- "path": "/home/user/Documents",
139- "suggested_path": "~/Documents",
140- "subscribed": 'True',
141- },
142- {
143- "volume_id": "volume-1",
144- "path": "/home/user/Music",
145- "suggested_path": "~/Music",
146- "subscribed": '',
147- },
148- {
149- "volume_id": "volume-2",
150- "path": "/home/user/Pictures/Photos",
151- "suggested_path": "~/Pictures/Photos",
152- "subscribed": '',
153- },
154+ (u'', u'1253698', SAMPLE_FOLDERS),
155 ]
156
157 SAMPLE_REPLICATIONS_INFO = [
158@@ -524,7 +508,7 @@
159
160 def test_change_volume_settings(self):
161 """The volume settings are successfully changed."""
162- expected_volume_id = SAMPLE_VOLUMES_INFO[0]['volume_id']
163+ expected_volume_id = SAMPLE_FOLDERS[0]['volume_id']
164
165 def got_signal(volume_id):
166 """The correct volume was changed."""
167
168=== modified file 'ubuntuone/controlpanel/tests/__init__.py'
169--- ubuntuone/controlpanel/tests/__init__.py 2011-01-06 20:33:15 +0000
170+++ ubuntuone/controlpanel/tests/__init__.py 2011-01-20 17:38:08 +0000
171@@ -136,40 +136,66 @@
172 ]
173
174 SAMPLE_FOLDERS = [
175- {u'generation': u'2', u'node_id': u'341da068-81d8-437a-8f75-5bb9d86455ba',
176- u'path': u'/home/tester/Public', u'subscribed': u'True',
177+ {u'generation': u'2',
178+ u'node_id': u'341da068-81d8-437a-8f75-5bb9d86455ba',
179+ u'path': u'/home/tester/Public',
180+ u'subscribed': u'True',
181 u'suggested_path': u'~/Public',
182- u'type': u'UDF', u'volume_id': u'9ea892f8-15fa-4201-bdbf-8de99fa5f588'},
183- {u'generation': u'', u'node_id': u'11fbc86c-0d7a-49f5-ae83-8402caf66c6a',
184- u'path': u'/home/tester/Documents', u'subscribed': u'',
185+ u'type': u'UDF',
186+ u'volume_id': u'9ea892f8-15fa-4201-bdbf-8de99fa5f588'},
187+
188+ {u'generation': u'',
189+ u'node_id': u'11fbc86c-0d7a-49f5-ae83-8402caf66c6a',
190+ u'path': u'/home/tester/Documents',
191+ u'subscribed': u'',
192 u'suggested_path': u'~/Documents',
193- u'type': u'UDF', u'volume_id': u'2db262f5-a151-4c19-969c-bb5ced753c61'},
194- {u'generation': u'24', u'node_id': u'9ee0e130-a7c7-4d76-a5e3-5df506221b48',
195- u'path': u'/home/tester/Pictures/Photos', u'subscribed': u'True',
196+ u'type': u'UDF',
197+ u'volume_id': u'2db262f5-a151-4c19-969c-bb5ced753c61'},
198+
199+ {u'generation': u'24',
200+ u'node_id': u'9ee0e130-a7c7-4d76-a5e3-5df506221b48',
201+ u'path': u'/home/tester/Pictures/Photos',
202+ u'subscribed': u'True',
203 u'suggested_path': u'~/Pictures/Photos',
204- u'type': u'UDF', u'volume_id': u'1deb2874-3d28-46ae-9999-d5f48de9f460'},
205+ u'type': u'UDF',
206+ u'volume_id': u'1deb2874-3d28-46ae-9999-d5f48de9f460'},
207 ]
208
209 SAMPLE_SHARES = [
210- {u'accepted': u'True', u'access_level': u'View',
211- u'free_bytes': u'39892622746', u'generation': u'2704',
212- u'name': u're', u'node_id': u'c483f419-ed28-490a-825d-a8c074e2d795',
213- u'other_username': u'otheruser', u'other_visible_name': u'Other User',
214+ {u'accepted': u'True',
215+ u'access_level': u'View',
216+ u'free_bytes': u'39892622746',
217+ u'generation': u'2704',
218+ u'name': u're',
219+ u'node_id': u'c483f419-ed28-490a-825d-a8c074e2d795',
220+ u'other_username': u'otheruser',
221+ u'other_visible_name': u'Other User',
222 u'path': u'/home/tester/.local/share/ubuntuone/shares/re from Other User',
223- u'type': u'Share', u'volume_id': u'4a1b263b-a2b3-4f66-9e66-4cd18050810d'},
224- {u'accepted': u'True', u'access_level': u'Modify',
225- u'free_bytes': u'39892622746', u'generation': u'2704',
226- u'name': u'do', u'node_id': u'84544ea4-aefe-4f91-9bb9-ed7b0a805baf',
227- u'other_username': u'otheruser', u'other_visible_name': u'Other User',
228+ u'type': u'Share',
229+ u'volume_id': u'4a1b263b-a2b3-4f66-9e66-4cd18050810d'},
230+
231+ {u'accepted': u'True',
232+ u'access_level': u'Modify',
233+ u'free_bytes': u'39892622746',
234+ u'generation': u'2704',
235+ u'name': u'do',
236+ u'node_id': u'84544ea4-aefe-4f91-9bb9-ed7b0a805baf',
237+ u'other_username': u'otheruser',
238+ u'other_visible_name': u'Other User',
239 u'path': u'/home/tester/.local/share/ubuntuone/shares/do from Other User',
240- u'type': u'Share', u'volume_id': u'7d130dfe-98b2-4bd5-8708-9eeba9838ac0'},
241+ u'type': u'Share',
242+ u'volume_id': u'7d130dfe-98b2-4bd5-8708-9eeba9838ac0'},
243 ]
244
245 SAMPLE_SHARED = [
246- {u'accepted': u'True', u'access_level': u'View',
247- u'free_bytes': u'', u'generation': u'',
248- u'name': u'bar', u'node_id': u'31e47530-9448-4f03-b4dc-4154fdf35225',
249- u'other_username': u'otheruser', u'other_visible_name': u'Other User',
250+ {u'accepted': u'True',
251+ u'access_level': u'View',
252+ u'free_bytes': u'',
253+ u'generation': u'',
254+ u'name': u'bar',
255+ u'node_id': u'31e47530-9448-4f03-b4dc-4154fdf35225',
256+ u'other_username': u'otheruser',
257+ u'other_visible_name': u'Other User',
258 u'path': u'/home/tester/Ubuntu One/bar',
259 u'type': u'Shared',
260 u'volume_id': u'79584900-517f-4dff-b2f3-20e8c1e79365'},
261
262=== modified file 'ubuntuone/controlpanel/tests/test_backend.py'
263--- ubuntuone/controlpanel/tests/test_backend.py 2011-01-18 21:24:31 +0000
264+++ ubuntuone/controlpanel/tests/test_backend.py 2011-01-20 17:38:08 +0000
265@@ -87,6 +87,7 @@
266 status_changed_handler = None
267 subscribed_folders = []
268 actions = []
269+ root_dir = u'/home/tester/Something/Pepe Mosquito'
270
271 def get_credentials(self):
272 """Return the mock credentials."""
273@@ -142,6 +143,10 @@
274 """Stop the file_sync service."""
275 MockDBusClient.actions.append('stop')
276
277+ def get_root_dir(self):
278+ """Grab the root dir."""
279+ return self.root_dir
280+
281 def get_folders(self):
282 """Grab list of folders."""
283 return SAMPLE_FOLDERS
284@@ -368,9 +373,23 @@
285 @inlineCallbacks
286 def test_volumes_info(self):
287 """The volumes_info method exercises its callback."""
288+ # fake quota info and calculate free bytes
289+ # pylint: disable=E1101
290+ self.be.wc.results[ACCOUNT_API] = SAMPLE_ACCOUNT_NO_CURRENT_PLAN
291+ self.be.wc.results[QUOTA_API] = SAMPLE_QUOTA_JSON
292+ result = yield self.be.account_info()
293+ free_bytes = int(result['quota_total']) - int(result['quota_used'])
294+
295+ # get root dir info
296+ root_dir = MockDBusClient.root_dir
297+ root_volume = {u'volume_id': u'', u'path': root_dir,
298+ u'subscribed': 'True', u'type': u'ROOT'}
299+
300 result = yield self.be.volumes_info()
301+
302+ expected = [('', unicode(free_bytes), [root_volume] + SAMPLE_FOLDERS)]
303 # later, we should unify folders and shares info
304- self.assertEqual(result, SAMPLE_FOLDERS)
305+ self.assertEqual(result, expected)
306
307 @inlineCallbacks
308 def test_subscribe_volume(self):

Subscribers

People subscribed via source and target branches