Merge lp:~nataliabidart/ubuntuone-control-panel/decouple-devices into lp:ubuntuone-control-panel

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 120
Merged at revision: 117
Proposed branch: lp:~nataliabidart/ubuntuone-control-panel/decouple-devices
Merge into: lp:ubuntuone-control-panel
Diff against target: 254 lines (+127/-54)
3 files modified
ubuntuone/controlpanel/backend.py (+75/-40)
ubuntuone/controlpanel/tests/__init__.py (+14/-12)
ubuntuone/controlpanel/tests/test_backend.py (+38/-2)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-control-panel/decouple-devices
Reviewer Review Type Date Requested Status
Manuel de la Peña (community) Approve
Alejandro J. Cura (community) Approve
Review via email: mp+55345@code.launchpad.net

Commit message

- Decoupled device list retrieved from the web from the local settings retrieved from syncdaemon (LP: #720704).

Description of the change

This change decouples the retrieval of the device info list from the retrieval of local settings from syncdaemon.

To test this, you should:

killall ubuntuone-control-panel-backend

In two terminals, run:

DEBUG=True PYTHONPATH=. bin/ubuntuone-control-panel-backend
DEBUG=True PYTHONPATH=. bin/ubuntuone-control-panel-gtk

The first test would be disconnecting your network connection and going to the devices tab, you should see a single device (your local device).

The second test is more complex, since it requires that syncdaemon is disabled. Due to bug bug #744980, you need to:

* u1sdtool -q
* edit ~/.config/ubuntuone/syncdaemon.conf and set files_sync_enabled = False
* re-run the control panel backend and frontend
* go to the devices tab and confirm that the device list is retrieved, but no local settings are offered

To post a comment you must log in.
119. By Natalia Bidart

Fixed typo.

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

Nice branch!

review: Approve
Revision history for this message
Manuel de la Peña (mandel) wrote :

Work fine with me to small remarks:

1. 'more the devices will be configurable.' - I guess is either 'more devices' or 'more of the devices'

2. I'm confused about this:
118 + show_notifs = bool_str(show_notifs)
119 + local_device["show_all_notifications"] = show_notifs

Why reassigning show_notifs and then storing it in the local_devices dict. What about just assigning it to the dict directly?

Since I don't consider the two above things to be lowering the quality of the code I approve and will trust the committer to the right thing.

review: Approve
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

> Work fine with me to small remarks:
>
> 1. 'more the devices will be configurable.' - I guess is either 'more devices'
> or 'more of the devices'

Fixed, thanks for the attention to detail!

> 2. I'm confused about this:
> 118 + show_notifs = bool_str(show_notifs)
> 119 + local_device["show_all_notifications"] = show_notifs
>
> Why reassigning show_notifs and then storing it in the local_devices dict.
> What about just assigning it to the dict directly?

Because otherwise it fells over the 80-columns width. I personally prefer assigning to a local variable that chopping off the line with = \.

120. By Natalia Bidart

Another typo, thanks mandel!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ubuntuone/controlpanel/backend.py'
--- ubuntuone/controlpanel/backend.py 2011-03-28 17:25:21 +0000
+++ ubuntuone/controlpanel/backend.py 2011-03-29 17:12:42 +0000
@@ -26,7 +26,7 @@
26from ubuntuone.controlpanel import dbus_client26from ubuntuone.controlpanel import dbus_client
27from ubuntuone.controlpanel import replication_client27from ubuntuone.controlpanel import replication_client
28from ubuntuone.controlpanel.logger import setup_logging, log_call28from ubuntuone.controlpanel.logger import setup_logging, log_call
29from ubuntuone.controlpanel.webclient import WebClient29from ubuntuone.controlpanel.webclient import WebClient, WebClientError
3030
3131
32logger = setup_logging('backend')32logger = setup_logging('backend')
@@ -143,6 +143,49 @@
143 _set_status_changed_handler)143 _set_status_changed_handler)
144144
145 @inlineCallbacks145 @inlineCallbacks
146 def _process_device_web_info(self, devices, enabled, limit_bw, limits,
147 show_notifs):
148 """Return a lis of processed devices."""
149 result = []
150 for d in devices:
151 di = {}
152 di["type"] = d["kind"]
153 di["name"] = d["description"]
154 di["configurable"] = ''
155 if di["type"] == DEVICE_TYPE_COMPUTER:
156 di["device_id"] = di["type"] + d["token"]
157 if di["type"] == DEVICE_TYPE_PHONE:
158 di["device_id"] = di["type"] + str(d["id"])
159
160 is_local = yield self.device_is_local(di["device_id"])
161 di["is_local"] = bool_str(is_local)
162 # currently, only local devices are configurable.
163 # eventually, more devices will be configurable.
164 di["configurable"] = bool_str(is_local and enabled)
165
166 if bool(di["configurable"]):
167 di["limit_bandwidth"] = bool_str(limit_bw)
168 di["show_all_notifications"] = bool_str(show_notifs)
169 upload = limits["upload"]
170 download = limits["download"]
171 di[UPLOAD_KEY] = str(upload)
172 di[DOWNLOAD_KEY] = str(download)
173
174 # date_added is not in the webservice yet (LP: #673668)
175 # di["date_added"] = ""
176
177 # missing values (LP: #673668)
178 # di["available_services"] = ""
179 # di["enabled_services"] = ""
180
181 if is_local: # prepend the local device!
182 result.insert(0, di)
183 else:
184 result.append(di)
185
186 returnValue(result)
187
188 @inlineCallbacks
146 def get_token(self):189 def get_token(self):
147 """Return the token from the credentials."""190 """Return the token from the credentials."""
148 credentials = yield dbus_client.get_credentials()191 credentials = yield dbus_client.get_credentials()
@@ -188,47 +231,39 @@
188 @inlineCallbacks231 @inlineCallbacks
189 def devices_info(self):232 def devices_info(self):
190 """Get the user devices info."""233 """Get the user devices info."""
191 result = []234 result = limit_bw = limits = show_notifs = None
192 limit_bw = yield dbus_client.bandwidth_throttling_enabled()235 enabled = yield dbus_client.files_sync_enabled()
193 show_all_notif = yield dbus_client.show_all_notifications_enabled()236 if enabled:
194 limits = yield dbus_client.get_throttling_limits()237 limit_bw = yield dbus_client.bandwidth_throttling_enabled()
195238 show_notifs = yield dbus_client.show_all_notifications_enabled()
196 devices = yield self.wc.call_api(DEVICES_API)239 limits = yield dbus_client.get_throttling_limits()
197 for d in devices:240
198 di = {}241 try:
199 di["type"] = d["kind"]242 devices = yield self.wc.call_api(DEVICES_API)
200 di["name"] = d["description"]243 except WebClientError:
201 di["configurable"] = ''244 logger.exception('devices_info: web client failure:')
202 if di["type"] == DEVICE_TYPE_COMPUTER:245 else:
203 di["device_id"] = di["type"] + d["token"]246 result = yield self._process_device_web_info(devices, enabled,
204 if di["type"] == DEVICE_TYPE_PHONE:247 limit_bw, limits,
205 di["device_id"] = di["type"] + str(d["id"])248 show_notifs)
206249 if result is None:
207 is_local = yield self.device_is_local(di["device_id"])250 credentials = yield dbus_client.get_credentials()
208 di["is_local"] = bool_str(is_local)251 local_device = {}
209 # currently, only local devices are configurable.252 local_device["type"] = DEVICE_TYPE_COMPUTER
210 # eventually, more the devices will be configurable.253 local_device["name"] = credentials['name']
211 di["configurable"] = bool_str(is_local)254 device_id = local_device["type"] + credentials["token"]
212255 local_device["device_id"] = device_id
213 if bool(di["configurable"]):256 local_device["is_local"] = bool_str(True)
214 di["limit_bandwidth"] = bool_str(limit_bw)257 local_device["configurable"] = bool_str(enabled)
215 di["show_all_notifications"] = bool_str(show_all_notif)258 if bool(local_device["configurable"]):
259 local_device["limit_bandwidth"] = bool_str(limit_bw)
260 show_notifs = bool_str(show_notifs)
261 local_device["show_all_notifications"] = show_notifs
216 upload = limits["upload"]262 upload = limits["upload"]
217 download = limits["download"]263 download = limits["download"]
218 di[UPLOAD_KEY] = str(upload)264 local_device[UPLOAD_KEY] = str(upload)
219 di[DOWNLOAD_KEY] = str(download)265 local_device[DOWNLOAD_KEY] = str(download)
220266 result = [local_device]
221 # date_added is not in the webservice yet (LP: #673668)
222 # di["date_added"] = ""
223
224 # missing values (LP: #673668)
225 # di["available_services"] = ""
226 # di["enabled_services"] = ""
227
228 if is_local: # prepend the local device!
229 result.insert(0, di)
230 else:
231 result.append(di)
232267
233 returnValue(result)268 returnValue(result)
234269
235270
=== modified file 'ubuntuone/controlpanel/tests/__init__.py'
--- ubuntuone/controlpanel/tests/__init__.py 2011-03-02 19:54:09 +0000
+++ ubuntuone/controlpanel/tests/__init__.py 2011-03-29 17:12:42 +0000
@@ -23,7 +23,7 @@
2323
24TOKEN = {u'consumer_key': u'xQ7xDAz',24TOKEN = {u'consumer_key': u'xQ7xDAz',
25 u'consumer_secret': u'KzCJWCTNbbntwfyCKKjomJDzlgqxLy',25 u'consumer_secret': u'KzCJWCTNbbntwfyCKKjomJDzlgqxLy',
26 u'token_name': u'test',26 u'name': u'Ubuntu One @ localhost',
27 u'token': u'ABCDEF01234-localtoken',27 u'token': u'ABCDEF01234-localtoken',
28 u'token_secret': u'qFYImEtlczPbsCnYyuwLoPDlPEnvNcIktZphPQklAWrvyfFMV'}28 u'token_secret': u'qFYImEtlczPbsCnYyuwLoPDlPEnvNcIktZphPQklAWrvyfFMV'}
2929
@@ -110,19 +110,21 @@
110]110]
111"""111"""
112112
113LOCAL_DEVICE = {
114 'is_local': 'True',
115 'configurable': 'True',
116 'device_id': 'ComputerABCDEF01234-localtoken',
117 'limit_bandwidth': '',
118 'show_all_notifications': 'True',
119 'max_download_speed': '-1',
120 'max_upload_speed': '-1',
121 'name': 'Ubuntu One @ localhost',
122 'type': 'Computer',
123}
124
113# note that local computer should be first, do not change!125# note that local computer should be first, do not change!
114EXPECTED_DEVICES_INFO = [126EXPECTED_DEVICES_INFO = [
115 {127 LOCAL_DEVICE,
116 'is_local': 'True',
117 'configurable': 'True',
118 'device_id': 'ComputerABCDEF01234-localtoken',
119 'limit_bandwidth': '',
120 'show_all_notifications': 'True',
121 'max_download_speed': '-1',
122 'max_upload_speed': '-1',
123 'name': 'Ubuntu One @ localhost',
124 'type': 'Computer',
125 },
126 {128 {
127 "device_id": "ComputerABCDEF01234token",129 "device_id": "ComputerABCDEF01234token",
128 "name": "Ubuntu One @ darkstar",130 "name": "Ubuntu One @ darkstar",
129131
=== modified file 'ubuntuone/controlpanel/tests/test_backend.py'
--- ubuntuone/controlpanel/tests/test_backend.py 2011-03-28 16:23:59 +0000
+++ ubuntuone/controlpanel/tests/test_backend.py 2011-03-29 17:12:42 +0000
@@ -44,6 +44,7 @@
44 EXPECTED_ACCOUNT_INFO,44 EXPECTED_ACCOUNT_INFO,
45 EXPECTED_ACCOUNT_INFO_WITH_CURRENT_PLAN,45 EXPECTED_ACCOUNT_INFO_WITH_CURRENT_PLAN,
46 EXPECTED_DEVICES_INFO,46 EXPECTED_DEVICES_INFO,
47 LOCAL_DEVICE,
47 ROOT_PATH,48 ROOT_PATH,
48 SAMPLE_ACCOUNT_NO_CURRENT_PLAN,49 SAMPLE_ACCOUNT_NO_CURRENT_PLAN,
49 SAMPLE_ACCOUNT_WITH_CURRENT_PLAN,50 SAMPLE_ACCOUNT_WITH_CURRENT_PLAN,
@@ -340,9 +341,43 @@
340 @inlineCallbacks341 @inlineCallbacks
341 def test_devices_info_fails(self):342 def test_devices_info_fails(self):
342 """The devices_info method exercises its errback."""343 """The devices_info method exercises its errback."""
344 def fail(*args, **kwargs):
345 """Raise any error other than WebClientError."""
346 raise ValueError(args)
347
348 self.patch(self.be.wc, 'call_api', fail)
349 yield self.assertFailure(self.be.devices_info(), ValueError)
350
351 @inlineCallbacks
352 def test_devices_info_with_webclient_error(self):
353 """The devices_info returns local info if webclient error."""
343 # pylint: disable=E1101354 # pylint: disable=E1101
344 self.be.wc.failure = 404355 self.be.wc.failure = 404
345 yield self.assertFailure(self.be.devices_info(), WebClientError)356 result = yield self.be.devices_info()
357
358 self.assertEqual(result, [LOCAL_DEVICE])
359 self.assertTrue(self.memento.check_error('devices_info',
360 'web client failure'))
361
362 @inlineCallbacks
363 def test_devices_info_if_files_disable(self):
364 """The devices_info returns device only info if files is disabled."""
365 yield self.be.disable_files()
366 status = yield self.be.file_sync_status()
367 assert status['status'] == backend.FILE_SYNC_DISABLED, status
368
369 # pylint: disable=E1101
370 self.be.wc.results[DEVICES_API] = SAMPLE_DEVICES_JSON
371 result = yield self.be.devices_info()
372
373 expected = EXPECTED_DEVICES_INFO[:]
374 for device in expected:
375 device.pop('limit_bandwidth', None)
376 device.pop('max_download_speed', None)
377 device.pop('max_upload_speed', None)
378 device.pop('show_all_notifications', None)
379 device['configurable'] = ''
380 self.assertEqual(result, expected)
346381
347 @inlineCallbacks382 @inlineCallbacks
348 def test_remove_device(self):383 def test_remove_device(self):
@@ -372,7 +407,8 @@
372 """The remove_device method fails as expected."""407 """The remove_device method fails as expected."""
373 # pylint: disable=E1101408 # pylint: disable=E1101
374 self.be.wc.failure = 404409 self.be.wc.failure = 404
375 yield self.assertFailure(self.be.devices_info(), WebClientError)410 yield self.assertFailure(self.be.remove_device(self.local_token),
411 WebClientError)
376412
377 @inlineCallbacks413 @inlineCallbacks
378 def test_change_show_all_notifications(self):414 def test_change_show_all_notifications(self):

Subscribers

People subscribed via source and target branches