Merge lp:~alecu/ubuntuone-control-panel/backend-born into lp:~nataliabidart/ubuntuone-control-panel/trunk
- backend-born
- Merge into trunk
Proposed by
Alejandro J. Cura
Status: | Merged |
---|---|
Merged at revision: | 4 |
Proposed branch: | lp:~alecu/ubuntuone-control-panel/backend-born |
Merge into: | lp:~nataliabidart/ubuntuone-control-panel/trunk |
Diff against target: |
555 lines (+494/-0) 10 files modified
integration/run-tests (+28/-0) integration/test_dbus_client.py (+73/-0) integration/test_dbus_service.py (+90/-0) integration/test_webclient.py (+90/-0) ubuntuone/controlpanel/__init__.py (+6/-0) ubuntuone/controlpanel/backend.py (+22/-0) ubuntuone/controlpanel/dbus_client.py (+54/-0) ubuntuone/controlpanel/dbus_service.py (+74/-0) ubuntuone/controlpanel/tests/test_backend.py (+31/-0) ubuntuone/controlpanel/webclient.py (+26/-0) |
To merge this branch: | bzr merge lp:~alecu/ubuntuone-control-panel/backend-born |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Natalia Bidart | Approve | ||
Review via email:
|
Commit message
The foundations of the control panel backend
Description of the change
The foundations of the control panel backend
To post a comment you must log in.
- 9. By Alejandro J. Cura
-
fix pylint complaints
- 10. By Alejandro J. Cura
-
style fixes
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory 'integration' | |||
2 | === added file 'integration/__init__.py' | |||
3 | === added file 'integration/run-tests' | |||
4 | --- integration/run-tests 1970-01-01 00:00:00 +0000 | |||
5 | +++ integration/run-tests 2010-09-24 23:06:03 +0000 | |||
6 | @@ -0,0 +1,28 @@ | |||
7 | 1 | #! /bin/bash | ||
8 | 2 | # | ||
9 | 3 | # Author: Natalia Bidart <natalia.bidart@gmail.com> | ||
10 | 4 | # Author: Alejandro J. Cura <alecu@canonical.com> | ||
11 | 5 | # | ||
12 | 6 | # Copyright 2010 Canonical Ltd. | ||
13 | 7 | # | ||
14 | 8 | # This program is free software: you can redistribute it and/or modify it | ||
15 | 9 | # under the terms of the GNU General Public License version 3, as published | ||
16 | 10 | # by the Free Software Foundation. | ||
17 | 11 | # | ||
18 | 12 | # This program is distributed in the hope that it will be useful, but | ||
19 | 13 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
20 | 14 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
21 | 15 | # PURPOSE. See the GNU General Public License for more details. | ||
22 | 16 | # | ||
23 | 17 | # You should have received a copy of the GNU General Public License along | ||
24 | 18 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
25 | 19 | |||
26 | 20 | if [ $# -ne 0 ]; then | ||
27 | 21 | MODULE="$@" | ||
28 | 22 | else | ||
29 | 23 | MODULE="integration" | ||
30 | 24 | fi | ||
31 | 25 | |||
32 | 26 | echo "Running test suite for ""$MODULE" | ||
33 | 27 | PYTHONPATH=. `which xvfb-run` u1trial "$MODULE" | ||
34 | 28 | rm -rf _trial_temp | ||
35 | 0 | 29 | ||
36 | === added file 'integration/test_dbus_client.py' | |||
37 | --- integration/test_dbus_client.py 1970-01-01 00:00:00 +0000 | |||
38 | +++ integration/test_dbus_client.py 2010-09-24 23:06:03 +0000 | |||
39 | @@ -0,0 +1,73 @@ | |||
40 | 1 | # -*- coding: utf-8 -*- | ||
41 | 2 | |||
42 | 3 | # Authors: Alejandro J. Cura <alecu@canonical.com> | ||
43 | 4 | # | ||
44 | 5 | # Copyright 2010 Canonical Ltd. | ||
45 | 6 | # | ||
46 | 7 | # This program is free software: you can redistribute it and/or modify it | ||
47 | 8 | # under the terms of the GNU General Public License version 3, as published | ||
48 | 9 | # by the Free Software Foundation. | ||
49 | 10 | # | ||
50 | 11 | # This program is distributed in the hope that it will be useful, but | ||
51 | 12 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
52 | 13 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
53 | 14 | # PURPOSE. See the GNU General Public License for more details. | ||
54 | 15 | # | ||
55 | 16 | # You should have received a copy of the GNU General Public License along | ||
56 | 17 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
57 | 18 | |||
58 | 19 | """Tests for the control panel backend DBus service.""" | ||
59 | 20 | |||
60 | 21 | import dbus | ||
61 | 22 | |||
62 | 23 | from twisted.internet import defer | ||
63 | 24 | from twisted.trial import unittest | ||
64 | 25 | |||
65 | 26 | from ubuntuone.controlpanel import dbus_service | ||
66 | 27 | from ubuntuone.controlpanel import dbus_client | ||
67 | 28 | from ubuntuone.controlpanel import (DBUS_BUS_NAME, DBUS_PREFERENCES_PATH, | ||
68 | 29 | DBUS_PREFERENCES_IFACE) | ||
69 | 30 | from ubuntuone.controlpanel.dbus_client import (DBUS_SSO_NAME, DBUS_SSO_PATH, | ||
70 | 31 | DBUS_SSO_IFACE) | ||
71 | 32 | |||
72 | 33 | SAMPLE_CREDS = { | ||
73 | 34 | "token": "ABCDEF12345678", | ||
74 | 35 | "access_token": "DEADCAFE2010", | ||
75 | 36 | } | ||
76 | 37 | |||
77 | 38 | class MockDBusSSOClient(dbus.service.Object): | ||
78 | 39 | """A mock object that mimicks ussoc.""" | ||
79 | 40 | |||
80 | 41 | @dbus.service.method(dbus_interface=DBUS_SSO_IFACE, in_signature="sssx") | ||
81 | 42 | def login_or_register_to_get_credentials(self, app_name, tcurl, help, wid): | ||
82 | 43 | """Get creds from the keyring, login/register if needed.""" | ||
83 | 44 | self.CredentialsFound(app_name, SAMPLE_CREDS) | ||
84 | 45 | |||
85 | 46 | @dbus.service.signal(dbus_interface=DBUS_SSO_IFACE, signature="sa{ss}") | ||
86 | 47 | def CredentialsFound(self, app_name, credentials): | ||
87 | 48 | """Credentials were finally found.""" | ||
88 | 49 | |||
89 | 50 | class DBusClientTestCase(unittest.TestCase): | ||
90 | 51 | """test for the dbus client.""" | ||
91 | 52 | timeout = 5 | ||
92 | 53 | |||
93 | 54 | def setUp(self): | ||
94 | 55 | super(DBusClientTestCase, self).setUp() | ||
95 | 56 | dbus_service.init_mainloop() | ||
96 | 57 | |||
97 | 58 | def register_mockserver(self, bus_name, object_path, object_class): | ||
98 | 59 | """The mock service is registered on the DBus.""" | ||
99 | 60 | session_bus = dbus.SessionBus() | ||
100 | 61 | name = session_bus.request_name(bus_name, | ||
101 | 62 | dbus.bus.NAME_FLAG_DO_NOT_QUEUE) | ||
102 | 63 | self.assertNotEqual(name, dbus.bus.REQUEST_NAME_REPLY_EXISTS) | ||
103 | 64 | bus_name = dbus.service.BusName(bus_name, bus=dbus.SessionBus()) | ||
104 | 65 | object_class(object_path=DBUS_SSO_PATH, bus_name=bus_name) | ||
105 | 66 | |||
106 | 67 | @defer.inlineCallbacks | ||
107 | 68 | def test_get_credentials_ok(self): | ||
108 | 69 | """Test the success case for get_credentials.""" | ||
109 | 70 | self.register_mockserver(DBUS_SSO_NAME, DBUS_SSO_PATH, | ||
110 | 71 | MockDBusSSOClient) | ||
111 | 72 | creds = yield dbus_client.get_credentials() | ||
112 | 73 | self.assertEqual(creds, SAMPLE_CREDS) | ||
113 | 0 | 74 | ||
114 | === added file 'integration/test_dbus_service.py' | |||
115 | --- integration/test_dbus_service.py 1970-01-01 00:00:00 +0000 | |||
116 | +++ integration/test_dbus_service.py 2010-09-24 23:06:03 +0000 | |||
117 | @@ -0,0 +1,90 @@ | |||
118 | 1 | # -*- coding: utf-8 -*- | ||
119 | 2 | |||
120 | 3 | # Authors: Alejandro J. Cura <alecu@canonical.com> | ||
121 | 4 | # | ||
122 | 5 | # Copyright 2010 Canonical Ltd. | ||
123 | 6 | # | ||
124 | 7 | # This program is free software: you can redistribute it and/or modify it | ||
125 | 8 | # under the terms of the GNU General Public License version 3, as published | ||
126 | 9 | # by the Free Software Foundation. | ||
127 | 10 | # | ||
128 | 11 | # This program is distributed in the hope that it will be useful, but | ||
129 | 12 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
130 | 13 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
131 | 14 | # PURPOSE. See the GNU General Public License for more details. | ||
132 | 15 | # | ||
133 | 16 | # You should have received a copy of the GNU General Public License along | ||
134 | 17 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
135 | 18 | |||
136 | 19 | """Tests for the control panel backend DBus service.""" | ||
137 | 20 | |||
138 | 21 | import dbus | ||
139 | 22 | |||
140 | 23 | from twisted.internet import defer | ||
141 | 24 | from twisted.trial import unittest | ||
142 | 25 | |||
143 | 26 | from ubuntuone.controlpanel import dbus_service | ||
144 | 27 | from ubuntuone.controlpanel import (DBUS_BUS_NAME, DBUS_PREFERENCES_PATH, | ||
145 | 28 | DBUS_PREFERENCES_IFACE) | ||
146 | 29 | |||
147 | 30 | |||
148 | 31 | class DBusServiceTestCase(unittest.TestCase): | ||
149 | 32 | """Test for the DBus service.""" | ||
150 | 33 | timeout = 5 | ||
151 | 34 | |||
152 | 35 | def setUp(self): | ||
153 | 36 | """Initialize each test run.""" | ||
154 | 37 | super(DBusServiceTestCase, self).setUp() | ||
155 | 38 | dbus_service.init_mainloop() | ||
156 | 39 | |||
157 | 40 | def test_register_service(self): | ||
158 | 41 | """The DBus service is successfully registered.""" | ||
159 | 42 | ret = dbus_service.register_service() | ||
160 | 43 | self.assertTrue(ret) | ||
161 | 44 | |||
162 | 45 | def test_cant_register_twice(self): | ||
163 | 46 | """The DBus service can't register if it already did.""" | ||
164 | 47 | ret = dbus_service.register_service() | ||
165 | 48 | self.assertTrue(ret) | ||
166 | 49 | ret = dbus_service.register_service() | ||
167 | 50 | self.assertFalse(ret) | ||
168 | 51 | test_cant_register_twice.skip = "Must run 2nd check in another process." | ||
169 | 52 | |||
170 | 53 | def test_dbus_busname_created(self): | ||
171 | 54 | """The DBus BusName is created.""" | ||
172 | 55 | busname = dbus_service.get_busname() | ||
173 | 56 | self.assertEqual(busname.get_name(), DBUS_BUS_NAME) | ||
174 | 57 | |||
175 | 58 | def test_account_info_returned(self): | ||
176 | 59 | """The account info is successfully returned.""" | ||
177 | 60 | dbus_service.publish_backend() | ||
178 | 61 | |||
179 | 62 | bus = dbus.SessionBus() | ||
180 | 63 | obj = bus.get_object(bus_name=DBUS_BUS_NAME, | ||
181 | 64 | object_path=DBUS_PREFERENCES_PATH, | ||
182 | 65 | follow_name_owner_changes=True) | ||
183 | 66 | self.iface_name = DBUS_PREFERENCES_IFACE | ||
184 | 67 | backend = dbus.Interface(object=obj, | ||
185 | 68 | dbus_interface=DBUS_PREFERENCES_IFACE) | ||
186 | 69 | d = defer.Deferred() | ||
187 | 70 | |||
188 | 71 | def got_signal(account_info): | ||
189 | 72 | """The correct signal was fired.""" | ||
190 | 73 | self.assertIn("quota_used", account_info) | ||
191 | 74 | self.assertIn("quota_total", account_info) | ||
192 | 75 | self.assertIn("type", account_info) | ||
193 | 76 | self.assertIn("name", account_info) | ||
194 | 77 | self.assertIn("email", account_info) | ||
195 | 78 | d.callback("success") | ||
196 | 79 | |||
197 | 80 | def got_error(*a): | ||
198 | 81 | """Some error happened in the DBus call.""" | ||
199 | 82 | d.errback(*a) | ||
200 | 83 | |||
201 | 84 | def ignore(*a): | ||
202 | 85 | """Do nothing with the returned value.""" | ||
203 | 86 | |||
204 | 87 | backend.connect_to_signal("AccountInfoReady", got_signal) | ||
205 | 88 | |||
206 | 89 | backend.account_info(reply_handler=ignore, error_handler=got_error) | ||
207 | 90 | return d | ||
208 | 0 | 91 | ||
209 | === added file 'integration/test_webclient.py' | |||
210 | --- integration/test_webclient.py 1970-01-01 00:00:00 +0000 | |||
211 | +++ integration/test_webclient.py 2010-09-24 23:06:03 +0000 | |||
212 | @@ -0,0 +1,90 @@ | |||
213 | 1 | # -*- coding: utf-8 -*- | ||
214 | 2 | |||
215 | 3 | # Authors: Alejandro J. Cura <alecu@canonical.com> | ||
216 | 4 | # | ||
217 | 5 | # Copyright 2010 Canonical Ltd. | ||
218 | 6 | # | ||
219 | 7 | # This program is free software: you can redistribute it and/or modify it | ||
220 | 8 | # under the terms of the GNU General Public License version 3, as published | ||
221 | 9 | # by the Free Software Foundation. | ||
222 | 10 | # | ||
223 | 11 | # This program is distributed in the hope that it will be useful, but | ||
224 | 12 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
225 | 13 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
226 | 14 | # PURPOSE. See the GNU General Public License for more details. | ||
227 | 15 | # | ||
228 | 16 | # You should have received a copy of the GNU General Public License along | ||
229 | 17 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
230 | 18 | |||
231 | 19 | """Tests for the control panel backend webservice client.""" | ||
232 | 20 | |||
233 | 21 | from twisted.application import internet, service | ||
234 | 22 | from twisted.internet import defer | ||
235 | 23 | from twisted.internet.defer import inlineCallbacks | ||
236 | 24 | from twisted.internet.threads import deferToThread | ||
237 | 25 | from twisted.trial import unittest | ||
238 | 26 | from twisted.web import vhost, static, server, resource | ||
239 | 27 | |||
240 | 28 | from ubuntuone.controlpanel import webclient | ||
241 | 29 | |||
242 | 30 | SAMPLE_RESOURCE = "sample resource" | ||
243 | 31 | |||
244 | 32 | |||
245 | 33 | class MockResource(resource.Resource): | ||
246 | 34 | """A simple web resource.""" | ||
247 | 35 | isLeaf = True | ||
248 | 36 | contents = "" | ||
249 | 37 | |||
250 | 38 | def getChild(self, name, request): | ||
251 | 39 | """Get a given child resource.""" | ||
252 | 40 | if name == '': | ||
253 | 41 | return self | ||
254 | 42 | return resource.Resource.getChild(self, name, request) | ||
255 | 43 | |||
256 | 44 | def render_GET(self, request): | ||
257 | 45 | """Make a bit of html out of these resource's content.""" | ||
258 | 46 | return self.contents | ||
259 | 47 | |||
260 | 48 | |||
261 | 49 | class MockWebService(object): | ||
262 | 50 | """A mock webservice for testing""" | ||
263 | 51 | |||
264 | 52 | def __init__(self): | ||
265 | 53 | """Start up this instance.""" | ||
266 | 54 | root = MockResource() | ||
267 | 55 | root.contents = SAMPLE_RESOURCE | ||
268 | 56 | site = server.Site(root) | ||
269 | 57 | application = service.Application('web') | ||
270 | 58 | self.serviceCollection = service.IServiceCollection(application) | ||
271 | 59 | self.tcpserver = internet.TCPServer(0, site) | ||
272 | 60 | self.tcpserver.setServiceParent(self.serviceCollection) | ||
273 | 61 | self.serviceCollection.startService() | ||
274 | 62 | |||
275 | 63 | def get_url(self): | ||
276 | 64 | """Build the url for this mock server.""" | ||
277 | 65 | portNum = self.tcpserver._port.getHost().port | ||
278 | 66 | return "http://localhost:%d/" % portNum | ||
279 | 67 | |||
280 | 68 | def stop(self): | ||
281 | 69 | """Shut it down.""" | ||
282 | 70 | self.serviceCollection.stopService() | ||
283 | 71 | |||
284 | 72 | |||
285 | 73 | class WebClientTestCase(unittest.TestCase): | ||
286 | 74 | """Test for the webservice client.""" | ||
287 | 75 | timeout = 5 | ||
288 | 76 | |||
289 | 77 | def setUp(self): | ||
290 | 78 | super(WebClientTestCase, self).setUp() | ||
291 | 79 | self.ws = MockWebService() | ||
292 | 80 | |||
293 | 81 | def tearDown(self): | ||
294 | 82 | super(WebClientTestCase, self).tearDown() | ||
295 | 83 | self.ws.stop() | ||
296 | 84 | |||
297 | 85 | @inlineCallbacks | ||
298 | 86 | def test_connect(self): | ||
299 | 87 | """Connect to the mock webservice.""" | ||
300 | 88 | webclient.BASE_URL = self.ws.get_url() | ||
301 | 89 | ret = yield deferToThread(webclient.getinfo) | ||
302 | 90 | self.assertEqual(ret, SAMPLE_RESOURCE) | ||
303 | 0 | 91 | ||
304 | === modified file 'ubuntuone/controlpanel/__init__.py' | |||
305 | --- ubuntuone/controlpanel/__init__.py 2010-09-15 21:43:48 +0000 | |||
306 | +++ ubuntuone/controlpanel/__init__.py 2010-09-24 23:06:03 +0000 | |||
307 | @@ -1,6 +1,7 @@ | |||
308 | 1 | # -*- coding: utf-8 -*- | 1 | # -*- coding: utf-8 -*- |
309 | 2 | 2 | ||
310 | 3 | # Authors: Natalia B Bidart <natalia.bidart@canonical.com> | 3 | # Authors: Natalia B Bidart <natalia.bidart@canonical.com> |
311 | 4 | # Authors: Alejandro J. Cura <alecu@canonical.com> | ||
312 | 4 | # | 5 | # |
313 | 5 | # Copyright 2010 Canonical Ltd. | 6 | # Copyright 2010 Canonical Ltd. |
314 | 6 | # | 7 | # |
315 | @@ -22,3 +23,8 @@ | |||
316 | 22 | their Ubuntu One subscription and preferences. | 23 | their Ubuntu One subscription and preferences. |
317 | 23 | 24 | ||
318 | 24 | """ | 25 | """ |
319 | 26 | |||
320 | 27 | # constants | ||
321 | 28 | DBUS_BUS_NAME = "com.ubuntuone.controlpanel" | ||
322 | 29 | DBUS_PREFERENCES_PATH = "/preferences" | ||
323 | 30 | DBUS_PREFERENCES_IFACE = "com.ubuntuone.controlpanel.Preferences" | ||
324 | 25 | 31 | ||
325 | === added file 'ubuntuone/controlpanel/backend.py' | |||
326 | --- ubuntuone/controlpanel/backend.py 1970-01-01 00:00:00 +0000 | |||
327 | +++ ubuntuone/controlpanel/backend.py 2010-09-24 23:06:03 +0000 | |||
328 | @@ -0,0 +1,22 @@ | |||
329 | 1 | # -*- coding: utf-8 -*- | ||
330 | 2 | |||
331 | 3 | # Authors: Alejandro J. Cura <alecu@canonical.com> | ||
332 | 4 | # | ||
333 | 5 | # Copyright 2010 Canonical Ltd. | ||
334 | 6 | # | ||
335 | 7 | # This program is free software: you can redistribute it and/or modify it | ||
336 | 8 | # under the terms of the GNU General Public License version 3, as published | ||
337 | 9 | # by the Free Software Foundation. | ||
338 | 10 | # | ||
339 | 11 | # This program is distributed in the hope that it will be useful, but | ||
340 | 12 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
341 | 13 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
342 | 14 | # PURPOSE. See the GNU General Public License for more details. | ||
343 | 15 | # | ||
344 | 16 | # You should have received a copy of the GNU General Public License along | ||
345 | 17 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
346 | 18 | |||
347 | 19 | """A backend for the Ubuntu One Control Panel.""" | ||
348 | 20 | |||
349 | 21 | class ControlBackend(object): | ||
350 | 22 | """A backend.""" | ||
351 | 0 | 23 | ||
352 | === added file 'ubuntuone/controlpanel/dbus_client.py' | |||
353 | --- ubuntuone/controlpanel/dbus_client.py 1970-01-01 00:00:00 +0000 | |||
354 | +++ ubuntuone/controlpanel/dbus_client.py 2010-09-24 23:06:03 +0000 | |||
355 | @@ -0,0 +1,54 @@ | |||
356 | 1 | # -*- coding: utf-8 -*- | ||
357 | 2 | |||
358 | 3 | # Authors: Alejandro J. Cura <alecu@canonical.com> | ||
359 | 4 | # | ||
360 | 5 | # Copyright 2010 Canonical Ltd. | ||
361 | 6 | # | ||
362 | 7 | # This program is free software: you can redistribute it and/or modify it | ||
363 | 8 | # under the terms of the GNU General Public License version 3, as published | ||
364 | 9 | # by the Free Software Foundation. | ||
365 | 10 | # | ||
366 | 11 | # This program is distributed in the hope that it will be useful, but | ||
367 | 12 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
368 | 13 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
369 | 14 | # PURPOSE. See the GNU General Public License for more details. | ||
370 | 15 | # | ||
371 | 16 | # You should have received a copy of the GNU General Public License along | ||
372 | 17 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
373 | 18 | |||
374 | 19 | """Client to use other DBus services.""" | ||
375 | 20 | |||
376 | 21 | import dbus.service | ||
377 | 22 | |||
378 | 23 | from twisted.internet import defer | ||
379 | 24 | |||
380 | 25 | DBUS_SSO_NAME = "com.ubuntu.sso" | ||
381 | 26 | DBUS_SSO_PATH = "/credentials" | ||
382 | 27 | DBUS_SSO_IFACE = "com.ubuntu.sso.ApplicationCredentials" | ||
383 | 28 | |||
384 | 29 | |||
385 | 30 | def get_credentials(): | ||
386 | 31 | """Get the credentials from the ubuntu-sso-client.""" | ||
387 | 32 | bus = dbus.SessionBus() | ||
388 | 33 | obj = bus.get_object(bus_name=DBUS_SSO_NAME, | ||
389 | 34 | object_path=DBUS_SSO_PATH, | ||
390 | 35 | follow_name_owner_changes=True) | ||
391 | 36 | proxy = dbus.Interface(object=obj, dbus_interface=DBUS_SSO_IFACE) | ||
392 | 37 | d = defer.Deferred() | ||
393 | 38 | |||
394 | 39 | def ignore_return(*a): | ||
395 | 40 | """The return value of the call to the proxy can be safely ignored.""" | ||
396 | 41 | |||
397 | 42 | def flag_error(*a): | ||
398 | 43 | """Make a twisted error from the error returned by the DBus call.""" | ||
399 | 44 | d.errback(*a) | ||
400 | 45 | |||
401 | 46 | def found_credentials(app_name, creds): | ||
402 | 47 | """Credentials have been found.""" | ||
403 | 48 | d.callback(creds) | ||
404 | 49 | |||
405 | 50 | proxy.connect_to_signal("CredentialsFound", found_credentials) | ||
406 | 51 | proxy.login_or_register_to_get_credentials("app", "tcurl", "help", 0, | ||
407 | 52 | reply_handler=ignore_return, | ||
408 | 53 | error_handler=flag_error) | ||
409 | 54 | return d | ||
410 | 0 | 55 | ||
411 | === added file 'ubuntuone/controlpanel/dbus_service.py' | |||
412 | --- ubuntuone/controlpanel/dbus_service.py 1970-01-01 00:00:00 +0000 | |||
413 | +++ ubuntuone/controlpanel/dbus_service.py 2010-09-24 23:06:03 +0000 | |||
414 | @@ -0,0 +1,74 @@ | |||
415 | 1 | # -*- coding: utf-8 -*- | ||
416 | 2 | |||
417 | 3 | # Authors: Alejandro J. Cura <alecu@canonical.com> | ||
418 | 4 | # | ||
419 | 5 | # Copyright 2010 Canonical Ltd. | ||
420 | 6 | # | ||
421 | 7 | # This program is free software: you can redistribute it and/or modify it | ||
422 | 8 | # under the terms of the GNU General Public License version 3, as published | ||
423 | 9 | # by the Free Software Foundation. | ||
424 | 10 | # | ||
425 | 11 | # This program is distributed in the hope that it will be useful, but | ||
426 | 12 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
427 | 13 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
428 | 14 | # PURPOSE. See the GNU General Public License for more details. | ||
429 | 15 | # | ||
430 | 16 | # You should have received a copy of the GNU General Public License along | ||
431 | 17 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
432 | 18 | |||
433 | 19 | """Export the control backend thru DBus.""" | ||
434 | 20 | |||
435 | 21 | import dbus.service | ||
436 | 22 | |||
437 | 23 | from dbus.mainloop.glib import DBusGMainLoop | ||
438 | 24 | from dbus.service import method, signal | ||
439 | 25 | |||
440 | 26 | from ubuntuone.controlpanel import (DBUS_BUS_NAME, DBUS_PREFERENCES_PATH, | ||
441 | 27 | DBUS_PREFERENCES_IFACE) | ||
442 | 28 | |||
443 | 29 | # XXX: should get this info from the web service | ||
444 | 30 | SAMPLE_DATA = { | ||
445 | 31 | "quota_used": "12345", | ||
446 | 32 | "quota_total": "54321", | ||
447 | 33 | "type": "paying customer", | ||
448 | 34 | "name": "john carlos", | ||
449 | 35 | "email": "john@carlos.com", | ||
450 | 36 | } | ||
451 | 37 | |||
452 | 38 | class ControlPanelBackend(dbus.service.Object): | ||
453 | 39 | """Export the Control Panel backend thru DBus.""" | ||
454 | 40 | # pylint: disable=C0103 | ||
455 | 41 | |||
456 | 42 | @method(dbus_interface=DBUS_PREFERENCES_IFACE, in_signature="") | ||
457 | 43 | def account_info(self): | ||
458 | 44 | """Find out the account info for the current logged in user.""" | ||
459 | 45 | self.AccountInfoReady(SAMPLE_DATA) | ||
460 | 46 | |||
461 | 47 | @signal(dbus_interface=DBUS_PREFERENCES_IFACE, signature="a{ss}") | ||
462 | 48 | def AccountInfoReady(self, info): | ||
463 | 49 | """The info for the current user is available now.""" | ||
464 | 50 | |||
465 | 51 | def init_mainloop(): | ||
466 | 52 | """Start the DBus mainloop.""" | ||
467 | 53 | DBusGMainLoop(set_as_default=True) | ||
468 | 54 | |||
469 | 55 | def register_service(): | ||
470 | 56 | """Try to register DBus service for making sure we run only one instance. | ||
471 | 57 | |||
472 | 58 | Return True if succesfully registered, False if already running. | ||
473 | 59 | """ | ||
474 | 60 | session_bus = dbus.SessionBus() | ||
475 | 61 | name = session_bus.request_name(DBUS_BUS_NAME, | ||
476 | 62 | dbus.bus.NAME_FLAG_DO_NOT_QUEUE) | ||
477 | 63 | return name != dbus.bus.REQUEST_NAME_REPLY_EXISTS | ||
478 | 64 | |||
479 | 65 | |||
480 | 66 | def get_busname(): | ||
481 | 67 | """Build the DBus BusName.""" | ||
482 | 68 | return dbus.service.BusName(DBUS_BUS_NAME, bus=dbus.SessionBus()) | ||
483 | 69 | |||
484 | 70 | |||
485 | 71 | def publish_backend(): | ||
486 | 72 | """Publish the backend on the DBus.""" | ||
487 | 73 | ControlPanelBackend(object_path=DBUS_PREFERENCES_PATH, | ||
488 | 74 | bus_name=get_busname()) | ||
489 | 0 | 75 | ||
490 | === added file 'ubuntuone/controlpanel/tests/test_backend.py' | |||
491 | --- ubuntuone/controlpanel/tests/test_backend.py 1970-01-01 00:00:00 +0000 | |||
492 | +++ ubuntuone/controlpanel/tests/test_backend.py 2010-09-24 23:06:03 +0000 | |||
493 | @@ -0,0 +1,31 @@ | |||
494 | 1 | # -*- coding: utf-8 -*- | ||
495 | 2 | |||
496 | 3 | # Authors: Alejandro J. Cura <alecu@canonical.com> | ||
497 | 4 | # | ||
498 | 5 | # Copyright 2010 Canonical Ltd. | ||
499 | 6 | # | ||
500 | 7 | # This program is free software: you can redistribute it and/or modify it | ||
501 | 8 | # under the terms of the GNU General Public License version 3, as published | ||
502 | 9 | # by the Free Software Foundation. | ||
503 | 10 | # | ||
504 | 11 | # This program is distributed in the hope that it will be useful, but | ||
505 | 12 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
506 | 13 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
507 | 14 | # PURPOSE. See the GNU General Public License for more details. | ||
508 | 15 | # | ||
509 | 16 | # You should have received a copy of the GNU General Public License along | ||
510 | 17 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
511 | 18 | |||
512 | 19 | """Tests for the control panel backend.""" | ||
513 | 20 | |||
514 | 21 | from twisted.trial.unittest import TestCase | ||
515 | 22 | |||
516 | 23 | from ubuntuone.controlpanel import backend | ||
517 | 24 | |||
518 | 25 | class BackendBasicTestCase(TestCase): | ||
519 | 26 | """Simple tests for the backend.""" | ||
520 | 27 | |||
521 | 28 | def test_backend_creation(self): | ||
522 | 29 | """The backend instance is created.""" | ||
523 | 30 | be = backend.ControlBackend() | ||
524 | 31 | self.assertNotEqual(be, None) | ||
525 | 0 | 32 | ||
526 | === added file 'ubuntuone/controlpanel/webclient.py' | |||
527 | --- ubuntuone/controlpanel/webclient.py 1970-01-01 00:00:00 +0000 | |||
528 | +++ ubuntuone/controlpanel/webclient.py 2010-09-24 23:06:03 +0000 | |||
529 | @@ -0,0 +1,26 @@ | |||
530 | 1 | # Authors: Alejandro J. Cura <alecu@canonical.com> | ||
531 | 2 | # | ||
532 | 3 | # Copyright 2010 Canonical Ltd. | ||
533 | 4 | # | ||
534 | 5 | # This program is free software: you can redistribute it and/or modify it | ||
535 | 6 | # under the terms of the GNU General Public License version 3, as published | ||
536 | 7 | # by the Free Software Foundation. | ||
537 | 8 | # | ||
538 | 9 | # This program is distributed in the hope that it will be useful, but | ||
539 | 10 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
540 | 11 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
541 | 12 | # PURPOSE. See the GNU General Public License for more details. | ||
542 | 13 | # | ||
543 | 14 | # You should have received a copy of the GNU General Public License along | ||
544 | 15 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
545 | 16 | |||
546 | 17 | """The control panel backend webservice client.""" | ||
547 | 18 | |||
548 | 19 | import urllib | ||
549 | 20 | |||
550 | 21 | BASE_URL = "https://one.ubuntu.com/api/1.0/" | ||
551 | 22 | |||
552 | 23 | def getinfo(): | ||
553 | 24 | """Get the info from the url.""" | ||
554 | 25 | f = urllib.urlopen(BASE_URL + "devices/") | ||
555 | 26 | return f.read() |
Very nice!