Merge lp:~nataliabidart/ubuntuone-control-panel/bind-some-more into lp:ubuntuone-control-panel

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 161
Merged at revision: 151
Proposed branch: lp:~nataliabidart/ubuntuone-control-panel/bind-some-more
Merge into: lp:ubuntuone-control-panel
Diff against target: 2579 lines (+616/-393)
33 files modified
.bzrignore (+1/-1)
bin/ubuntuone-control-panel-gtk (+2/-2)
bin/ubuntuone-control-panel-qt (+2/-2)
data/qt/controlpanel.ui (+5/-5)
data/qt/mainwindow.ui (+1/-1)
data/qt/preferences.ui (+1/-1)
po/POTFILES.in (+9/-9)
run-tests (+2/-2)
setup.py (+5/-5)
ubuntuone/controlpanel/__init__.py (+1/-0)
ubuntuone/controlpanel/backend.py (+1/-1)
ubuntuone/controlpanel/gui/__init__.py (+116/-0)
ubuntuone/controlpanel/gui/gtk/__init__.py (+5/-1)
ubuntuone/controlpanel/gui/gtk/gui.py (+79/-173)
ubuntuone/controlpanel/gui/gtk/tests/__init__.py (+4/-4)
ubuntuone/controlpanel/gui/gtk/tests/test_gui.py (+63/-61)
ubuntuone/controlpanel/gui/gtk/tests/test_gui_basic.py (+6/-6)
ubuntuone/controlpanel/gui/gtk/tests/test_package_manager.py (+1/-1)
ubuntuone/controlpanel/gui/gtk/tests/test_widgets.py (+1/-1)
ubuntuone/controlpanel/gui/qt/__init__.py (+4/-1)
ubuntuone/controlpanel/gui/qt/controlpanel.py (+53/-4)
ubuntuone/controlpanel/gui/qt/devices.py (+1/-1)
ubuntuone/controlpanel/gui/qt/folders.py (+1/-1)
ubuntuone/controlpanel/gui/qt/gui.py (+5/-1)
ubuntuone/controlpanel/gui/qt/preferences.py (+1/-1)
ubuntuone/controlpanel/gui/qt/profile.py (+1/-1)
ubuntuone/controlpanel/gui/qt/services.py (+1/-1)
ubuntuone/controlpanel/gui/qt/tests/__init__.py (+58/-0)
ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py (+77/-0)
ubuntuone/controlpanel/gui/qt/tests/test_gui.py (+8/-28)
ubuntuone/controlpanel/integrationtests/test_gui_service.py (+3/-3)
ubuntuone/controlpanel/integrationtests/test_sd_client/linux.py (+63/-56)
ubuntuone/controlpanel/sd_client/linux.py (+35/-19)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-control-panel/bind-some-more
Reviewer Review Type Date Requested Status
Eric Casteleijn (community) Approve
Alejandro J. Cura (community) Approve
Review via email: mp+62191@code.launchpad.net

Commit message

- Unify GTK and QT UI implementations into a new gui module.
- Move all human readable and translatable strings into a common gui module so both GTK and QT can use them.
- Binded QT UI with backend to update the sync status label according to syncdaemon status changes (UI tests included).

Description of the change

To run the test suites, please make sure to have a clone of the qtreactor and then:

./run-tests
./run-tests -qt

To run the UI, please build the source code and run:

DEBUG=True PYTHONPATH=. ./bin/ubuntuone-control-panel-qt

To test the status label changes, you will need to trigger status changes yourself, since as you can see from the block:

1485 + # this call is crashing with MemoryError as per
1486 + # http://pastebin.ubuntu.com/612270/
1487 + #self.backend.file_sync_status()

that we can't query syncdaemon at the moment (from linux at least). To trigger status changes either drop a file inside Ubuntu One or disconnect/connect your syncdaemon (u1sdtool -d/u1sdtool -c).

The diff is huge, but consider that most of the changes are caused by having the new gui module grouping both UI implementation. The important part of this diff is all the changes made to:

ubuntuone/controlpanel/gui/qt/controlpanel.py
ubuntuone/controlpanel/gui/qt/tests/*.py

Thanks!

To post a comment you must log in.
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Note: all the changes regarding SyncDaemonTool imports and syncdaemon DBus constants are meant to avoid twisted installing a default reactor in the import chain (ie before we install our own qt reactor).

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

Looks very good.

review: Approve
160. By Natalia Bidart

Forgotten files and factory for a SyncDaemonTool.

161. By Natalia Bidart

Merged trunk in.

Revision history for this message
Eric Casteleijn (thisfred) wrote :

Awesome code, both sets of tests pass, and the label changes work. +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2011-05-23 17:19:29 +0000
3+++ .bzrignore 2011-05-24 20:11:16 +0000
4@@ -5,5 +5,5 @@
5 dist/
6 po/ubuntuone-control-panel.pot
7 ubuntuone/controlpanel/constants.py
8-ubuntuone/controlpanel/qt/ui/*_ui.py
9+ubuntuone/controlpanel/gui/qt/ui/*_ui.py
10 qtreactor/
11\ No newline at end of file
12
13=== modified file 'bin/ubuntuone-control-panel-gtk'
14--- bin/ubuntuone-control-panel-gtk 2011-03-31 16:41:07 +0000
15+++ bin/ubuntuone-control-panel-gtk 2011-05-24 20:11:16 +0000
16@@ -26,11 +26,11 @@
17
18 from optparse import OptionParser
19
20-from ubuntuone.controlpanel.gtk import TRANSLATION_DOMAIN
21+from ubuntuone.controlpanel import TRANSLATION_DOMAIN
22
23 gettext.textdomain(TRANSLATION_DOMAIN)
24 # import the GUI after the translation domain has been set
25-from ubuntuone.controlpanel.gtk.gui import main
26+from ubuntuone.controlpanel.gui.gtk import main
27
28
29 def parser_options():
30
31=== modified file 'bin/ubuntuone-control-panel-qt'
32--- bin/ubuntuone-control-panel-qt 2011-05-20 16:59:25 +0000
33+++ bin/ubuntuone-control-panel-qt 2011-05-24 20:11:16 +0000
34@@ -26,11 +26,11 @@
35
36 from optparse import OptionParser
37
38-from ubuntuone.controlpanel.qt import TRANSLATION_DOMAIN
39+from ubuntuone.controlpanel import TRANSLATION_DOMAIN
40
41 gettext.textdomain(TRANSLATION_DOMAIN)
42 # import the GUI after the translation domain has been set
43-from ubuntuone.controlpanel.qt.gui import main
44+from ubuntuone.controlpanel.gui.qt import main
45
46
47 def parser_options():
48
49=== modified file 'data/qt/controlpanel.ui'
50--- data/qt/controlpanel.ui 2011-05-23 16:24:47 +0000
51+++ data/qt/controlpanel.ui 2011-05-24 20:11:16 +0000
52@@ -213,31 +213,31 @@
53 <customwidget>
54 <class>FoldersPanel</class>
55 <extends>QWidget</extends>
56- <header>ubuntuone.controlpanel.qt.folders</header>
57+ <header>ubuntuone.controlpanel.gui.qt.folders</header>
58 <container>1</container>
59 </customwidget>
60 <customwidget>
61 <class>ServicesPanel</class>
62 <extends>QWidget</extends>
63- <header>ubuntuone.controlpanel.qt.services</header>
64+ <header>ubuntuone.controlpanel.gui.qt.services</header>
65 <container>1</container>
66 </customwidget>
67 <customwidget>
68 <class>DevicesPanel</class>
69 <extends>QWidget</extends>
70- <header>ubuntuone.controlpanel.qt.devices</header>
71+ <header>ubuntuone.controlpanel.gui.qt.devices</header>
72 <container>1</container>
73 </customwidget>
74 <customwidget>
75 <class>PreferencesPanel</class>
76 <extends>QWidget</extends>
77- <header>ubuntuone.controlpanel.qt.preferences</header>
78+ <header>ubuntuone.controlpanel.gui.qt.preferences</header>
79 <container>1</container>
80 </customwidget>
81 <customwidget>
82 <class>ProfilePanel</class>
83 <extends>QWidget</extends>
84- <header>ubuntuone.controlpanel.qt.profile</header>
85+ <header>ubuntuone.controlpanel.gui.qt.profile</header>
86 <container>1</container>
87 </customwidget>
88 </customwidgets>
89
90=== modified file 'data/qt/mainwindow.ui'
91--- data/qt/mainwindow.ui 2011-05-23 18:16:06 +0000
92+++ data/qt/mainwindow.ui 2011-05-24 20:11:16 +0000
93@@ -43,7 +43,7 @@
94 <customwidget>
95 <class>ControlPanel</class>
96 <extends>QWidget</extends>
97- <header>ubuntuone.controlpanel.qt.controlpanel</header>
98+ <header>ubuntuone.controlpanel.gui.qt.controlpanel</header>
99 <container>1</container>
100 </customwidget>
101 </customwidgets>
102
103=== modified file 'data/qt/preferences.ui'
104--- data/qt/preferences.ui 2011-05-23 16:13:27 +0000
105+++ data/qt/preferences.ui 2011-05-24 20:11:16 +0000
106@@ -24,7 +24,7 @@
107 <item>
108 <widget class="QGroupBox" name="groupBox">
109 <property name="title">
110- <string>Bandwidth Settings</string>
111+ <string>Bandwidth settings</string>
112 </property>
113 <layout class="QGridLayout" name="gridLayout">
114 <item row="0" column="0">
115
116=== modified file 'po/POTFILES.in'
117--- po/POTFILES.in 2011-04-01 18:53:11 +0000
118+++ po/POTFILES.in 2011-05-24 20:11:16 +0000
119@@ -1,10 +1,10 @@
120 ubuntuone-control-panel-gtk.desktop.in
121-ubuntuone/controlpanel/gtk/gui.py
122-[type: gettext/glade] data/dashboard.ui
123-[type: gettext/glade] data/device.ui
124-[type: gettext/glade] data/devices.ui
125-[type: gettext/glade] data/install.ui
126-[type: gettext/glade] data/management.ui
127-[type: gettext/glade] data/overview.ui
128-[type: gettext/glade] data/services.ui
129-[type: gettext/glade] data/volumes.ui
130+ubuntuone/controlpanel/gui/__init__.py
131+[type: gettext/glade] data/gtk/dashboard.ui
132+[type: gettext/glade] data/gtk/device.ui
133+[type: gettext/glade] data/gtk/devices.ui
134+[type: gettext/glade] data/gtk/install.ui
135+[type: gettext/glade] data/gtk/management.ui
136+[type: gettext/glade] data/gtk/overview.ui
137+[type: gettext/glade] data/gtk/services.ui
138+[type: gettext/glade] data/gtk/volumes.ui
139
140=== modified file 'run-tests'
141--- run-tests 2011-05-20 20:25:55 +0000
142+++ run-tests 2011-05-24 20:11:16 +0000
143@@ -16,8 +16,8 @@
144 # You should have received a copy of the GNU General Public License along
145 # with this program. If not, see <http://www.gnu.org/licenses/>.
146
147-QT_TESTS_PATH=ubuntuone/controlpanel/qt/tests
148-GTK_TESTS_PATH=ubuntuone/controlpanel/gtk/tests
149+QT_TESTS_PATH=ubuntuone/controlpanel/gui/qt/tests
150+GTK_TESTS_PATH=ubuntuone/controlpanel/gui/gtk/tests
151
152 set -e
153
154
155=== modified file 'setup.py'
156--- setup.py 2011-05-20 19:41:25 +0000
157+++ setup.py 2011-05-24 20:11:16 +0000
158@@ -73,6 +73,7 @@
159 class ControlPanelBuild(build_extra.build_extra):
160 """Build PyQt (.ui) files and resources."""
161
162+ QT_UI_DIR = os.path.join('ubuntuone', 'controlpanel', 'gui', 'qt', 'ui')
163 description = "build PyQt GUIs (.ui) and resources (.qrc)"
164
165 def compile_ui(self, ui_file, py_file=None):
166@@ -83,8 +84,7 @@
167 # python file in the qt moodule
168 py_file = os.path.split(ui_file)[1]
169 py_file = os.path.splitext(py_file)[0] + '_ui.py'
170- py_file = os.path.join('ubuntuone', 'controlpanel', 'qt', 'ui',
171- py_file)
172+ py_file = os.path.join(self.QT_UI_DIR, py_file)
173 # we indeed want to catch Exception, is ugly but we need it
174 # pylint: disable=W0703
175 try:
176@@ -110,8 +110,7 @@
177 if py_file is None:
178 py_file = os.path.split(qrc_file)[1]
179 py_file = os.path.splitext(py_file)[0] + '_rc.py'
180- py_file = os.path.join('ubuntuone', 'controlpanel', 'qt', 'ui',
181- py_file)
182+ py_file = os.path.join(self.QT_UI_DIR, py_file)
183 path = os.getenv('PATH')
184 os.putenv('PATH', path + os.path.pathsep + os.path.join(
185 os.path.dirname(PyQt4.__file__),'bin'))
186@@ -227,7 +226,8 @@
187 'DBus service to query/modify all the Ubuntu One bits.',
188 url='https://launchpad.net/ubuntuone-control-panel',
189 packages=[
190- 'ubuntuone', 'ubuntuone.controlpanel', 'ubuntuone.controlpanel.gtk',
191+ 'ubuntuone', 'ubuntuone.controlpanel',
192+ 'ubuntuone.controlpanel.gui.gtk', 'ubuntuone.controlpanel.gui.qt',
193 'ubuntuone.controlpanel.login_client', 'ubuntuone.controlpanel.sd_client',
194 'ubuntuone.controlpanel.web_client',
195 ],
196
197=== modified file 'ubuntuone/controlpanel/__init__.py'
198--- ubuntuone/controlpanel/__init__.py 2010-12-18 17:35:01 +0000
199+++ ubuntuone/controlpanel/__init__.py 2011-05-24 20:11:16 +0000
200@@ -30,3 +30,4 @@
201 DBUS_PREFERENCES_IFACE = "com.ubuntuone.controlpanel.Preferences"
202
203 WEBSERVICE_BASE_URL = u"https://one.ubuntu.com/api/"
204+TRANSLATION_DOMAIN = 'ubuntuone-control-panel'
205
206=== modified file 'ubuntuone/controlpanel/backend.py'
207--- ubuntuone/controlpanel/backend.py 2011-05-19 19:03:04 +0000
208+++ ubuntuone/controlpanel/backend.py 2011-05-24 20:11:16 +0000
209@@ -168,7 +168,7 @@
210 result = self._process_file_sync_status(status)
211 handler(result)
212
213- self._status_changed_handler = process_and_callback
214+ self._status_changed_handler = handler
215 sd_client.set_status_changed_handler(process_and_callback)
216
217 def _get_status_changed_handler(self):
218
219=== added directory 'ubuntuone/controlpanel/gui'
220=== added file 'ubuntuone/controlpanel/gui/__init__.py'
221--- ubuntuone/controlpanel/gui/__init__.py 1970-01-01 00:00:00 +0000
222+++ ubuntuone/controlpanel/gui/__init__.py 2011-05-24 20:11:16 +0000
223@@ -0,0 +1,116 @@
224+# -*- coding: utf-8 -*-
225+
226+# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
227+#
228+# Copyright 2011 Canonical Ltd.
229+#
230+# This program is free software: you can redistribute it and/or modify it
231+# under the terms of the GNU General Public License version 3, as published
232+# by the Free Software Foundation.
233+#
234+# This program is distributed in the hope that it will be useful, but
235+# WITHOUT ANY WARRANTY; without even the implied warranties of
236+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
237+# PURPOSE. See the GNU General Public License for more details.
238+#
239+# You should have received a copy of the GNU General Public License along
240+# with this program. If not, see <http://www.gnu.org/licenses/>.
241+
242+"""The control panel UI for Ubuntu One."""
243+
244+import gettext
245+
246+_ = gettext.gettext
247+
248+
249+ERROR_COLOR = 'red'
250+KILOBYTES = 1024
251+NO_OP = lambda *a, **kw: None
252+# http://design.canonical.com/the-toolkit/ubuntu-logo-and-circle-of-friends/
253+ORANGE = '#DD4814'
254+QUOTA_THRESHOLD = 0.95
255+SHARES_MIN_SIZE_FULL = 1048576
256+
257+LEARN_MORE_LINK = 'https://one.ubuntu.com/'
258+CONTACTS_LINK = 'https://one.ubuntu.com/'
259+FILE_URI_PREFIX = 'file://'
260+
261+ALWAYS_SUBSCRIBED = _('Always in sync!')
262+BOOKMARKS = _('Firefox extension')
263+CONNECT_BUTTON_LABEL = _('Connect to Ubuntu One')
264+CONTACTS = _('Evolution plug-in')
265+CREDENTIALS_ERROR = _('There was a problem while retrieving the credentials.')
266+DASHBOARD_BUTTON_TOOLTIP = _('View your personal details and service '
267+ 'summary')
268+DASHBOARD_TITLE = _('Welcome to Ubuntu One!')
269+DASHBOARD_VALUE_ERROR = _('The information could not be retrieved. '
270+ 'Maybe your internet connection is down?')
271+DESKTOPCOUCH_PKG = 'desktopcouch-ubuntuone'
272+DEVICE_CHANGE_ERROR = _('The settings could not be changed,\n'
273+ 'previous values were restored.')
274+DEVICE_CONFIRM_REMOVE = _('Are you sure you want to remove this device '
275+ 'from Ubuntu One?')
276+DEVICE_REMOVABLE_PREFIX = 'Ubuntu One @ '
277+DEVICE_REMOVAL_ERROR = _('The device could not be removed.')
278+DEVICES_BUTTON_TOOLTIP = _('Manage devices registered with your personal '
279+ 'cloud')
280+DEVICES_TITLE = _('The devices connected with your personal cloud are listed '
281+ 'below.')
282+FAILED_INSTALL = _('<i>%(package_name)s</i> could not be installed')
283+FOLDERS_CONFIRM_MERGE = _('The contents of your cloud folder will be merged '
284+ 'with your local folder "%(folder_path)s" when '
285+ 'subscribing.\nDo you want to subscribe to this '
286+ 'cloud folder?')
287+FOLDERS_BUTTON_TOOLTIP = VOLUMES_BUTTON_TOOLTIP = _('Manage your cloud '
288+ 'folders')
289+FOLDERS_TITLE = _('Select which folders from your cloud you want to sync with '
290+ 'this computer')
291+FILE_SYNC_CONNECT = _('Connect')
292+FILE_SYNC_CONNECT_TOOLTIP = _('Connect the file sync service with '
293+ 'your personal cloud')
294+FILE_SYNC_DISABLED = _('File Sync is disabled.')
295+FILE_SYNC_DISCONNECT = _('Disconnect')
296+FILE_SYNC_DISCONNECT_TOOLTIP = _('Disconnect the file sync service from '
297+ 'your personal cloud')
298+FILE_SYNC_DISCONNECTED = _('File Sync is disconnected.')
299+FILE_SYNC_ENABLE = _('Enable')
300+FILE_SYNC_ENABLE_TOOLTIP = _('Enable the file sync service')
301+FILE_SYNC_ERROR = _('File Sync error.')
302+FILE_SYNC_IDLE = _('File Sync is up-to-date.')
303+FILE_SYNC_RESTART = _('Restart')
304+FILE_SYNC_RESTART_TOOLTIP = _('Restart the file sync service')
305+FILE_SYNC_SERVICE_NAME = _('File Sync')
306+FILE_SYNC_START = _('Start')
307+FILE_SYNC_START_TOOLTIP = _('Start the file sync service')
308+FILE_SYNC_STARTING = _('File Sync starting...')
309+FILE_SYNC_STOP = _('Stop')
310+FILE_SYNC_STOP_TOOLTIP = _('Stop the file sync service')
311+FILE_SYNC_STOPPED = _('File Sync is stopped.')
312+FILE_SYNC_SYNCING = _('File Sync in progress...')
313+FREE_SPACE_TEXT = _('%(free_space)s available storage')
314+INSTALL_PACKAGE = _('You need to install the package <i>%(package_name)s'
315+ '</i> in order to enable more sync services.')
316+INSTALL_PLUGIN = _('Install the %(plugin_name)s for the sync service: '
317+ '%(service_name)s')
318+INSTALLING = _('Installation of <i>%(package_name)s</i> in progress')
319+LOADING = _('Loading...')
320+MAIN_WINDOW_TITLE = _('%(app_name)s Control Panel')
321+MY_FOLDERS = _('My folders')
322+NAME_NOT_SET = _('[unknown user name]')
323+MUSIC_DISPLAY_NAME = _('Purchased Music')
324+MUSIC_REAL_PATH = '.ubuntuone/Purchased from Ubuntu One'
325+NETWORK_OFFLINE = _('An internet connection is required to join or sign '
326+ 'in to %(app_name)s.')
327+NO_DEVICES = _('No devices to show.')
328+NO_FOLDERS = _('No folders to show.')
329+NO_PAIRING_RECORD = _('There is no Ubuntu One pairing record.')
330+QUOTA_LABEL = _('Using %(used)s of %(total)s (%(percentage).0f%%)')
331+SERVICES_BUTTON_TOOLTIP = _('Manage the sync services')
332+SERVICES_TITLE = _('Enable the sync services for this computer.')
333+SETTINGS_CHANGE_ERROR = _('The settings could not be changed,\n'
334+ 'previous values were restored.')
335+SHARES_BUTTON_TOOLTIP = _('Manage the shares offered to others')
336+SHARES_TITLE = _('Manage permissions for shares made to other users.')
337+SUCCESS_INSTALL = _('<i>%(package_name)s</i> was successfully installed')
338+VALUE_ERROR = _('Value could not be retrieved.')
339+UNKNOWN_ERROR = _('Unknown error')
340
341=== renamed directory 'ubuntuone/controlpanel/gtk' => 'ubuntuone/controlpanel/gui/gtk'
342=== modified file 'ubuntuone/controlpanel/gui/gtk/__init__.py'
343--- ubuntuone/controlpanel/gtk/__init__.py 2011-03-29 19:14:21 +0000
344+++ ubuntuone/controlpanel/gui/gtk/__init__.py 2011-05-24 20:11:16 +0000
345@@ -21,4 +21,8 @@
346 DBUS_BUS_NAME = 'com.ubuntuone.controlpanel.gui'
347 DBUS_PATH = '/gui'
348 DBUS_IFACE_GUI = 'com.ubuntuone.controlpanel.gui'
349-TRANSLATION_DOMAIN = 'ubuntuone-control-panel'
350+
351+# Unused import main
352+# pylint: disable=W0611
353+
354+from ubuntuone.controlpanel.gui.gtk.gui import main
355
356=== modified file 'ubuntuone/controlpanel/gui/gtk/gui.py'
357--- ubuntuone/controlpanel/gtk/gui.py 2011-05-19 19:03:04 +0000
358+++ ubuntuone/controlpanel/gui/gtk/gui.py 2011-05-24 20:11:16 +0000
359@@ -21,7 +21,6 @@
360
361 from __future__ import division
362
363-import gettext
364 import os
365
366 from functools import wraps
367@@ -42,15 +41,19 @@
368 PING_URL as U1_PING_URL, DESCRIPTION as U1_DESCRIPTION)
369 # pylint: enable=E0611,F0401
370
371-from ubuntuone.controlpanel.gtk import (
372+# Wildcard import ubuntuone.controlpanel.gui
373+# pylint: disable=W0401, W0614
374+from ubuntuone.controlpanel.gui import *
375+# pylint: enable=W0401, W0614
376+from ubuntuone.controlpanel.gui.gtk import (
377 DBUS_IFACE_GUI, DBUS_BUS_NAME as DBUS_BUS_NAME_GUI,
378- DBUS_PATH as DBUS_PATH_GUI)
379-from ubuntuone.controlpanel.gtk.widgets import LabelLoading, PanelTitle
380+ DBUS_PATH as DBUS_PATH_GUI, package_manager)
381+from ubuntuone.controlpanel.gui.gtk.widgets import LabelLoading, PanelTitle
382 # Use ubiquity package when ready (LP: #673665)
383-from ubuntuone.controlpanel.gtk.widgets import GreyableBin
384+from ubuntuone.controlpanel.gui.gtk.widgets import GreyableBin
385
386 from ubuntuone.controlpanel import (DBUS_BUS_NAME, DBUS_PREFERENCES_PATH,
387- DBUS_PREFERENCES_IFACE, backend)
388+ DBUS_PREFERENCES_IFACE, TRANSLATION_DOMAIN, backend)
389 from ubuntuone.controlpanel.backend import (DEVICE_TYPE_PHONE,
390 DEVICE_TYPE_COMPUTER)
391 from ubuntuone.controlpanel.dbus_service import bool_str
392@@ -58,7 +61,6 @@
393 from ubuntuone.controlpanel.utils import (get_data_file,
394 ERROR_TYPE, ERROR_MESSAGE)
395
396-from ubuntuone.controlpanel.gtk import package_manager, TRANSLATION_DOMAIN
397
398 try:
399 from gi.repository import Unity # pylint: disable=E0611
400@@ -68,19 +70,9 @@
401 USE_LIBUNITY = False
402
403 logger = setup_logging('gtk.gui')
404-_ = gettext.gettext
405-
406-
407-# http://design.canonical.com/the-toolkit/ubuntu-logo-and-circle-of-friends/
408-ORANGE = '#DD4814'
409-ERROR_COLOR = 'red'
410-LOADING = _('Loading...')
411-VALUE_ERROR = _('Value could not be retrieved.')
412-UNKNOWN_ERROR = _('Unknown error')
413+
414+
415 WARNING_MARKUP = '<span foreground="%s"><b>%%s</b></span>' % ERROR_COLOR
416-KILOBYTES = 1024
417-NO_OP = lambda *a, **kw: None
418-FILE_URI_PREFIX = 'file://'
419
420
421 def error_handler(*args, **kwargs):
422@@ -159,7 +151,7 @@
423
424
425 class ControlPanelMixin(object):
426- """The main interface for the Ubuntu One control panel."""
427+ """A basic mixin class to provide common functionality to widgets."""
428
429 def __init__(self, filename=None, backend_instance=None):
430 if backend_instance is not None:
431@@ -278,13 +270,6 @@
432 (gobject.TYPE_BOOLEAN, gobject.TYPE_PYOBJECT)),
433 }
434
435- CREDENTIALS_ERROR = _('There was a problem while retrieving the '
436- 'credentials.')
437- NETWORK_OFFLINE = _('An internet connection is required to join or sign '
438- 'in to %(app_name)s.')
439- CONNECT = _('Connect to Ubuntu One')
440- LEARN_MORE_LINK = 'https://one.ubuntu.com/'
441-
442 def __init__(self, main_window):
443 GreyableBin.__init__(self)
444
445@@ -308,7 +293,7 @@
446 self.warning_label.set_text('')
447 self.warning_label.set_property('xalign', 0.5)
448
449- self.connect_button.set_uri(self.CONNECT)
450+ self.connect_button.set_uri(CONNECT_BUTTON_LABEL)
451
452 self.main_window = main_window
453 self._credentials_are_new = False
454@@ -371,7 +356,7 @@
455
456 def on_learn_more_button_clicked(self, *a, **kw):
457 """User wants to learn more."""
458- uri_hook(self.learn_more_button, self.LEARN_MORE_LINK)
459+ uri_hook(self.learn_more_button, LEARN_MORE_LINK)
460
461 @filter_by_app_name
462 @log_call(logger.info, with_args=False)
463@@ -392,7 +377,7 @@
464 def on_credentials_error(self, app_name, error_dict):
465 """SSO backend notifies of an error when fetching credentials."""
466 self.set_property('greyed', False)
467- self._set_warning(self.CREDENTIALS_ERROR)
468+ self._set_warning(CREDENTIALS_ERROR)
469
470 @filter_by_app_name
471 @log_call(logger.info)
472@@ -405,7 +390,7 @@
473 """Network state is reported."""
474 msg = ''
475 if state is networkstate.OFFLINE:
476- msg = self.NETWORK_OFFLINE % {'app_name': U1_APP_NAME}
477+ msg = NETWORK_OFFLINE % {'app_name': U1_APP_NAME}
478 self.set_sensitive(False)
479 self._set_warning(msg)
480 else:
481@@ -418,9 +403,8 @@
482 class DashboardPanel(UbuntuOneBin, ControlPanelMixin):
483 """The dashboard panel. The user can manage the subscription."""
484
485- TITLE = _('Welcome to Ubuntu One!')
486- VALUE_ERROR = _('The information could not be retrieved. '
487- 'Maybe your internet connection is down?')
488+ TITLE = DASHBOARD_TITLE
489+ VALUE_ERROR = DASHBOARD_VALUE_ERROR
490
491 def __init__(self, main_window=None):
492 UbuntuOneBin.__init__(self)
493@@ -458,22 +442,8 @@
494 class VolumesPanel(UbuntuOneBin, ControlPanelMixin):
495 """The volumes panel."""
496
497- TITLE = _('Select which folders from your cloud you want to sync with '
498- 'this computer')
499- MY_FOLDERS = _('My folders')
500- ALWAYS_SUBSCRIBED = _('Always in sync!')
501- FREE_SPACE_TEXT = _('%(free_space)s available storage')
502- NO_VOLUMES = _('No folders to show.')
503- NAME_NOT_SET = _('[unknown user name]')
504- CONFIRM_MERGE = _('The contents of your cloud folder will be merged with '
505- 'your local folder "%(folder_path)s" when subscribing.\n'
506- 'Do you want to subscribe to this cloud folder?')
507- MUSIC_DISPLAY_NAME = _('Purchased Music')
508- MUSIC_REAL_PATH = '.ubuntuone/Purchased from Ubuntu One'
509-
510+ TITLE = FOLDERS_TITLE
511 MAX_COLS = 8
512- MIN_SIZE_FULL = 1048576
513-
514 CONTACT_ICON_NAME = 'avatar-default'
515 FOLDER_ICON_NAME = 'folder'
516 SHARE_ICON_NAME = 'folder-remote'
517@@ -511,8 +481,8 @@
518
519 def _process_name(self, name):
520 """Tweak 'name' with a translatable music folder name."""
521- if name == self.MUSIC_REAL_PATH:
522- result = self.MUSIC_DISPLAY_NAME
523+ if name == MUSIC_REAL_PATH:
524+ result = MUSIC_DISPLAY_NAME
525 else:
526 result = name
527 return result
528@@ -522,28 +492,28 @@
529
530 self.volumes_store.clear()
531 if not info:
532- self.on_success(self.NO_VOLUMES)
533+ self.on_success(NO_FOLDERS)
534 return
535 else:
536 self.on_success()
537
538 for name, free_bytes, volumes in info:
539 if backend.ControlBackend.NAME_NOT_SET in name:
540- name = self.NAME_NOT_SET
541+ name = NAME_NOT_SET
542
543 if name:
544 name = name + "'s"
545 # we already added user folders, let's add an empty row
546 treeiter = self.volumes_store.append(None, self._empty_row)
547 else:
548- name = self.MY_FOLDERS
549+ name = MY_FOLDERS
550
551 scroll_to_cell = False
552 if free_bytes == backend.ControlBackend.FREE_BYTES_NOT_AVAILABLE:
553 free_bytes = ''
554 else:
555 free_bytes = int(free_bytes)
556- if free_bytes < self.MIN_SIZE_FULL:
557+ if free_bytes < SHARES_MIN_SIZE_FULL:
558 free_bytes_str = self.NO_FREE_SPACE
559 scroll_to_cell = True
560 else:
561@@ -570,10 +540,10 @@
562
563 if is_root:
564 sensitive = False
565- name = self.ROOT % (name, ORANGE, self.ALWAYS_SUBSCRIBED)
566+ name = self.ROOT % (name, ORANGE, ALWAYS_SUBSCRIBED)
567 elif is_share:
568 icon_name = self.SHARE_ICON_NAME
569- elif name == self.MUSIC_DISPLAY_NAME:
570+ elif name == MUSIC_DISPLAY_NAME:
571 icon_name = self.MUSIC_ICON_NAME
572
573 if volume[u'path'] is None:
574@@ -618,7 +588,7 @@
575
576 response = gtk.RESPONSE_YES
577 if not subscribed and os.path.exists(volume_path):
578- self.confirm_dialog.set_markup(self.CONFIRM_MERGE %
579+ self.confirm_dialog.set_markup(FOLDERS_CONFIRM_MERGE %
580 {'folder_path': volume_path})
581 response = self.confirm_dialog.run()
582 self.confirm_dialog.hide()
583@@ -655,7 +625,7 @@
584 class SharesPanel(UbuntuOneBin, ControlPanelMixin):
585 """The shares panel - NOT IMPLEMENTED YET."""
586
587- TITLE = _('Manage permissions for shares made to other users.')
588+ TITLE = SHARES_TITLE
589
590 def __init__(self, main_window=None):
591 UbuntuOneBin.__init__(self)
592@@ -667,11 +637,6 @@
593 class Device(gtk.EventBox, ControlPanelMixin):
594 """The device widget."""
595
596- DEVICE_CHANGE_ERROR = _('The settings could not be changed,\n'
597- 'previous values were restored.')
598- DEVICE_REMOVAL_ERROR = _('The device could not be removed.')
599- REMOVABLE_PREFIX = 'Ubuntu One @ '
600-
601 def __init__(self, confirm_remove_dialog=None):
602 gtk.EventBox.__init__(self)
603 ControlPanelMixin.__init__(self, filename='device.ui')
604@@ -771,7 +736,7 @@
605 self.id = kwargs['device_id']
606
607 if 'device_name' in kwargs:
608- name = kwargs['device_name'].replace(self.REMOVABLE_PREFIX, '')
609+ name = kwargs['device_name'].replace(DEVICE_REMOVABLE_PREFIX, '')
610 name = '<span font_size="large"><b>%s</b></span>' % name
611 self.device_name.set_markup(name)
612
613@@ -837,7 +802,7 @@
614 if device_id != self.id:
615 return
616 self.update(**self._last_settings)
617- self._set_warning(self.DEVICE_CHANGE_ERROR, self.warning_label)
618+ self._set_warning(DEVICE_CHANGE_ERROR, self.warning_label)
619 self.set_sensitive(True)
620
621 # is safe to log the device_id since it was already removed
622@@ -853,7 +818,7 @@
623 """The removal of this device failed."""
624 if device_id != self.id:
625 return
626- self._set_warning(self.DEVICE_REMOVAL_ERROR, self.warning_label)
627+ self._set_warning(DEVICE_REMOVAL_ERROR, self.warning_label)
628 self.set_sensitive(True)
629
630
631@@ -865,11 +830,7 @@
632 gobject.TYPE_NONE, ()),
633 }
634
635- TITLE = _('The devices connected with your personal cloud are listed '
636- 'below.')
637- NO_DEVICES = _('No devices to show.')
638- CONFIRM_REMOVE = _('Are you sure you want to remove this device '
639- 'from Ubuntu One?')
640+ TITLE = DEVICES_TITLE
641
642 def __init__(self, main_window=None):
643 UbuntuOneBin.__init__(self)
644@@ -882,7 +843,7 @@
645 flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
646 type=gtk.MESSAGE_WARNING,
647 buttons=gtk.BUTTONS_YES_NO,
648- message_format=self.CONFIRM_REMOVE)
649+ message_format=DEVICE_CONFIRM_REMOVE)
650 self.confirm_remove_dialog = gtk.MessageDialog(**kw)
651
652 self.backend.connect_to_signal('DevicesInfoReady',
653@@ -899,7 +860,7 @@
654 self.devices.remove(child)
655
656 if not info:
657- self.on_success(self.NO_DEVICES)
658+ self.on_success(NO_DEVICES)
659 else:
660 self.on_success()
661
662@@ -949,12 +910,6 @@
663 'finished': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ()),
664 }
665
666- INSTALL_PACKAGE = _('You need to install the package <i>%(package_name)s'
667- '</i> in order to enable more sync services.')
668- INSTALLING = _('Installation of <i>%(package_name)s</i> in progress')
669- FAILED_INSTALL = _('<i>%(package_name)s</i> could not be installed')
670- SUCCESS_INSTALL = _('<i>%(package_name)s</i> was successfully installed')
671-
672 def __init__(self, package_name, message=None):
673 gtk.VBox.__init__(self)
674 ControlPanelMixin.__init__(self, filename='install.ui')
675@@ -969,7 +924,7 @@
676
677 self.message = message
678 if self.message is None:
679- self.message = self.INSTALL_PACKAGE % self.args
680+ self.message = INSTALL_PACKAGE % self.args
681 self.reset()
682
683 self.show()
684@@ -1007,13 +962,13 @@
685 self.itself.pack_start(self.progress_bar)
686
687 self.transaction.connect('finished', self.on_install_finished)
688- self.install_label.set_markup(self.INSTALLING % self.args)
689+ self.install_label.set_markup(INSTALLING % self.args)
690 yield self.transaction.run()
691 except package_manager.aptdaemon.errors.NotAuthorizedError:
692 self.reset()
693 except: # pylint: disable=W0702
694 logger.exception('on_install_button_clicked')
695- self._set_warning(self.FAILED_INSTALL % self.args,
696+ self._set_warning(FAILED_INSTALL % self.args,
697 self.install_label)
698 if self.progress_bar is not None:
699 self.progress_bar.hide()
700@@ -1029,19 +984,16 @@
701 if exit_code != package_manager.aptdaemon.enums.EXIT_SUCCESS:
702 if hasattr(transaction, 'error'):
703 logger.error('transaction failed: %r', transaction.error)
704- self._set_warning(self.FAILED_INSTALL % self.args,
705+ self._set_warning(FAILED_INSTALL % self.args,
706 self.install_label)
707 else:
708- self.install_label.set_markup(self.SUCCESS_INSTALL % self.args)
709+ self.install_label.set_markup(SUCCESS_INSTALL % self.args)
710 self.emit('finished')
711
712
713 class Service(gtk.VBox, ControlPanelMixin):
714 """A service."""
715
716- CHANGE_ERROR = _('The settings could not be changed,\n'
717- 'previous values were restored.')
718-
719 def __init__(self, service_id, name,
720 container=None, check_button=None, action_button=None,
721 *args, **kwargs):
722@@ -1064,11 +1016,9 @@
723 class FileSyncService(Service):
724 """The file sync service."""
725
726- FILES_SERVICE_NAME = _('File Sync')
727-
728 def __init__(self, container, check_button, action_button):
729 Service.__init__(self, service_id='file-sync',
730- name=self.FILES_SERVICE_NAME,
731+ name=FILE_SYNC_SERVICE_NAME,
732 container=container,
733 check_button=check_button,
734 action_button=action_button)
735@@ -1123,9 +1073,6 @@
736 class DesktopcouchService(Service):
737 """A desktopcouch service."""
738
739- INSTALL_PACKAGE = _('Install the %(plugin_name)s for the sync service: '
740- '%(service_name)s')
741-
742 def __init__(self, service_id, name, enabled,
743 container, check_button,
744 dependency=None, dependency_name=None):
745@@ -1144,7 +1091,7 @@
746 if dependency_name is None:
747 dependency_name = dependency
748 args = {'plugin_name': dependency_name, 'service_name': service_id}
749- message = self.INSTALL_PACKAGE % args
750+ message = INSTALL_PLUGIN % args
751 self.dependency = InstallPackage(dependency, message)
752 self.dependency.connect('finished', self.on_depedency_finished)
753
754@@ -1183,26 +1130,21 @@
755 if replication_id != self.id:
756 return
757 self.check_button.set_active(not self.check_button.get_active())
758- self._set_warning(self.CHANGE_ERROR, self.warning_label)
759+ self._set_warning(SETTINGS_CHANGE_ERROR, self.warning_label)
760
761
762 class ServicesPanel(UbuntuOneBin, ControlPanelMixin):
763 """The services panel."""
764
765- TITLE = _('Enable the sync services for this computer.')
766- DESKTOPCOUCH_PKG = 'desktopcouch-ubuntuone'
767- BOOKMARKS = _('Firefox extension')
768- CONTACTS = _('Evolution plug-in')
769- NO_PAIRING_RECORD = _('There is no Ubuntu One pairing record.')
770- CONTACTS_LINK = 'https://one.ubuntu.com/'
771+ TITLE = SERVICES_TITLE
772
773 def __init__(self, main_window=None):
774 UbuntuOneBin.__init__(self)
775 ControlPanelMixin.__init__(self, filename='services.ui')
776 self.add(self.itself)
777
778- self.plugin_names = {'contacts': self.CONTACTS,
779- 'bookmarks': self.BOOKMARKS}
780+ self.plugin_names = {'contacts': CONTACTS,
781+ 'bookmarks': BOOKMARKS}
782
783 self.package_manager = package_manager.PackageManager()
784 self.install_box = None
785@@ -1222,7 +1164,7 @@
786 @property
787 def has_desktopcouch(self):
788 """Is desktopcouch installed?"""
789- return self.package_manager.is_installed(self.DESKTOPCOUCH_PKG)
790+ return self.package_manager.is_installed(DESKTOPCOUCH_PKG)
791
792 def on_file_sync_button_clicked(self, *args, **kwargs):
793 """The "Show me my U1 folder" button was clicked.
794@@ -1239,7 +1181,7 @@
795 XXX: this should be part of the DesktopcouchService widget.
796
797 """
798- uri_hook(None, self.CONTACTS)
799+ uri_hook(None, CONTACTS)
800
801 def on_bookmarks_button_clicked(self, *args, **kwargs):
802 """The bookmarks button was clicked.
803@@ -1261,7 +1203,7 @@
804 if not self.has_desktopcouch:
805 self.message.set_text('')
806
807- self.install_box = InstallPackage(self.DESKTOPCOUCH_PKG)
808+ self.install_box = InstallPackage(DESKTOPCOUCH_PKG)
809 self.install_box.connect('finished', self.load_replications)
810 self.itself.pack_end(self.install_box, expand=False)
811 self.itself.reorder_child(self.install_box, 0)
812@@ -1311,7 +1253,7 @@
813 """The replication info can not be retrieved."""
814 if error_dict is not None and \
815 error_dict.get('error_type', None) == 'NoPairingRecord':
816- self.on_error(self.NO_PAIRING_RECORD)
817+ self.on_error(NO_PAIRING_RECORD)
818 else:
819 self.on_error(error_dict=error_dict)
820
821@@ -1325,30 +1267,6 @@
822 class FileSyncStatus(gtk.HBox, ControlPanelMixin):
823 """A file sync status widget."""
824
825- FILE_SYNC_DISABLED = _('File Sync is disabled.')
826- FILE_SYNC_STARTING = _('File Sync starting...')
827- FILE_SYNC_STOPPED = _('File Sync is stopped.')
828- FILE_SYNC_DISCONNECTED = _('File Sync is disconnected.')
829- FILE_SYNC_SYNCING = _('File Sync in progress...')
830- FILE_SYNC_IDLE = _('File Sync is up-to-date.')
831- FILE_SYNC_ERROR = _('File Sync error.')
832-
833- CONNECT = _('Connect')
834- DISCONNECT = _('Disconnect')
835- ENABLE = _('Enable')
836- RESTART = _('Restart')
837- START = _('Start')
838- STOP = _('Stop')
839-
840- CONNECT_TOOLTIP = _('Connect the file sync service '
841- 'with your personal cloud')
842- DISCONNECT_TOOLTIP = _('Disconnect the file sync service '
843- 'from your personal cloud')
844- ENABLE_TOOLTIP = _('Enable the file sync service')
845- RESTART_TOOLTIP = _('Restart the file sync service')
846- START_TOOLTIP = _('Start the file sync service')
847- STOP_TOOLTIP = _('Stop the file sync service')
848-
849 def __init__(self):
850 gtk.HBox.__init__(self)
851 ControlPanelMixin.__init__(self)
852@@ -1408,55 +1326,55 @@
853 @log_call(logger.info)
854 def on_file_sync_status_disabled(self, msg=None):
855 """Backend notifies of file sync status being disabled."""
856- self._update_status(self.FILE_SYNC_DISABLED,
857- self.ENABLE, self.on_enable_clicked,
858- '✘', 'red', self.ENABLE_TOOLTIP)
859+ self._update_status(FILE_SYNC_DISABLED,
860+ FILE_SYNC_ENABLE, self.on_enable_clicked,
861+ '✘', 'red', FILE_SYNC_ENABLE_TOOLTIP)
862
863 @log_call(logger.info)
864 def on_file_sync_status_starting(self, msg=None):
865 """Backend notifies of file sync status being starting."""
866- self._update_status(self.FILE_SYNC_STARTING,
867- self.STOP, self.on_stop_clicked,
868- '⇅', ORANGE, self.STOP_TOOLTIP)
869+ self._update_status(FILE_SYNC_STARTING,
870+ FILE_SYNC_STOP, self.on_stop_clicked,
871+ '⇅', ORANGE, FILE_SYNC_STOP_TOOLTIP)
872
873 @log_call(logger.info)
874 def on_file_sync_status_stopped(self, msg=None):
875 """Backend notifies of file sync being stopped."""
876- self._update_status(self.FILE_SYNC_STOPPED,
877- self.START, self.on_start_clicked,
878- '✘', 'red', self.START_TOOLTIP)
879+ self._update_status(FILE_SYNC_STOPPED,
880+ FILE_SYNC_START, self.on_start_clicked,
881+ '✘', 'red', FILE_SYNC_START_TOOLTIP)
882
883 @log_call(logger.info)
884 def on_file_sync_status_disconnected(self, msg=None):
885 """Backend notifies of file sync status being ready."""
886- self._update_status(self.FILE_SYNC_DISCONNECTED,
887- self.CONNECT, self.on_connect_clicked,
888- '✘', 'red', self.CONNECT_TOOLTIP,)
889+ self._update_status(FILE_SYNC_DISCONNECTED,
890+ FILE_SYNC_CONNECT, self.on_connect_clicked,
891+ '✘', 'red', FILE_SYNC_CONNECT_TOOLTIP,)
892
893 @log_call(logger.info)
894 def on_file_sync_status_syncing(self, msg=None):
895 """Backend notifies of file sync status being syncing."""
896- self._update_status(self.FILE_SYNC_SYNCING,
897- self.DISCONNECT, self.on_disconnect_clicked,
898- '⇅', ORANGE, self.DISCONNECT_TOOLTIP)
899+ self._update_status(FILE_SYNC_SYNCING,
900+ FILE_SYNC_DISCONNECT, self.on_disconnect_clicked,
901+ '⇅', ORANGE, FILE_SYNC_DISCONNECT_TOOLTIP)
902
903 @log_call(logger.info)
904 def on_file_sync_status_idle(self, msg=None):
905 """Backend notifies of file sync status being idle."""
906- self._update_status(self.FILE_SYNC_IDLE,
907- self.DISCONNECT, self.on_disconnect_clicked,
908- '✔', 'green', self.DISCONNECT_TOOLTIP)
909+ self._update_status(FILE_SYNC_IDLE,
910+ FILE_SYNC_DISCONNECT, self.on_disconnect_clicked,
911+ '✔', 'green', FILE_SYNC_DISCONNECT_TOOLTIP)
912
913 @log_call(logger.error)
914 def on_file_sync_status_error(self, error_dict=None):
915 """Backend notifies of an error when fetching file sync status."""
916- msg = self.FILE_SYNC_ERROR
917+ msg = FILE_SYNC_ERROR
918 reason = error_dict.get('error_msg', '') if error_dict else ''
919 if reason:
920 msg += ' (' + reason + ')'
921 self._update_status(WARNING_MARKUP % msg,
922- self.RESTART, self.on_restart_clicked,
923- tooltip=self.RESTART_TOOLTIP)
924+ FILE_SYNC_RESTART, self.on_restart_clicked,
925+ tooltip=FILE_SYNC_RESTART_TOOLTIP)
926
927 @log_call(logger.error)
928 def on_files_start_error(self, error_dict=None):
929@@ -1514,19 +1432,9 @@
930 'unauthorized': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ()),
931 }
932
933- QUOTA_LABEL = _('Using %(used)s of %(total)s (%(percentage).0f%%)')
934- QUOTA_THRESHOLD = 0.95
935 DASHBOARD_BUTTON_NAME = 'ModeLeft'
936 SERVICES_BUTTON_NAME = 'ModeRight'
937
938- DASHBOARD_BUTTON_TOOLTIP = _('View your personal details and service '
939- 'summary')
940- VOLUMES_BUTTON_TOOLTIP = _('Manage your cloud folders')
941- SHARES_BUTTON_TOOLTIP = _('Manage the shares offered to others')
942- DEVICES_BUTTON_TOOLTIP = _('Manage devices registered with your personal '
943- 'cloud')
944- SERVICES_BUTTON_TOOLTIP = _('Manage the sync services')
945-
946 def __init__(self, main_window=None):
947 gtk.VBox.__init__(self)
948 ControlPanelMixin.__init__(self, filename='management.ui')
949@@ -1565,20 +1473,20 @@
950 self.notebook.insert_page(getattr(self, tab), position=page_num)
951
952 self.dashboard_button.set_name(self.DASHBOARD_BUTTON_NAME)
953- self.dashboard_button.set_tooltip_text(self.DASHBOARD_BUTTON_TOOLTIP)
954+ self.dashboard_button.set_tooltip_text(DASHBOARD_BUTTON_TOOLTIP)
955
956- self.volumes_button.set_tooltip_text(self.VOLUMES_BUTTON_TOOLTIP)
957+ self.volumes_button.set_tooltip_text(FOLDERS_BUTTON_TOOLTIP)
958 self.volumes_button.connect('clicked', lambda b: self.volumes.load())
959
960- self.shares_button.set_tooltip_text(self.SHARES_BUTTON_TOOLTIP)
961+ self.shares_button.set_tooltip_text(SHARES_BUTTON_TOOLTIP)
962
963- self.devices_button.set_tooltip_text(self.DEVICES_BUTTON_TOOLTIP)
964+ self.devices_button.set_tooltip_text(DEVICES_BUTTON_TOOLTIP)
965 self.devices_button.connect('clicked', lambda b: self.devices.load())
966 self.devices.connect('local-device-removed',
967 lambda widget: self.emit('local-device-removed'))
968
969 self.services_button.set_name(self.SERVICES_BUTTON_NAME)
970- self.services_button.set_tooltip_text(self.SERVICES_BUTTON_TOOLTIP)
971+ self.services_button.set_tooltip_text(SERVICES_BUTTON_TOOLTIP)
972 self.services_button.connect('clicked',
973 lambda b: self.services.refresh())
974
975@@ -1598,7 +1506,7 @@
976 fraction = round(fraction, 2)
977
978 logger.debug('ManagementPanel: updating quota to %r.', fraction)
979- if fraction >= self.QUOTA_THRESHOLD:
980+ if fraction >= QUOTA_THRESHOLD:
981 self.quota_label.set_markup(WARNING_MARKUP % msg)
982 else:
983 self.quota_label.set_markup(msg)
984@@ -1625,7 +1533,7 @@
985 total = int(info['quota_total'])
986 data = {'used': self.humanize(used), 'total': self.humanize(total),
987 'percentage': (used / total) * 100}
988- self._update_quota(self.QUOTA_LABEL % data, data)
989+ self._update_quota(QUOTA_LABEL % data, data)
990
991 @log_call(logger.error)
992 def on_account_info_error(self, error_dict=None):
993@@ -1721,13 +1629,11 @@
994 class ControlPanelWindow(gtk.Window):
995 """The main window for the Ubuntu One control panel."""
996
997- TITLE = _('%(app_name)s Control Panel')
998-
999 def __init__(self, switch_to='', alert=False):
1000 super(ControlPanelWindow, self).__init__()
1001
1002 self.connect('focus-in-event', self.remove_urgency)
1003- self.set_title(self.TITLE % {'app_name': U1_APP_NAME})
1004+ self.set_title(MAIN_WINDOW_TITLE % {'app_name': U1_APP_NAME})
1005 self.set_position(gtk.WIN_POS_CENTER_ALWAYS)
1006 self.set_icon_name('ubuntuone')
1007 self.set_size_request(736, 525) # bug #683164
1008
1009=== modified file 'ubuntuone/controlpanel/gui/gtk/tests/__init__.py'
1010--- ubuntuone/controlpanel/gtk/tests/__init__.py 2011-05-19 17:57:56 +0000
1011+++ ubuntuone/controlpanel/gui/gtk/tests/__init__.py 2011-05-24 20:11:16 +0000
1012@@ -25,8 +25,8 @@
1013 from ubuntuone.devtools.handlers import MementoHandler
1014
1015 from ubuntuone.controlpanel.backend import ControlBackend
1016-from ubuntuone.controlpanel.gtk import gui
1017-from ubuntuone.controlpanel.gtk.tests.test_package_manager import (
1018+from ubuntuone.controlpanel.gui.gtk import gui
1019+from ubuntuone.controlpanel.gui.gtk.tests.test_package_manager import (
1020 FakedTransaction)
1021 from ubuntuone.controlpanel.tests import TestCase
1022
1023@@ -81,7 +81,7 @@
1024
1025 FAKE_VOLUMES_INFO = [
1026 (u'', u'147852369', [ROOT] + FAKE_FOLDERS_INFO),
1027- (u'Other User', gui.VolumesPanel.MIN_SIZE_FULL, FAKE_SHARES_INFO),
1028+ (u'Other User', gui.SHARES_MIN_SIZE_FULL, FAKE_SHARES_INFO),
1029 ]
1030
1031 FAKE_VOLUMES_NO_FREE_SPACE_INFO = [
1032@@ -91,7 +91,7 @@
1033 u'subscribed': u'', u'type': ControlBackend.SHARE_TYPE,
1034 u'display_name': u'something',
1035 }]),
1036- (u'Almost no free space', gui.VolumesPanel.MIN_SIZE_FULL - 1,
1037+ (u'Almost no free space', gui.SHARES_MIN_SIZE_FULL - 1,
1038 [{u'volume_id': u'1', u'name': u'almostfull', u'path': u'almost-full',
1039 u'subscribed': u'', u'type': ControlBackend.SHARE_TYPE,
1040 u'display_name': u'yadda',
1041
1042=== modified file 'ubuntuone/controlpanel/gui/gtk/tests/test_gui.py'
1043--- ubuntuone/controlpanel/gtk/tests/test_gui.py 2011-05-19 17:57:56 +0000
1044+++ ubuntuone/controlpanel/gui/gtk/tests/test_gui.py 2011-05-24 20:11:16 +0000
1045@@ -22,17 +22,17 @@
1046
1047 import operator
1048
1049-from ubuntuone.controlpanel.gtk import gui
1050-from ubuntuone.controlpanel.gtk.tests import (FAKE_ACCOUNT_INFO,
1051+from ubuntuone.controlpanel.gui.gtk import gui
1052+from ubuntuone.controlpanel.gui.gtk.tests import (FAKE_ACCOUNT_INFO,
1053 FAKE_DEVICE_INFO, FAKE_DEVICES_INFO, FAKE_FOLDERS_INFO,
1054 FAKE_VOLUMES_INFO, FAKE_VOLUMES_NO_FREE_SPACE_INFO, FAKE_REPLICATIONS_INFO,
1055 MUSIC_FOLDER, ROOT, USER_HOME,
1056 FakedConfirmDialog,
1057 )
1058-from ubuntuone.controlpanel.gtk.tests.test_gui_basic import (
1059+from ubuntuone.controlpanel.gui.gtk.tests.test_gui_basic import (
1060 ControlPanelMixinTestCase,
1061 )
1062-from ubuntuone.controlpanel.gtk.tests.test_package_manager import (
1063+from ubuntuone.controlpanel.gui.gtk.tests.test_package_manager import (
1064 SUCCESS, FAILURE)
1065
1066
1067@@ -177,7 +177,7 @@
1068 self.ui.on_volumes_info_ready([])
1069
1070 self.assertFalse(self.ui.message.active)
1071- self.assertEqual(self.ui.message.get_text(), self.ui.NO_VOLUMES)
1072+ self.assertEqual(self.ui.message.get_text(), gui.NO_FOLDERS)
1073
1074 def test_on_volumes_info_ready(self):
1075 """The volumes info is processed when ready."""
1076@@ -187,7 +187,7 @@
1077 len(self.ui.volumes_store))
1078 treeiter = self.ui.volumes_store.get_iter_root()
1079 for name, free_bytes, volumes in FAKE_VOLUMES_INFO:
1080- name = "%s's" % name if name else self.ui.MY_FOLDERS
1081+ name = "%s's" % name if name else gui.MY_FOLDERS
1082 free_bytes = self.ui.humanize(int(free_bytes))
1083 header = (name, self.ui.FREE_SPACE % {'free_space': free_bytes})
1084
1085@@ -219,7 +219,7 @@
1086 if volume['type'] == 'ROOT':
1087 sensitive = False
1088 path = self.ui.ROOT % (path, gui.ORANGE,
1089- self.ui.ALWAYS_SUBSCRIBED)
1090+ gui.ALWAYS_SUBSCRIBED)
1091 elif volume['type'] == 'SHARE':
1092 path = volume['name']
1093
1094@@ -268,7 +268,7 @@
1095
1096 treeiter = self.ui.volumes_store.get_iter_root()
1097 for name, free_bytes, volumes in FAKE_VOLUMES_NO_FREE_SPACE_INFO:
1098- name = "%s's" % name if name else self.ui.MY_FOLDERS
1099+ name = "%s's" % name if name else gui.MY_FOLDERS
1100 free_bytes = self.ui.humanize(int(free_bytes))
1101 free_bytes = self.ui.NO_FREE_SPACE % {'free_space': free_bytes}
1102
1103@@ -303,7 +303,7 @@
1104
1105 treeiter = self.ui.volumes_store.get_iter_root()
1106 for name, free_bytes, volumes in info:
1107- name = "%s's" % name if name else self.ui.MY_FOLDERS
1108+ name = "%s's" % name if name else gui.MY_FOLDERS
1109
1110 # check parent row
1111 row = self.ui.volumes_store.get(treeiter,
1112@@ -394,7 +394,7 @@
1113 row = self.ui.volumes_store.get(treeiter, *xrange(self.ui.MAX_COLS))
1114
1115 volume = MUSIC_FOLDER
1116- self.assertEqual(row[0], self.ui.MUSIC_DISPLAY_NAME)
1117+ self.assertEqual(row[0], gui.MUSIC_DISPLAY_NAME)
1118 self.assertEqual(row[1], bool(volume['subscribed']))
1119 self.assertEqual(row[2], self.ui.MUSIC_ICON_NAME)
1120 self.assertTrue(row[3], 'toggle should be shown on child!')
1121@@ -483,7 +483,7 @@
1122 path = FAKE_FOLDERS_INFO[-1]['path']
1123 self.assertTrue(self.ui.confirm_dialog.was_run, 'dialog was run')
1124 self.assertEqual(self.ui.confirm_dialog.markup,
1125- self.ui.CONFIRM_MERGE % {'folder_path': path})
1126+ gui.FOLDERS_CONFIRM_MERGE % {'folder_path': path})
1127 self.assertFalse(self.ui.confirm_dialog.is_visible, 'dialog was hid')
1128
1129 def test_subscribe_does_not_call_backend_if_dialog_closed(self):
1130@@ -537,7 +537,8 @@
1131 """Assert that the device has the values from expected."""
1132 self.assertEqual(device.id,
1133 expected['device_id'])
1134- value = expected['device_name'].replace(self.ui.REMOVABLE_PREFIX, '')
1135+ value = expected['device_name'].replace(gui.DEVICE_REMOVABLE_PREFIX,
1136+ '')
1137 self.assertEqual(device.device_name.get_text(), value)
1138 self.assertEqual(device.device_type.get_icon_name()[0],
1139 expected['device_type'].lower())
1140@@ -625,13 +626,13 @@
1141 def test_update_device_name(self):
1142 """A device can be updated from a dict."""
1143 value = 'The death star'
1144- self.ui.update(device_name=self.ui.REMOVABLE_PREFIX + value)
1145+ self.ui.update(device_name=gui.DEVICE_REMOVABLE_PREFIX + value)
1146 self.assertEqual(value, self.ui.device_name.get_text())
1147
1148 def test_update_unicode_device_name(self):
1149 """A device can be updated from a dict."""
1150 value = u'Ñoño Ñandú'
1151- self.ui.update(device_name=self.ui.REMOVABLE_PREFIX + value)
1152+ self.ui.update(device_name=gui.DEVICE_REMOVABLE_PREFIX + value)
1153 self.assertEqual(value, self.ui.device_name.get_text())
1154
1155 def test_update_device_type_computer(self):
1156@@ -778,7 +779,7 @@
1157
1158 self.assertTrue(self.ui.get_sensitive())
1159 self.assert_warning_correct(self.ui.warning_label,
1160- self.ui.DEVICE_CHANGE_ERROR)
1161+ gui.DEVICE_CHANGE_ERROR)
1162 self.assert_device_equal(self.ui, FAKE_DEVICE_INFO) # restored info
1163
1164 def test_on_device_settings_change_error_after_success(self):
1165@@ -827,7 +828,7 @@
1166 self.assertTrue(self.ui.get_sensitive(),
1167 'Must be enabled after removal error.')
1168 self.assert_warning_correct(self.ui.warning_label,
1169- self.ui.DEVICE_REMOVAL_ERROR)
1170+ gui.DEVICE_REMOVAL_ERROR)
1171
1172 def test_on_device_removal_error_other_id(self):
1173 """On other device removal error, do nothing."""
1174@@ -911,7 +912,7 @@
1175 kwargs = dict(parent=self.kwargs['main_window'],
1176 flags=flags, type=gui.gtk.MESSAGE_WARNING,
1177 buttons=gui.gtk.BUTTONS_YES_NO,
1178- message_format=self.ui.CONFIRM_REMOVE)
1179+ message_format=gui.DEVICE_CONFIRM_REMOVE)
1180 self.assertEqual(dialog._kwargs, kwargs)
1181
1182 def test_backend_signals(self):
1183@@ -954,7 +955,7 @@
1184 """When there are no devices, a notification is shown."""
1185 self.ui.on_devices_info_ready([])
1186
1187- self.assertEqual(self.ui.message.get_text(), self.ui.NO_DEVICES)
1188+ self.assertEqual(self.ui.message.get_text(), gui.NO_DEVICES)
1189
1190 def test_on_devices_info_ready(self):
1191 """The devices info is processed when ready."""
1192@@ -967,7 +968,8 @@
1193 self.assertIsInstance(child, gui.Device)
1194
1195 self.assertEqual(device['device_id'], child.id)
1196- value = device['device_name'].replace(child.REMOVABLE_PREFIX, '')
1197+ value = device['device_name'].replace(gui.DEVICE_REMOVABLE_PREFIX,
1198+ '')
1199 self.assertEqual(value, child.device_name.get_text())
1200 self.assertEqual(device['device_type'].lower(),
1201 child.device_type.get_icon_name()[0])
1202@@ -1099,7 +1101,7 @@
1203
1204 def test_install_label(self):
1205 """The install label is correct."""
1206- msg = self.ui.INSTALL_PACKAGE % self.kwargs
1207+ msg = gui.INSTALL_PACKAGE % self.kwargs
1208 self.assertEqual(self.ui.install_label.get_label(), msg)
1209
1210 @gui.package_manager.inline_callbacks
1211@@ -1121,7 +1123,7 @@
1212 children = self.ui.itself.get_children()
1213 self.assertEqual(len(children), 2)
1214 self.assertEqual(self.ui.install_label, children[0])
1215- msg = self.ui.INSTALLING % self.kwargs
1216+ msg = gui.INSTALLING % self.kwargs
1217 self.assertEqual(self.ui.install_label.get_label(), msg)
1218
1219 @gui.package_manager.inline_callbacks
1220@@ -1130,7 +1132,7 @@
1221 self.patch(self.ui.package_manager, 'install', lambda name: SUCCESS)
1222 yield self.ui.install_button.clicked()
1223
1224- msg = self.ui.SUCCESS_INSTALL % self.kwargs
1225+ msg = gui.SUCCESS_INSTALL % self.kwargs
1226 self.assertEqual(self.ui.install_label.get_label(), msg)
1227
1228 @gui.package_manager.inline_callbacks
1229@@ -1155,7 +1157,7 @@
1230 self.patch(self.ui.package_manager, 'install', fail)
1231 yield self.ui.install_button.clicked()
1232
1233- msg = self.ui.FAILED_INSTALL % self.kwargs
1234+ msg = gui.FAILED_INSTALL % self.kwargs
1235 self.assert_warning_correct(self.ui.install_label, msg)
1236
1237 @gui.package_manager.inline_callbacks
1238@@ -1166,7 +1168,7 @@
1239 self.ui.on_install_finished(object(), SUCCESS)
1240
1241 self.assertFalse(self.ui.progress_bar.get_sensitive())
1242- msg = self.ui.SUCCESS_INSTALL % self.kwargs
1243+ msg = gui.SUCCESS_INSTALL % self.kwargs
1244 self.assertEqual(self.ui.install_label.get_label(), msg)
1245 self.assertEqual(self._called, ((self.ui,), {}))
1246
1247@@ -1177,7 +1179,7 @@
1248 self.ui.on_install_finished(object(), FAILURE)
1249
1250 self.assertFalse(self.ui.progress_bar.get_sensitive())
1251- msg = self.ui.FAILED_INSTALL % self.kwargs
1252+ msg = gui.FAILED_INSTALL % self.kwargs
1253 self.assert_warning_correct(self.ui.install_label, msg)
1254
1255
1256@@ -1224,7 +1226,7 @@
1257
1258 klass = gui.FileSyncService
1259 service_id = 'file-sync'
1260- name = gui.FileSyncService.FILES_SERVICE_NAME
1261+ name = gui.FILE_SYNC_SERVICE_NAME
1262 kwargs = {'container': None, 'check_button': None, 'action_button': None}
1263
1264 def test_backend_account_signals(self):
1265@@ -1362,7 +1364,7 @@
1266 self.ui.on_replication_settings_changed(replication_id='yadda')
1267
1268 self.assert_warning_correct(self.ui.warning_label,
1269- self.ui.CHANGE_ERROR)
1270+ gui.SETTINGS_CHANGE_ERROR)
1271
1272 def test_on_replication_settings_change_error(self):
1273 """When settings were not changed, notify the user.
1274@@ -1375,7 +1377,7 @@
1275 self.ui.on_replication_settings_change_error(replication_id=self.ui.id)
1276
1277 self.assert_warning_correct(self.ui.warning_label,
1278- self.ui.CHANGE_ERROR)
1279+ gui.SETTINGS_CHANGE_ERROR)
1280 self.assertEqual(old_val, self.ui.button.get_active())
1281
1282 def test_on_replication_settings_change_error_after_success(self):
1283@@ -1519,7 +1521,7 @@
1284 self.assertTrue(self.ui.install_box.get_visible())
1285 self.assertIn(self.ui.install_box, self.ui.itself.get_children())
1286 self.assertEqual(self.ui.install_box.package_name,
1287- self.ui.DESKTOPCOUCH_PKG)
1288+ gui.DESKTOPCOUCH_PKG)
1289
1290 def test_install_box_finished_connected(self):
1291 """The install box 'finished' signal is connected."""
1292@@ -1549,7 +1551,7 @@
1293 def test_message(self):
1294 """Global load message is stopped and proper test is shown."""
1295 self.assertFalse(self.ui.message.active)
1296- self.assertEqual(self.ui.message.get_text(), self.ui.CHOOSE_SERVICES)
1297+ self.assertEqual(self.ui.message.get_text(), '')
1298
1299 def test_has_desktopcouch(self):
1300 """Has desktopcouch installed?"""
1301@@ -1572,7 +1574,7 @@
1302 def test_replications_with_dependencies_not_installed(self):
1303 """Has proper child for each desktopcouch replication available."""
1304 self.ui.package_manager.is_installed = \
1305- lambda name: True if name == self.ui.DESKTOPCOUCH_PKG else False
1306+ lambda name: True if name == gui.DESKTOPCOUCH_PKG else False
1307 self.ui.on_replications_info_ready(info=FAKE_REPLICATIONS_INFO)
1308
1309 children = self.ui.replications.get_children()
1310@@ -1620,7 +1622,7 @@
1311
1312 def setUp(self):
1313 super(ServicesWithDesktopcouchErrorTestCase, self).setUp()
1314- self.ui.package_manager._installed[self.ui.DESKTOPCOUCH_PKG] = True
1315+ self.ui.package_manager._installed[gui.DESKTOPCOUCH_PKG] = True
1316
1317 def test_no_pairing_record(self):
1318 """The pairing record is not in place."""
1319@@ -1629,7 +1631,7 @@
1320
1321 self.assertEqual(self.ui.replications.get_children(), [])
1322 self.assertFalse(self.ui.message.active)
1323- self.assert_warning_correct(self.ui.message, self.ui.NO_PAIRING_RECORD)
1324+ self.assert_warning_correct(self.ui.message, gui.NO_PAIRING_RECORD)
1325
1326 def test_other_error(self):
1327 """There was an error other than no pairing record."""
1328@@ -1754,9 +1756,9 @@
1329 self.patch(self.ui, 'on_enable_clicked', self._set_called)
1330 self.ui.on_file_sync_status_disabled('msg')
1331
1332- self.assert_status_correct(self.ui.FILE_SYNC_DISABLED,
1333- action=self.ui.ENABLE,
1334- tooltip=self.ui.ENABLE_TOOLTIP)
1335+ self.assert_status_correct(gui.FILE_SYNC_DISABLED,
1336+ action=gui.FILE_SYNC_ENABLE,
1337+ tooltip=gui.FILE_SYNC_ENABLE_TOOLTIP)
1338
1339 def test_on_file_sync_status_starting(self):
1340 """The file sync status is starting.
1341@@ -1768,9 +1770,9 @@
1342 self.patch(self.ui, 'on_stop_clicked', self._set_called)
1343 self.ui.on_file_sync_status_starting('msg')
1344
1345- self.assert_status_correct(self.ui.FILE_SYNC_STARTING,
1346- action=self.ui.STOP,
1347- tooltip=self.ui.STOP_TOOLTIP)
1348+ self.assert_status_correct(gui.FILE_SYNC_STARTING,
1349+ action=gui.FILE_SYNC_STOP,
1350+ tooltip=gui.FILE_SYNC_STOP_TOOLTIP)
1351
1352 def test_on_file_sync_status_stopped(self):
1353 """The file sync is stopped.
1354@@ -1782,9 +1784,9 @@
1355 self.patch(self.ui, 'on_start_clicked', self._set_called)
1356 self.ui.on_file_sync_status_stopped('msg')
1357
1358- self.assert_status_correct(self.ui.FILE_SYNC_STOPPED,
1359- action=self.ui.START,
1360- tooltip=self.ui.START_TOOLTIP)
1361+ self.assert_status_correct(gui.FILE_SYNC_STOPPED,
1362+ action=gui.FILE_SYNC_START,
1363+ tooltip=gui.FILE_SYNC_START_TOOLTIP)
1364
1365 def test_on_file_sync_status_disconnected(self):
1366 """The file sync status is disconnected.
1367@@ -1796,9 +1798,9 @@
1368 self.patch(self.ui, 'on_connect_clicked', self._set_called)
1369 self.ui.on_file_sync_status_disconnected('msg')
1370
1371- self.assert_status_correct(self.ui.FILE_SYNC_DISCONNECTED,
1372- action=self.ui.CONNECT,
1373- tooltip=self.ui.CONNECT_TOOLTIP)
1374+ self.assert_status_correct(gui.FILE_SYNC_DISCONNECTED,
1375+ action=gui.FILE_SYNC_CONNECT,
1376+ tooltip=gui.FILE_SYNC_CONNECT_TOOLTIP)
1377
1378 def test_on_file_sync_status_syncing(self):
1379 """The file sync status is syncing.
1380@@ -1810,9 +1812,9 @@
1381 self.patch(self.ui, 'on_disconnect_clicked', self._set_called)
1382 self.ui.on_file_sync_status_syncing('msg')
1383
1384- self.assert_status_correct(self.ui.FILE_SYNC_SYNCING,
1385- action=self.ui.DISCONNECT,
1386- tooltip=self.ui.DISCONNECT_TOOLTIP)
1387+ self.assert_status_correct(gui.FILE_SYNC_SYNCING,
1388+ action=gui.FILE_SYNC_DISCONNECT,
1389+ tooltip=gui.FILE_SYNC_DISCONNECT_TOOLTIP)
1390
1391 def test_on_file_sync_status_idle(self):
1392 """The file sync status is idle.
1393@@ -1824,9 +1826,9 @@
1394 self.patch(self.ui, 'on_disconnect_clicked', self._set_called)
1395 self.ui.on_file_sync_status_idle('msg')
1396
1397- self.assert_status_correct(self.ui.FILE_SYNC_IDLE,
1398- action=self.ui.DISCONNECT,
1399- tooltip=self.ui.DISCONNECT_TOOLTIP)
1400+ self.assert_status_correct(gui.FILE_SYNC_IDLE,
1401+ action=gui.FILE_SYNC_DISCONNECT,
1402+ tooltip=gui.FILE_SYNC_DISCONNECT_TOOLTIP)
1403
1404 def test_on_file_sync_status_error_with_error_msg(self):
1405 """The file sync status couldn't be retrieved."""
1406@@ -1834,20 +1836,20 @@
1407 msg = 'error message'
1408 self.ui.on_file_sync_status_error({'error_msg': msg})
1409
1410- msg = gui.WARNING_MARKUP % (self.ui.FILE_SYNC_ERROR + ' (' + msg + ')')
1411+ msg = gui.WARNING_MARKUP % (gui.FILE_SYNC_ERROR + ' (' + msg + ')')
1412 self.assert_status_correct(msg,
1413- action=self.ui.RESTART,
1414- tooltip=self.ui.RESTART_TOOLTIP)
1415+ action=gui.FILE_SYNC_RESTART,
1416+ tooltip=gui.FILE_SYNC_RESTART_TOOLTIP)
1417
1418 def test_on_file_sync_status_error_without_error_msg(self):
1419 """The file sync status couldn't be retrieved."""
1420 self.patch(self.ui, 'on_restart_clicked', self._set_called)
1421 self.ui.on_file_sync_status_error()
1422
1423- msg = gui.WARNING_MARKUP % self.ui.FILE_SYNC_ERROR
1424+ msg = gui.WARNING_MARKUP % gui.FILE_SYNC_ERROR
1425 self.assert_status_correct(msg,
1426- action=self.ui.RESTART,
1427- tooltip=self.ui.RESTART_TOOLTIP)
1428+ action=gui.FILE_SYNC_RESTART,
1429+ tooltip=gui.FILE_SYNC_RESTART_TOOLTIP)
1430
1431 def test_on_files_start_error(self):
1432 """The files service could not be started."""
1433@@ -1907,10 +1909,10 @@
1434 expected = {'used': self.ui.humanize(used),
1435 'total': self.ui.humanize(total),
1436 'percentage': percentage}
1437- msg = self.ui.QUOTA_LABEL % expected
1438+ msg = gui.QUOTA_LABEL % expected
1439 self.assertEqual(self.ui.quota_label.get_text(), msg)
1440
1441- if percentage >= self.ui.QUOTA_THRESHOLD * 100:
1442+ if percentage >= gui.QUOTA_THRESHOLD * 100:
1443 self.assert_warning_correct(self.ui.quota_label, msg)
1444
1445 if progressbar_fraction is None:
1446@@ -2091,7 +2093,7 @@
1447
1448 info['quota_total'] = '12345678'
1449 info['quota_used'] = str(int(int(info['quota_total']) *
1450- self.ui.QUOTA_THRESHOLD))
1451+ gui.QUOTA_THRESHOLD))
1452 self.ui.on_account_info_ready(info)
1453
1454 self.assert_account_info_correct(info)
1455@@ -2150,7 +2152,7 @@
1456 '%s_button should have a tooltip set' % tab)
1457
1458 actual = getattr(self.ui, '%s_button' % tab).get_tooltip_text()
1459- expected = getattr(self.ui, '%s_BUTTON_TOOLTIP' % tab.upper())
1460+ expected = getattr(gui, '%s_BUTTON_TOOLTIP' % tab.upper())
1461 self.assertEqual(actual, expected)
1462
1463 def test_on_unauthorized_error(self):
1464
1465=== modified file 'ubuntuone/controlpanel/gui/gtk/tests/test_gui_basic.py'
1466--- ubuntuone/controlpanel/gtk/tests/test_gui_basic.py 2011-05-06 14:28:15 +0000
1467+++ ubuntuone/controlpanel/gui/gtk/tests/test_gui_basic.py 2011-05-24 20:11:16 +0000
1468@@ -21,8 +21,8 @@
1469 from __future__ import division
1470
1471
1472-from ubuntuone.controlpanel.gtk import gui
1473-from ubuntuone.controlpanel.gtk.tests import BaseTestCase, FakedSSOBackend
1474+from ubuntuone.controlpanel.gui.gtk import gui
1475+from ubuntuone.controlpanel.gui.gtk.tests import BaseTestCase, FakedSSOBackend
1476 from ubuntuone.controlpanel.tests import TOKEN
1477
1478 from ubuntuone.devtools.testcase import skipIf
1479@@ -119,7 +119,7 @@
1480
1481 def test_title_is_correct(self):
1482 """The window title is correct."""
1483- expected = self.ui.TITLE % {'app_name': gui.U1_APP_NAME}
1484+ expected = gui.MAIN_WINDOW_TITLE % {'app_name': gui.U1_APP_NAME}
1485 self.assertEqual(self.ui.get_title(), expected)
1486
1487 def test_control_panel_is_the_only_child(self):
1488@@ -491,7 +491,7 @@
1489 def test_state_offline(self):
1490 """Network connection is offline."""
1491 self.ui.on_network_state_changed(gui.networkstate.OFFLINE)
1492- msg = self.ui.NETWORK_OFFLINE % {'app_name': gui.U1_APP_NAME}
1493+ msg = gui.NETWORK_OFFLINE % {'app_name': gui.U1_APP_NAME}
1494
1495 self.assert_warning_correct(self.ui.warning_label, msg)
1496 self.assertFalse(self.ui.get_sensitive())
1497@@ -550,7 +550,7 @@
1498 self.ui.on_credentials_error(gui.U1_APP_NAME, {})
1499 self.assertTrue(self.ui.get_visible())
1500 self.assert_warning_correct(self.ui.warning_label,
1501- self.ui.CREDENTIALS_ERROR)
1502+ gui.CREDENTIALS_ERROR)
1503
1504 def test_on_authorization_denied(self):
1505 """Callback 'on_authorization_denied' is correct."""
1506@@ -682,7 +682,7 @@
1507 self.patch(gui, 'uri_hook', self._set_called)
1508 self.ui.learn_more_button.clicked()
1509
1510- expected = (self.ui.learn_more_button, self.ui.LEARN_MORE_LINK)
1511+ expected = (self.ui.learn_more_button, gui.LEARN_MORE_LINK)
1512 self.assertEqual(self._called, (expected, {}))
1513
1514 def test_on_credentials_not_found_unset_greyed(self):
1515
1516=== modified file 'ubuntuone/controlpanel/gui/gtk/tests/test_package_manager.py'
1517--- ubuntuone/controlpanel/gtk/tests/test_package_manager.py 2011-04-05 18:04:56 +0000
1518+++ ubuntuone/controlpanel/gui/gtk/tests/test_package_manager.py 2011-05-24 20:11:16 +0000
1519@@ -27,7 +27,7 @@
1520 # Unable to import 'defer', pylint: disable=F0401,E0611,W0404
1521 import defer
1522
1523-from ubuntuone.controlpanel.gtk import package_manager
1524+from ubuntuone.controlpanel.gui.gtk import package_manager
1525 from ubuntuone.controlpanel.tests import TestCase
1526
1527
1528
1529=== modified file 'ubuntuone/controlpanel/gui/gtk/tests/test_widgets.py'
1530--- ubuntuone/controlpanel/gtk/tests/test_widgets.py 2011-04-11 17:38:47 +0000
1531+++ ubuntuone/controlpanel/gui/gtk/tests/test_widgets.py 2011-05-24 20:11:16 +0000
1532@@ -19,7 +19,7 @@
1533 """The test suite for the extra widgets."""
1534
1535 from ubuntuone.controlpanel.tests import TestCase
1536-from ubuntuone.controlpanel.gtk import widgets
1537+from ubuntuone.controlpanel.gui.gtk import widgets
1538
1539
1540 class LoadingTestCase(TestCase):
1541
1542=== renamed directory 'ubuntuone/controlpanel/qt' => 'ubuntuone/controlpanel/gui/qt'
1543=== modified file 'ubuntuone/controlpanel/gui/qt/__init__.py'
1544--- ubuntuone/controlpanel/qt/__init__.py 2011-05-20 18:22:24 +0000
1545+++ ubuntuone/controlpanel/gui/qt/__init__.py 2011-05-24 20:11:16 +0000
1546@@ -18,4 +18,7 @@
1547
1548 """The Qt graphical interface for the control panel for Ubuntu One."""
1549
1550-TRANSLATION_DOMAIN = 'ubuntuone-control-panel'
1551+# Unused import main
1552+# pylint: disable=W0611
1553+
1554+from ubuntuone.controlpanel.gui.qt.gui import main
1555
1556=== modified file 'ubuntuone/controlpanel/gui/qt/controlpanel.py'
1557--- ubuntuone/controlpanel/qt/controlpanel.py 2011-05-20 17:15:39 +0000
1558+++ ubuntuone/controlpanel/gui/qt/controlpanel.py 2011-05-24 20:11:16 +0000
1559@@ -18,16 +18,65 @@
1560
1561 """The user interface for the control panel for Ubuntu One."""
1562
1563-from PyQt4 import QtGui
1564-
1565-from ubuntuone.controlpanel.qt.ui import controlpanel_ui
1566+from PyQt4 import QtGui, QtCore
1567+
1568+from ubuntuone.controlpanel import backend
1569+from ubuntuone.controlpanel.logger import setup_logging, log_call
1570+# Wildcard import ubuntuone.controlpanel.gui
1571+# pylint: disable=W0401, W0614
1572+from ubuntuone.controlpanel.gui import *
1573+# pylint: enable=W0401, W0614
1574+from ubuntuone.controlpanel.gui.qt.ui import controlpanel_ui
1575+
1576+
1577+logger = setup_logging('qt.controlpanel')
1578+
1579+
1580+FILE_SYNC_STATUS = {
1581+ backend.FILE_SYNC_DISCONNECTED: FILE_SYNC_DISCONNECTED,
1582+ backend.FILE_SYNC_DISABLED: FILE_SYNC_DISABLED,
1583+ backend.FILE_SYNC_ERROR: FILE_SYNC_ERROR,
1584+ backend.FILE_SYNC_IDLE: FILE_SYNC_IDLE,
1585+ backend.FILE_SYNC_STARTING: FILE_SYNC_STARTING,
1586+ backend.FILE_SYNC_STOPPED: FILE_SYNC_STOPPED,
1587+ backend.FILE_SYNC_SYNCING: FILE_SYNC_SYNCING,
1588+}
1589+
1590+STATUS_MARKUP = u'<b>⭐</b> %s'
1591
1592
1593 class ControlPanel(QtGui.QWidget):
1594 """The Control Panel widget"""
1595
1596- def __init__(self, parent):
1597+ def __init__(self, parent=None):
1598 """Initialize the UI of the widget."""
1599 QtGui.QWidget.__init__(self, parent)
1600 self.ui = controlpanel_ui.Ui_Form()
1601 self.ui.setupUi(self)
1602+
1603+ self.backend = backend.ControlBackend()
1604+ self.backend.status_changed_handler = self.process_status
1605+
1606+ # this call is crashing with MemoryError as per
1607+ # http://pastebin.ubuntu.com/612270/
1608+ #self.backend.file_sync_status()
1609+
1610+ logger.debug('%s: started.', self.__class__.__name__)
1611+
1612+ @log_call(logger.debug)
1613+ def process_status(self, status):
1614+ """Match status with signals."""
1615+ logger.debug('process_status: new status received %r', status)
1616+
1617+ try:
1618+ status = FILE_SYNC_STATUS[status[backend.STATUS_KEY]]
1619+ except KeyError:
1620+ logger.exception('process_status: received unknown status dict %r',
1621+ status)
1622+ else:
1623+ msg = STATUS_MARKUP % (status,)
1624+ self.ui.sync_status_label.setText(msg)
1625+
1626+ @QtCore.pyqtSlot()
1627+ def on_change_sync_status_button_clicked(self, *a, **kw):
1628+ """The change sync status button was clicked."""
1629
1630=== modified file 'ubuntuone/controlpanel/gui/qt/devices.py'
1631--- ubuntuone/controlpanel/qt/devices.py 2011-05-20 23:37:46 +0000
1632+++ ubuntuone/controlpanel/gui/qt/devices.py 2011-05-24 20:11:16 +0000
1633@@ -20,7 +20,7 @@
1634
1635 from PyQt4 import QtGui
1636
1637-from ubuntuone.controlpanel.qt.ui import devices_ui
1638+from ubuntuone.controlpanel.gui.qt.ui import devices_ui
1639
1640
1641 class DevicesPanel(QtGui.QWidget):
1642
1643=== modified file 'ubuntuone/controlpanel/gui/qt/folders.py'
1644--- ubuntuone/controlpanel/qt/folders.py 2011-05-20 23:36:37 +0000
1645+++ ubuntuone/controlpanel/gui/qt/folders.py 2011-05-24 20:11:16 +0000
1646@@ -20,7 +20,7 @@
1647
1648 from PyQt4 import QtGui
1649
1650-from ubuntuone.controlpanel.qt.ui import folders_ui
1651+from ubuntuone.controlpanel.gui.qt.ui import folders_ui
1652
1653
1654 class FoldersPanel(QtGui.QWidget):
1655
1656=== modified file 'ubuntuone/controlpanel/gui/qt/gui.py'
1657--- ubuntuone/controlpanel/qt/gui.py 2011-05-23 18:36:26 +0000
1658+++ ubuntuone/controlpanel/gui/qt/gui.py 2011-05-24 20:11:16 +0000
1659@@ -23,7 +23,11 @@
1660 from dbus.mainloop.qt import DBusQtMainLoop
1661 from PyQt4 import Qt, QtGui
1662
1663-from ubuntuone.controlpanel.qt.ui import mainwindow_ui
1664+from ubuntuone.controlpanel.logger import setup_logging
1665+from ubuntuone.controlpanel.gui.qt.ui import mainwindow_ui
1666+
1667+
1668+logger = setup_logging('qt.gui')
1669
1670
1671 class MainWindow(QtGui.QMainWindow):
1672
1673=== modified file 'ubuntuone/controlpanel/gui/qt/preferences.py'
1674--- ubuntuone/controlpanel/qt/preferences.py 2011-05-20 23:37:46 +0000
1675+++ ubuntuone/controlpanel/gui/qt/preferences.py 2011-05-24 20:11:16 +0000
1676@@ -20,7 +20,7 @@
1677
1678 from PyQt4 import QtGui
1679
1680-from ubuntuone.controlpanel.qt.ui import preferences_ui
1681+from ubuntuone.controlpanel.gui.qt.ui import preferences_ui
1682
1683
1684 class PreferencesPanel(QtGui.QWidget):
1685
1686=== modified file 'ubuntuone/controlpanel/gui/qt/profile.py'
1687--- ubuntuone/controlpanel/qt/profile.py 2011-05-20 23:37:46 +0000
1688+++ ubuntuone/controlpanel/gui/qt/profile.py 2011-05-24 20:11:16 +0000
1689@@ -20,7 +20,7 @@
1690
1691 from PyQt4 import QtGui
1692
1693-from ubuntuone.controlpanel.qt.ui import profile_ui
1694+from ubuntuone.controlpanel.gui.qt.ui import profile_ui
1695
1696
1697 class ProfilePanel(QtGui.QWidget):
1698
1699=== modified file 'ubuntuone/controlpanel/gui/qt/services.py'
1700--- ubuntuone/controlpanel/qt/services.py 2011-05-20 23:37:46 +0000
1701+++ ubuntuone/controlpanel/gui/qt/services.py 2011-05-24 20:11:16 +0000
1702@@ -20,7 +20,7 @@
1703
1704 from PyQt4 import QtGui
1705
1706-from ubuntuone.controlpanel.qt.ui import services_ui
1707+from ubuntuone.controlpanel.gui.qt.ui import services_ui
1708
1709
1710 class ServicesPanel(QtGui.QWidget):
1711
1712=== modified file 'ubuntuone/controlpanel/gui/qt/tests/__init__.py'
1713--- ubuntuone/controlpanel/qt/tests/__init__.py 2011-05-19 14:55:39 +0000
1714+++ ubuntuone/controlpanel/gui/qt/tests/__init__.py 2011-05-24 20:11:16 +0000
1715@@ -17,3 +17,61 @@
1716 # with this program. If not, see <http://www.gnu.org/licenses/>.
1717
1718 """The test suite for the Qt UI for the control panel for Ubuntu One."""
1719+
1720+from ubuntuone.controlpanel.tests import TestCase
1721+
1722+
1723+def skip_if_abstract_class(test):
1724+ """Decorator to skip a test if is an abstract class."""
1725+
1726+ def inner(instance):
1727+ """Skip a test if is an abstract class."""
1728+ abstract = any(i is None for i in (instance.innerclass_ui,
1729+ instance.innerclass_name,
1730+ instance.class_ui))
1731+ result = None
1732+ if not abstract:
1733+ result = test(instance)
1734+
1735+ return result
1736+
1737+ return inner
1738+
1739+
1740+class BaseTestCase(TestCase):
1741+ """Base Test Case."""
1742+
1743+ innerclass_ui = None
1744+ innerclass_name = None
1745+ class_ui = None
1746+ kwargs = {}
1747+
1748+ @skip_if_abstract_class
1749+ def setUp(self):
1750+ super(BaseTestCase, self).setUp()
1751+ # self.class_ui is not callable
1752+ # pylint: disable=E1102
1753+ self.ui = self.class_ui(**self.kwargs)
1754+
1755+ @skip_if_abstract_class
1756+ def test_init_loads_ui(self):
1757+ """The __init__ method loads the ui."""
1758+ self.patch(self.innerclass_ui, self.innerclass_name, FakeUi)
1759+ # pylint: disable=E1102
1760+ self.ui = self.class_ui(**self.kwargs)
1761+ # pylint: disable=E1101
1762+ self.assertEqual(self.ui.ui.called,
1763+ ((self.ui,), {}), 'setupUi called.')
1764+
1765+
1766+class FakeUi(object):
1767+ """A fake Ui object."""
1768+
1769+ def __init__(self):
1770+ """Initialize this fake instance."""
1771+ self.called = None
1772+
1773+ # pylint: disable=C0103
1774+ def setupUi(self, *args, **kwargs):
1775+ """Fake setupUi."""
1776+ self.called = (args, kwargs)
1777
1778=== added file 'ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py'
1779--- ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 1970-01-01 00:00:00 +0000
1780+++ ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 2011-05-24 20:11:16 +0000
1781@@ -0,0 +1,77 @@
1782+# -*- coding: utf-8 -*-
1783+
1784+# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
1785+#
1786+# Copyright 2011 Canonical Ltd.
1787+#
1788+# This program is free software: you can redistribute it and/or modify it
1789+# under the terms of the GNU General Public License version 3, as published
1790+# by the Free Software Foundation.
1791+#
1792+# This program is distributed in the hope that it will be useful, but
1793+# WITHOUT ANY WARRANTY; without even the implied warranties of
1794+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1795+# PURPOSE. See the GNU General Public License for more details.
1796+#
1797+# You should have received a copy of the GNU General Public License along
1798+# with this program. If not, see <http://www.gnu.org/licenses/>.
1799+
1800+"""Tests for the Control Panel."""
1801+
1802+from ubuntuone.controlpanel.gui.qt import controlpanel as gui
1803+from ubuntuone.controlpanel.gui.qt.tests import BaseTestCase
1804+
1805+
1806+class ControlPanelTestCase(BaseTestCase):
1807+ """Test the qt control panel."""
1808+
1809+ innerclass_ui = gui.controlpanel_ui
1810+ innerclass_name = "Ui_Form"
1811+ class_ui = gui.ControlPanel
1812+
1813+ def test_backend(self):
1814+ """Backend is created."""
1815+ self.assertIsInstance(self.ui.backend,
1816+ gui.backend.ControlBackend)
1817+
1818+ def test_process_status_changed(self):
1819+ """Backend's file sync status changed callback is connected."""
1820+ self.assertEqual(self.ui.backend.status_changed_handler,
1821+ self.ui.process_status)
1822+
1823+ def _test_process_status(self, status_key):
1824+ """File sync status changes update the label."""
1825+ status = {gui.backend.STATUS_KEY: status_key,
1826+ gui.backend.MSG_KEY: 'something not important'}
1827+ self.ui.process_status(status)
1828+
1829+ self.assertEqual(self.ui.ui.sync_status_label.text(),
1830+ gui.STATUS_MARKUP % gui.FILE_SYNC_STATUS[status_key])
1831+
1832+ def test_process_status_disconnected(self):
1833+ """File sync status disconnected update the label."""
1834+ self._test_process_status(gui.backend.FILE_SYNC_DISCONNECTED)
1835+
1836+ def test_process_status_disabled(self):
1837+ """File sync status disabled update the label."""
1838+ self._test_process_status(gui.backend.FILE_SYNC_DISABLED)
1839+
1840+ def test_process_status_error(self):
1841+ """File sync status error update the label."""
1842+ self._test_process_status(gui.backend.FILE_SYNC_ERROR)
1843+
1844+ def test_process_status_idle(self):
1845+ """File sync status idle update the label."""
1846+ self._test_process_status(gui.backend.FILE_SYNC_IDLE)
1847+
1848+ def test_process_status_starting(self):
1849+ """File sync status starting update the label."""
1850+ self._test_process_status(gui.backend.FILE_SYNC_STARTING)
1851+
1852+ def test_process_status_stopped(self):
1853+ """File sync status stopped update the label."""
1854+ self._test_process_status(gui.backend.FILE_SYNC_STOPPED)
1855+
1856+ def test_process_status_syncing(self):
1857+ """File sync status syncing update the label."""
1858+ self._test_process_status(gui.backend.FILE_SYNC_SYNCING)
1859
1860=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_gui.py'
1861--- ubuntuone/controlpanel/qt/tests/test_gui.py 2011-05-23 18:36:26 +0000
1862+++ ubuntuone/controlpanel/gui/qt/tests/test_gui.py 2011-05-24 20:11:16 +0000
1863@@ -18,36 +18,16 @@
1864
1865 """Tests for the Qt UI."""
1866
1867-from ubuntuone.controlpanel.qt import gui
1868-
1869-from ubuntuone.controlpanel.tests import TestCase
1870-
1871-
1872-class FakeUi(object):
1873- """A fake Ui object."""
1874-
1875- def __init__(self):
1876- """Initialize this fake instance."""
1877- self.called = None
1878-
1879- # pylint: disable=C0103
1880- def setupUi(self, *args, **kwargs):
1881- """Fake setupUi."""
1882- self.called = (args, kwargs)
1883-
1884-
1885-class MainWindowTestCase(TestCase):
1886+from ubuntuone.controlpanel.gui.qt import gui
1887+from ubuntuone.controlpanel.gui.qt.tests import BaseTestCase
1888+
1889+
1890+class MainWindowTestCase(BaseTestCase):
1891 """Test the qt main window."""
1892
1893- def setUp(self):
1894- self.patch(gui.mainwindow_ui, "Ui_MainWindow", FakeUi)
1895- self.ui = gui.MainWindow()
1896-
1897- def test_init_loads_ui(self):
1898- """The __init__ method loads the ui."""
1899- # pylint: disable=E1101
1900- self.assertEqual(self.ui.ui.called,
1901- ((self.ui,), {}), 'setupUi called.')
1902+ innerclass_ui = gui.mainwindow_ui
1903+ innerclass_name = "Ui_MainWindow"
1904+ class_ui = gui.MainWindow
1905
1906 def test_close_event_calls_custom_close_callback(self):
1907 """When closing the window, close_callback is called."""
1908
1909=== modified file 'ubuntuone/controlpanel/integrationtests/test_gui_service.py'
1910--- ubuntuone/controlpanel/integrationtests/test_gui_service.py 2011-03-30 19:51:14 +0000
1911+++ ubuntuone/controlpanel/integrationtests/test_gui_service.py 2011-05-24 20:11:16 +0000
1912@@ -25,7 +25,7 @@
1913
1914 from dbus.mainloop.glib import DBusGMainLoop
1915
1916-from ubuntuone.controlpanel.gtk import gui
1917+from ubuntuone.controlpanel.gui.gtk import gui
1918 from ubuntuone.devtools.testcase import DBusTestCase
1919 from twisted.trial.unittest import TestCase
1920
1921@@ -63,9 +63,9 @@
1922 dbus_gmain_loop = self.mocker.replace(
1923 "dbus.mainloop.glib.DBusGMainLoop")
1924 register_service = self.mocker.replace(
1925- "ubuntuone.controlpanel.gtk.gui.register_service")
1926+ "ubuntuone.controlpanel.gui.gtk.gui.register_service")
1927 publish_service = self.mocker.replace(
1928- "ubuntuone.controlpanel.gtk.gui.publish_service")
1929+ "ubuntuone.controlpanel.gui.gtk.gui.publish_service")
1930 main = self.mocker.replace("gtk.main")
1931 dbus_gmain_loop(set_as_default=True)
1932 loop = self.mocker.mock()
1933
1934=== modified file 'ubuntuone/controlpanel/integrationtests/test_sd_client/linux.py'
1935--- ubuntuone/controlpanel/integrationtests/test_sd_client/linux.py 2011-05-18 19:12:57 +0000
1936+++ ubuntuone/controlpanel/integrationtests/test_sd_client/linux.py 2011-05-24 20:11:16 +0000
1937@@ -24,9 +24,16 @@
1938 import dbus
1939
1940 from twisted.internet.defer import inlineCallbacks, returnValue
1941+from ubuntuone.platform.linux import dbus_interface as sd_dbus_iface, tools
1942
1943 from ubuntuone.controlpanel import sd_client
1944-from ubuntuone.controlpanel.sd_client import sd_dbus_iface
1945+from ubuntuone.controlpanel.sd_client import (
1946+ SD_DBUS_IFACE_NAME,
1947+ SD_DBUS_IFACE_SYNC_NAME,
1948+ SD_DBUS_IFACE_STATUS_NAME,
1949+ SD_DBUS_IFACE_CONFIG_NAME,
1950+ SD_DBUS_IFACE_FOLDERS_NAME,
1951+)
1952 from ubuntuone.controlpanel.integrationtests import (TestDBusException,
1953 DBusClientTestCase)
1954
1955@@ -52,47 +59,47 @@
1956 throttling = False
1957 limits = {"download": -1, "upload": -1}
1958
1959- @dbus.service.method(dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME,
1960+ @dbus.service.method(dbus_interface=SD_DBUS_IFACE_CONFIG_NAME,
1961 in_signature="", out_signature="a{si}")
1962 def get_throttling_limits(self):
1963 """Return the throttling dict."""
1964 return self.limits
1965
1966 @dbus.service.method(in_signature="ii",
1967- dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
1968+ dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
1969 def set_throttling_limits(self, download, upload):
1970 """Set the throttling dict."""
1971 self.limits["download"] = download
1972 self.limits["upload"] = upload
1973
1974 @dbus.service.method(in_signature="", out_signature="b",
1975- dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
1976+ dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
1977 def bandwidth_throttling_enabled(self):
1978 """Get the state of bw throttling."""
1979 return self.throttling
1980
1981- @dbus.service.method(dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
1982+ @dbus.service.method(dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
1983 def enable_bandwidth_throttling(self):
1984 """Enable bw throttling."""
1985 self.throttling = True
1986
1987- @dbus.service.method(dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
1988+ @dbus.service.method(dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
1989 def disable_bandwidth_throttling(self):
1990 """Disable bw throttling."""
1991 self.throttling = False
1992
1993 @dbus.service.method(in_signature="", out_signature="b",
1994- dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
1995+ dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
1996 def show_all_notifications_enabled(self):
1997 """Get the state of show_all_notifications."""
1998 return self.show_all_notifications
1999
2000- @dbus.service.method(dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
2001+ @dbus.service.method(dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
2002 def enable_show_all_notifications(self):
2003 """Enable show_all_notifications."""
2004 self.show_all_notifications = True
2005
2006- @dbus.service.method(dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
2007+ @dbus.service.method(dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
2008 def disable_show_all_notifications(self):
2009 """Disable show_all_notifications."""
2010 self.show_all_notifications = False
2011@@ -101,46 +108,46 @@
2012 class ConfigMockDBusSyncDaemonFailing(dbus.service.Object):
2013 """A mock object that mimicks syncdaemon but fails."""
2014
2015- @dbus.service.method(dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME,
2016+ @dbus.service.method(dbus_interface=SD_DBUS_IFACE_CONFIG_NAME,
2017 in_signature="", out_signature="a{si}")
2018 def get_throttling_limits(self):
2019 """Fail while getting the throttling dict."""
2020 raise TestDBusException()
2021
2022 @dbus.service.method(in_signature="ii",
2023- dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
2024+ dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
2025 def set_throttling_limits(self, download, upload):
2026 """Fail while setting the throttling dict."""
2027 raise TestDBusException()
2028
2029 @dbus.service.method(in_signature="", out_signature="b",
2030- dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
2031+ dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
2032 def bandwidth_throttling_enabled(self):
2033 """Get the state of bw throttling."""
2034 raise TestDBusException()
2035
2036- @dbus.service.method(dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
2037+ @dbus.service.method(dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
2038 def enable_bandwidth_throttling(self):
2039 """Enable bw throttling."""
2040 raise TestDBusException()
2041
2042- @dbus.service.method(dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
2043+ @dbus.service.method(dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
2044 def disable_bandwidth_throttling(self):
2045 """Disable bw throttling."""
2046 raise TestDBusException()
2047
2048 @dbus.service.method(in_signature="", out_signature="b",
2049- dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
2050+ dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
2051 def show_all_notifications_enabled(self):
2052 """Get the state of show_all_notifications."""
2053 raise TestDBusException()
2054
2055- @dbus.service.method(dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
2056+ @dbus.service.method(dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
2057 def enable_show_all_notifications(self):
2058 """Enable show_all_notifications."""
2059 raise TestDBusException()
2060
2061- @dbus.service.method(dbus_interface=sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
2062+ @dbus.service.method(dbus_interface=SD_DBUS_IFACE_CONFIG_NAME)
2063 def disable_show_all_notifications(self):
2064 """Disable show_all_notifications."""
2065 raise TestDBusException()
2066@@ -152,7 +159,7 @@
2067 @inlineCallbacks
2068 def test_throttle_limits_returned(self):
2069 """When SD returns the limits, they are handled."""
2070- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2071+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2072 "/config", ConfigMockDBusSyncDaemon)
2073 limits = yield sd_client.get_throttling_limits()
2074 self.assertEqual(limits, ConfigMockDBusSyncDaemon.limits)
2075@@ -160,7 +167,7 @@
2076 @inlineCallbacks
2077 def test_getting_throttle_limits_throws_an_error(self):
2078 """Handle DBus error when getting the limits."""
2079- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2080+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2081 "/config", ConfigMockDBusSyncDaemonFailing)
2082 yield self.assertFailure(sd_client.get_throttling_limits(),
2083 dbus.DBusException)
2084@@ -168,7 +175,7 @@
2085 @inlineCallbacks
2086 def test_throttle_limits_set(self):
2087 """Setting the limits."""
2088- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2089+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2090 "/config", ConfigMockDBusSyncDaemon)
2091 yield sd_client.set_throttling_limits(SAMPLE_LIMITS)
2092 expected_result = {
2093@@ -180,7 +187,7 @@
2094 @inlineCallbacks
2095 def test_setting_throttle_limits_throws_an_error(self):
2096 """Handle DBus error when setting the limits."""
2097- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2098+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2099 "/config", ConfigMockDBusSyncDaemonFailing)
2100 d = sd_client.set_throttling_limits(SAMPLE_LIMITS)
2101 yield self.assertFailure(d, dbus.DBusException)
2102@@ -188,7 +195,7 @@
2103 @inlineCallbacks
2104 def test_throttle_get(self):
2105 """Getting the throttling state."""
2106- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2107+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2108 "/config", ConfigMockDBusSyncDaemon)
2109 self.mock.throttling = False
2110 throttling = yield sd_client.bandwidth_throttling_enabled()
2111@@ -200,7 +207,7 @@
2112 @inlineCallbacks
2113 def test_throttle_get_throws_an_error(self):
2114 """Handle DBus error when getting the throttling state."""
2115- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2116+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2117 "/config", ConfigMockDBusSyncDaemonFailing)
2118 d = sd_client.bandwidth_throttling_enabled()
2119 yield self.assertFailure(d, dbus.DBusException)
2120@@ -208,7 +215,7 @@
2121 @inlineCallbacks
2122 def test_throttle_enable(self):
2123 """Enabling bw throttling."""
2124- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2125+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2126 "/config", ConfigMockDBusSyncDaemon)
2127 self.mock.throttling = False
2128 yield sd_client.enable_bandwidth_throttling()
2129@@ -217,7 +224,7 @@
2130 @inlineCallbacks
2131 def test_throttle_enable_throws_an_error(self):
2132 """Handle DBus error when enabling throttling."""
2133- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2134+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2135 "/config", ConfigMockDBusSyncDaemonFailing)
2136 d = sd_client.enable_bandwidth_throttling()
2137 yield self.assertFailure(d, dbus.DBusException)
2138@@ -225,7 +232,7 @@
2139 @inlineCallbacks
2140 def test_throttle_disable(self):
2141 """Disabling bw throttling."""
2142- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2143+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2144 "/config", ConfigMockDBusSyncDaemon)
2145 self.mock.throttling = True
2146 yield sd_client.disable_bandwidth_throttling()
2147@@ -234,7 +241,7 @@
2148 @inlineCallbacks
2149 def test_throttle_disable_throws_an_error(self):
2150 """Handle DBus error when disabling throttling."""
2151- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2152+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2153 "/config", ConfigMockDBusSyncDaemonFailing)
2154 d = sd_client.disable_bandwidth_throttling()
2155 yield self.assertFailure(d, dbus.DBusException)
2156@@ -246,7 +253,7 @@
2157 @inlineCallbacks
2158 def test_notifications_get(self):
2159 """Getting the show_all_notifications state."""
2160- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2161+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2162 "/config", ConfigMockDBusSyncDaemon)
2163 self.mock.show_all_notifications = False
2164 state = yield sd_client.show_all_notifications_enabled()
2165@@ -258,7 +265,7 @@
2166 @inlineCallbacks
2167 def test_notifications_get_throws_an_error(self):
2168 """Handle DBus error when getting the show_all_notifications state."""
2169- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2170+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2171 "/config", ConfigMockDBusSyncDaemonFailing)
2172 d = sd_client.show_all_notifications_enabled()
2173 yield self.assertFailure(d, dbus.DBusException)
2174@@ -266,7 +273,7 @@
2175 @inlineCallbacks
2176 def test_notifications_enable(self):
2177 """Enabling show_all_notifications."""
2178- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2179+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2180 "/config", ConfigMockDBusSyncDaemon)
2181 self.mock.show_all_notifications = False
2182 yield sd_client.enable_show_all_notifications()
2183@@ -275,7 +282,7 @@
2184 @inlineCallbacks
2185 def test_notifications_enable_throws_an_error(self):
2186 """Handle DBus error when enabling show_all_notifications."""
2187- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2188+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2189 "/config", ConfigMockDBusSyncDaemonFailing)
2190 d = sd_client.enable_show_all_notifications()
2191 yield self.assertFailure(d, dbus.DBusException)
2192@@ -283,7 +290,7 @@
2193 @inlineCallbacks
2194 def test_notifications_disable(self):
2195 """Disabling show_all_notifications."""
2196- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2197+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2198 "/config", ConfigMockDBusSyncDaemon)
2199 self.mock.show_all_notifications = True
2200 yield sd_client.disable_show_all_notifications()
2201@@ -292,7 +299,7 @@
2202 @inlineCallbacks
2203 def test_notifications_disable_throws_an_error(self):
2204 """Handle DBus error when disabling show_all_notifications."""
2205- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2206+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2207 "/config", ConfigMockDBusSyncDaemonFailing)
2208 d = sd_client.disable_show_all_notifications()
2209 yield self.assertFailure(d, dbus.DBusException)
2210@@ -326,7 +333,7 @@
2211
2212 return udf
2213
2214- @dbus.service.method(sd_dbus_iface.DBUS_IFACE_FOLDERS_NAME,
2215+ @dbus.service.method(SD_DBUS_IFACE_FOLDERS_NAME,
2216 in_signature='s')
2217 def create(self, path):
2218 """Create a user defined folder in the specified path."""
2219@@ -339,7 +346,7 @@
2220 self.udf_id += 1
2221 self.emit_folder_created(udf)
2222
2223- @dbus.service.method(sd_dbus_iface.DBUS_IFACE_FOLDERS_NAME,
2224+ @dbus.service.method(SD_DBUS_IFACE_FOLDERS_NAME,
2225 in_signature='s')
2226 def delete(self, folder_id):
2227 """Delete the folder specified by folder_id"""
2228@@ -350,13 +357,13 @@
2229 udf = self.udfs.pop(folder_id)
2230 self.emit_folder_deleted(udf)
2231
2232- @dbus.service.method(sd_dbus_iface.DBUS_IFACE_FOLDERS_NAME,
2233+ @dbus.service.method(SD_DBUS_IFACE_FOLDERS_NAME,
2234 out_signature='aa{ss}')
2235 def get_folders(self):
2236 """Return the list of folders (a list of dicts)"""
2237 return [sd_dbus_iface.get_udf_dict(udf) for udf in self.udfs.values()]
2238
2239- @dbus.service.method(sd_dbus_iface.DBUS_IFACE_FOLDERS_NAME,
2240+ @dbus.service.method(SD_DBUS_IFACE_FOLDERS_NAME,
2241 in_signature='s', out_signature='')
2242 def subscribe(self, folder_id):
2243 """Subscribe to the specified folder"""
2244@@ -368,7 +375,7 @@
2245 self.udfs[folder_id]['subscribed'] = sd_dbus_iface.bool_str(True)
2246 self.emit_folder_subscribed(self.udfs[folder_id])
2247
2248- @dbus.service.method(sd_dbus_iface.DBUS_IFACE_FOLDERS_NAME,
2249+ @dbus.service.method(SD_DBUS_IFACE_FOLDERS_NAME,
2250 in_signature='s', out_signature='')
2251 def unsubscribe(self, folder_id):
2252 """Unsubscribe from the specified folder"""
2253@@ -380,7 +387,7 @@
2254 self.udfs[folder_id]['subscribed'] = sd_dbus_iface.bool_str(False)
2255 self.emit_folder_unsubscribed(self.udfs[folder_id])
2256
2257- @dbus.service.method(sd_dbus_iface.DBUS_IFACE_FOLDERS_NAME,
2258+ @dbus.service.method(SD_DBUS_IFACE_FOLDERS_NAME,
2259 in_signature='s', out_signature='a{ss}')
2260 def get_info(self, path):
2261 """Override get_info to avoid accessing filesystem_manager."""
2262@@ -390,7 +397,7 @@
2263 else:
2264 return {}
2265
2266- @dbus.service.method(sd_dbus_iface.DBUS_IFACE_FOLDERS_NAME,
2267+ @dbus.service.method(SD_DBUS_IFACE_FOLDERS_NAME,
2268 in_signature='', out_signature='')
2269 def refresh_volumes(self):
2270 """Refresh the volumes list, requesting it to the server."""
2271@@ -402,7 +409,7 @@
2272 def setUp(self):
2273 super(FoldersTestCase, self).setUp()
2274 self.patch(sd_dbus_iface, 'get_udf_dict', lambda udf: udf)
2275- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2276+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2277 "/folders", FoldersMockDBusSyncDaemon)
2278
2279 @inlineCallbacks
2280@@ -575,7 +582,7 @@
2281
2282 def setUp(self):
2283 super(SharesTestCase, self).setUp()
2284- self.patch(sd_client, 'SyncDaemonTool', FakedSyncDaemonTool)
2285+ self.patch(tools, 'SyncDaemonTool', FakedSyncDaemonTool)
2286 SHARES.clear()
2287
2288 @inlineCallbacks
2289@@ -670,7 +677,7 @@
2290 """Get the current status of the system."""
2291 return self.state_dict
2292
2293- @dbus.service.method(sd_dbus_iface.DBUS_IFACE_STATUS_NAME,
2294+ @dbus.service.method(SD_DBUS_IFACE_STATUS_NAME,
2295 in_signature='', out_signature='a{ss}')
2296 def current_status(self):
2297 """Return the current faked status of the system."""
2298@@ -679,7 +686,7 @@
2299 # pylint: disable=C0103
2300 # Invalid name "StatusChanged"
2301
2302- @dbus.service.signal(sd_dbus_iface.DBUS_IFACE_STATUS_NAME)
2303+ @dbus.service.signal(SD_DBUS_IFACE_STATUS_NAME)
2304 def StatusChanged(self, status):
2305 """Fire a signal to notify that the status of the system changed."""
2306
2307@@ -693,7 +700,7 @@
2308
2309 def setUp(self):
2310 super(StatusTestCase, self).setUp()
2311- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2312+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2313 "/status", StatusMockDBusSyncDaemon)
2314
2315 @inlineCallbacks
2316@@ -727,7 +734,7 @@
2317 self.assertEqual(sig._handler, self._set_called)
2318 self.assertEqual(sig._member, 'StatusChanged')
2319 self.assertEqual(sig._path, '/status')
2320- self.assertEqual(sig._interface, sd_dbus_iface.DBUS_IFACE_STATUS_NAME)
2321+ self.assertEqual(sig._interface, SD_DBUS_IFACE_STATUS_NAME)
2322
2323
2324 class FileSyncTestCase(DBusClientTestCase):
2325@@ -737,7 +744,7 @@
2326 def test_files_sync_enabled(self):
2327 """Retrieve whether file sync is enabled."""
2328 expected = object()
2329- self.patch(sd_client.SyncDaemonTool, 'is_files_sync_enabled',
2330+ self.patch(tools.SyncDaemonTool, 'is_files_sync_enabled',
2331 lambda _: expected)
2332
2333 enabled = yield sd_client.files_sync_enabled()
2334@@ -747,7 +754,7 @@
2335 @inlineCallbacks
2336 def test_set_files_sync_enabled(self):
2337 """Set if file sync is enabled or not."""
2338- self.patch(sd_client.SyncDaemonTool, 'enable_files_sync',
2339+ self.patch(tools.SyncDaemonTool, 'enable_files_sync',
2340 self._set_called)
2341 expected = object()
2342 # set some unique value
2343@@ -758,7 +765,7 @@
2344 @inlineCallbacks
2345 def test_connect_file_sync(self):
2346 """Set if file sync is enabled or not."""
2347- self.patch(sd_client.SyncDaemonTool, 'connect', self._set_called)
2348+ self.patch(tools.SyncDaemonTool, 'connect', self._set_called)
2349 yield sd_client.connect_file_sync()
2350
2351 self.assertEqual(self._called, ((), {}))
2352@@ -766,7 +773,7 @@
2353 @inlineCallbacks
2354 def test_disconnect_file_sync(self):
2355 """Set if file sync is enabled or not."""
2356- self.patch(sd_client.SyncDaemonTool, 'disconnect', self._set_called)
2357+ self.patch(tools.SyncDaemonTool, 'disconnect', self._set_called)
2358 yield sd_client.disconnect_file_sync()
2359
2360 self.assertEqual(self._called, ((), {}))
2361@@ -774,7 +781,7 @@
2362 @inlineCallbacks
2363 def test_start_file_sync(self):
2364 """Set if file sync is enabled or not."""
2365- self.patch(sd_client.SyncDaemonTool, 'start', self._set_called)
2366+ self.patch(tools.SyncDaemonTool, 'start', self._set_called)
2367 yield sd_client.start_file_sync()
2368
2369 self.assertEqual(self._called, ((), {}))
2370@@ -782,7 +789,7 @@
2371 @inlineCallbacks
2372 def test_stop_file_sync(self):
2373 """Set if file sync is enabled or not."""
2374- self.patch(sd_client.SyncDaemonTool, 'quit', self._set_called)
2375+ self.patch(tools.SyncDaemonTool, 'quit', self._set_called)
2376 yield sd_client.stop_file_sync()
2377
2378 self.assertEqual(self._called, ((), {}))
2379@@ -795,19 +802,19 @@
2380 SHARES_DIR = u'/yadda/yoda/.hidden/ugly/dir/name/shares'
2381 SHARES_DIR_LINK = u'/yadda/yoda/Test me/Shared With Me'
2382
2383- @dbus.service.method(sd_dbus_iface.DBUS_IFACE_SYNC_NAME,
2384+ @dbus.service.method(SD_DBUS_IFACE_SYNC_NAME,
2385 in_signature='', out_signature='s')
2386 def get_rootdir(self):
2387 """Return the root dir/mount point."""
2388 return self.ROOT_DIR
2389
2390- @dbus.service.method(sd_dbus_iface.DBUS_IFACE_SYNC_NAME,
2391+ @dbus.service.method(SD_DBUS_IFACE_SYNC_NAME,
2392 in_signature='', out_signature='s')
2393 def get_sharesdir(self):
2394 """Return the shares dir/mount point."""
2395 return self.SHARES_DIR
2396
2397- @dbus.service.method(sd_dbus_iface.DBUS_IFACE_SYNC_NAME,
2398+ @dbus.service.method(SD_DBUS_IFACE_SYNC_NAME,
2399 in_signature='', out_signature='s')
2400 def get_sharesdir_link(self):
2401 """Return the root dir/mount point."""
2402@@ -819,7 +826,7 @@
2403
2404 def setUp(self):
2405 super(BasicTestCase, self).setUp()
2406- self.register_mockserver(sd_dbus_iface.DBUS_IFACE_NAME,
2407+ self.register_mockserver(SD_DBUS_IFACE_NAME,
2408 "/", MockDBusSyncDaemon)
2409
2410 @inlineCallbacks
2411
2412=== modified file 'ubuntuone/controlpanel/sd_client/linux.py'
2413--- ubuntuone/controlpanel/sd_client/linux.py 2011-05-18 18:05:19 +0000
2414+++ ubuntuone/controlpanel/sd_client/linux.py 2011-05-24 20:11:16 +0000
2415@@ -23,12 +23,19 @@
2416
2417 from twisted.internet import defer
2418
2419-from ubuntuone.platform.linux import dbus_interface as sd_dbus_iface
2420-from ubuntuone.platform.linux.tools import SyncDaemonTool
2421-
2422 from ubuntuone.controlpanel.logger import setup_logging
2423
2424
2425+SD_DBUS_IFACE_NAME = 'com.ubuntuone.SyncDaemon'
2426+SD_DBUS_IFACE_SYNC_NAME = SD_DBUS_IFACE_NAME + '.SyncDaemon'
2427+SD_DBUS_IFACE_STATUS_NAME = SD_DBUS_IFACE_NAME + '.Status'
2428+SD_DBUS_IFACE_EVENTS_NAME = SD_DBUS_IFACE_NAME + '.Events'
2429+SD_DBUS_IFACE_FS_NAME = SD_DBUS_IFACE_NAME + '.FileSystem'
2430+SD_DBUS_IFACE_SHARES_NAME = SD_DBUS_IFACE_NAME + '.Shares'
2431+SD_DBUS_IFACE_CONFIG_NAME = SD_DBUS_IFACE_NAME + '.Config'
2432+SD_DBUS_IFACE_FOLDERS_NAME = SD_DBUS_IFACE_NAME + '.Folders'
2433+SD_DBUS_IFACE_PUBLIC_FILES_NAME = SD_DBUS_IFACE_NAME + '.PublicFiles'
2434+
2435 logger = setup_logging('sd_client')
2436
2437
2438@@ -40,12 +47,21 @@
2439 """Do nothing"""
2440
2441
2442+def get_syncdaemon_tool():
2443+ """Get a proxy for the SyncDaemonTool."""
2444+ # Reimport 'SyncDaemonTool'
2445+ # pylint: disable=W0404
2446+ from ubuntuone.platform.linux.tools import SyncDaemonTool
2447+ proxy = SyncDaemonTool(bus=dbus.SessionBus())
2448+ return proxy
2449+
2450+
2451 def get_syncdaemon_proxy(object_path, dbus_interface):
2452 """Get a DBus proxy for syncdaemon at 'object_path':'dbus_interface'."""
2453 logger.debug('get_syncdaemon_proxy: object_path %r, dbus_interface %r',
2454 object_path, dbus_interface)
2455 bus = dbus.SessionBus()
2456- obj = bus.get_object(bus_name=sd_dbus_iface.DBUS_IFACE_NAME,
2457+ obj = bus.get_object(bus_name=SD_DBUS_IFACE_NAME,
2458 object_path=object_path,
2459 follow_name_owner_changes=True)
2460 proxy = dbus.Interface(object=obj, dbus_interface=dbus_interface)
2461@@ -55,19 +71,19 @@
2462 def get_config_syncdaemon_proxy():
2463 """Get a DBus proxy for syncdaemon config calls."""
2464 return get_syncdaemon_proxy("/config",
2465- sd_dbus_iface.DBUS_IFACE_CONFIG_NAME)
2466+ SD_DBUS_IFACE_CONFIG_NAME)
2467
2468
2469 def get_folders_syncdaemon_proxy():
2470 """Get a DBus proxy for syncdaemon folders calls."""
2471 return get_syncdaemon_proxy("/folders",
2472- sd_dbus_iface.DBUS_IFACE_FOLDERS_NAME)
2473+ SD_DBUS_IFACE_FOLDERS_NAME)
2474
2475
2476 def get_status_syncdaemon_proxy():
2477 """Get a DBus proxy for syncdaemon status calls."""
2478 return get_syncdaemon_proxy("/status",
2479- sd_dbus_iface.DBUS_IFACE_STATUS_NAME)
2480+ SD_DBUS_IFACE_STATUS_NAME)
2481
2482
2483 def get_throttling_limits():
2484@@ -149,7 +165,7 @@
2485 def get_root_dir():
2486 """Retrieve the root information from syncdaemon."""
2487 d = defer.Deferred()
2488- proxy = get_syncdaemon_proxy("/", sd_dbus_iface.DBUS_IFACE_SYNC_NAME)
2489+ proxy = get_syncdaemon_proxy("/", SD_DBUS_IFACE_SYNC_NAME)
2490 proxy.get_rootdir(reply_handler=d.callback, error_handler=d.errback)
2491 return d
2492
2493@@ -157,7 +173,7 @@
2494 def get_shares_dir():
2495 """Retrieve the shares information from syncdaemon."""
2496 d = defer.Deferred()
2497- proxy = get_syncdaemon_proxy("/", sd_dbus_iface.DBUS_IFACE_SYNC_NAME)
2498+ proxy = get_syncdaemon_proxy("/", SD_DBUS_IFACE_SYNC_NAME)
2499 proxy.get_sharesdir(reply_handler=d.callback, error_handler=d.errback)
2500 return d
2501
2502@@ -165,7 +181,7 @@
2503 def get_shares_dir_link():
2504 """Retrieve the shares information from syncdaemon."""
2505 d = defer.Deferred()
2506- proxy = get_syncdaemon_proxy("/", sd_dbus_iface.DBUS_IFACE_SYNC_NAME)
2507+ proxy = get_syncdaemon_proxy("/", SD_DBUS_IFACE_SYNC_NAME)
2508 proxy.get_sharesdir_link(reply_handler=d.callback, error_handler=d.errback)
2509 return d
2510
2511@@ -244,7 +260,7 @@
2512 @defer.inlineCallbacks
2513 def get_shares():
2514 """Retrieve the shares information from syncdaemon."""
2515- result = yield SyncDaemonTool(bus=dbus.SessionBus()).get_shares()
2516+ result = yield get_syncdaemon_tool().get_shares()
2517 defer.returnValue(result)
2518
2519
2520@@ -252,7 +268,7 @@
2521 def subscribe_share(share_id):
2522 """Subscribe to 'share_id'."""
2523 try:
2524- yield SyncDaemonTool(bus=dbus.SessionBus()).subscribe_share(share_id)
2525+ yield get_syncdaemon_tool().subscribe_share(share_id)
2526 except Exception, e:
2527 raise VolumesError(share_id, e)
2528
2529@@ -261,7 +277,7 @@
2530 def unsubscribe_share(share_id):
2531 """Unsubscribe 'share_id'."""
2532 try:
2533- yield SyncDaemonTool(bus=dbus.SessionBus()).unsubscribe_share(share_id)
2534+ yield get_syncdaemon_tool().unsubscribe_share(share_id)
2535 except Exception, e:
2536 raise VolumesError(share_id, e)
2537
2538@@ -283,35 +299,35 @@
2539
2540 def files_sync_enabled():
2541 """Get if file sync service is enabled."""
2542- enabled = SyncDaemonTool(bus=None).is_files_sync_enabled()
2543+ enabled = get_syncdaemon_tool().is_files_sync_enabled()
2544 return defer.succeed(enabled)
2545
2546
2547 @defer.inlineCallbacks
2548 def set_files_sync_enabled(enabled):
2549 """Set the file sync service to be 'enabled'."""
2550- yield SyncDaemonTool(bus=dbus.SessionBus()).enable_files_sync(enabled)
2551+ yield get_syncdaemon_tool().enable_files_sync(enabled)
2552
2553
2554 @defer.inlineCallbacks
2555 def connect_file_sync():
2556 """Connect the file sync service."""
2557- yield SyncDaemonTool(bus=dbus.SessionBus()).connect()
2558+ yield get_syncdaemon_tool().connect()
2559
2560
2561 @defer.inlineCallbacks
2562 def disconnect_file_sync():
2563 """Disconnect the file sync service."""
2564- yield SyncDaemonTool(bus=dbus.SessionBus()).disconnect()
2565+ yield get_syncdaemon_tool().disconnect()
2566
2567
2568 @defer.inlineCallbacks
2569 def start_file_sync():
2570 """Start the file sync service."""
2571- yield SyncDaemonTool(bus=dbus.SessionBus()).start()
2572+ yield get_syncdaemon_tool().start()
2573
2574
2575 @defer.inlineCallbacks
2576 def stop_file_sync():
2577 """Stop the file sync service."""
2578- yield SyncDaemonTool(bus=dbus.SessionBus()).quit()
2579+ yield get_syncdaemon_tool().quit()

Subscribers

People subscribed via source and target branches