Merge lp:~facundo/magicicada-client/remove-sync-menu into lp:magicicada-client

Proposed by Facundo Batista
Status: Merged
Approved by: Natalia Bidart
Approved revision: 1445
Merged at revision: 1444
Proposed branch: lp:~facundo/magicicada-client/remove-sync-menu
Merge into: lp:magicicada-client
Diff against target: 1535 lines (+23/-1209)
17 files modified
contrib/testing/testcase.py (+9/-18)
setup.py (+0/-1)
ubuntuone/clientdefs.py.in (+2/-11)
ubuntuone/platform/ipc/ipc_client.py (+1/-16)
ubuntuone/platform/ipc/linux.py (+1/-33)
ubuntuone/platform/ipc/perspective_broker.py (+1/-5)
ubuntuone/platform/sync_menu/__init__.py (+0/-41)
ubuntuone/platform/sync_menu/common.py (+0/-41)
ubuntuone/platform/sync_menu/linux.py (+0/-330)
ubuntuone/platform/tests/ipc/test_external_interface.py (+2/-15)
ubuntuone/platform/tests/sync_menu/__init__.py (+0/-27)
ubuntuone/platform/tests/sync_menu/test_common.py (+0/-54)
ubuntuone/platform/tests/sync_menu/test_linux.py (+0/-586)
ubuntuone/platform/tests/test_tools.py (+5/-13)
ubuntuone/platform/tools/__init__.py (+1/-7)
ubuntuone/syncdaemon/__init__.py (+1/-7)
ubuntuone/syncdaemon/interaction_interfaces.py (+0/-4)
To merge this branch: bzr merge lp:~facundo/magicicada-client/remove-sync-menu
Reviewer Review Type Date Requested Status
Natalia Bidart Approve
Review via email: mp+343773@code.launchpad.net

Commit message

Remove SyncMenu traces - no more UI client except Magicicada own shiny thing.

To post a comment you must log in.
1444. By Facundo Batista

Removed more unused constants.

1445. By Facundo Batista

Merged trunk in.

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

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'contrib/testing/testcase.py'
--- contrib/testing/testcase.py 2018-03-14 21:01:56 +0000
+++ contrib/testing/testcase.py 2018-04-24 23:14:39 +0000
@@ -58,8 +58,6 @@
58 main,58 main,
59 local_rescan,59 local_rescan,
60 tritcask,60 tritcask,
61 RECENT_TRANSFERS,
62 UPLOADING,
63)61)
64from ubuntuone.syncdaemon import logger62from ubuntuone.syncdaemon import logger
65from ubuntuone import platform63from ubuntuone import platform
@@ -78,6 +76,10 @@
78 'password': 'test_password'}76 'password': 'test_password'}
7977
8078
79def NOOP(*a, **kw):
80 """Do nothing."""
81
82
81@contextlib.contextmanager83@contextlib.contextmanager
82def environ(env_var, new_value):84def environ(env_var, new_value):
83 """context manager to replace/add an environ value"""85 """context manager to replace/add an environ value"""
@@ -190,14 +192,6 @@
190 node_is_with_queued_move = cleanup = get_public_files = disconnect192 node_is_with_queued_move = cleanup = get_public_files = disconnect
191193
192194
193class FakeStatusListener(object):
194 """A fake StatusListener."""
195
196 def menu_data(self):
197 """Fake menu_data."""
198 return {RECENT_TRANSFERS: [], UPLOADING: []}
199
200
201class FakeMonitor(object):195class FakeMonitor(object):
202 """A fake FilesystemMonitor."""196 """A fake FilesystemMonitor."""
203197
@@ -259,8 +253,8 @@
259 self.vm = volume_manager.VolumeManager(self)253 self.vm = volume_manager.VolumeManager(self)
260 self.fs = fs_manager.FileSystemManager(254 self.fs = fs_manager.FileSystemManager(
261 self.data_dir, self.partials_dir, self.vm, self.db)255 self.data_dir, self.partials_dir, self.vm, self.db)
262 self.event_q = event_queue.EventQueue(self.fs,256 self.event_q = event_queue.EventQueue(
263 monitor_class=self._monitor_class)257 self.fs, monitor_class=self._monitor_class)
264 self.fs.register_eq(self.event_q)258 self.fs.register_eq(self.event_q)
265 self.action_q = self._fake_AQ_class(self.event_q, self,259 self.action_q = self._fake_AQ_class(self.event_q, self,
266 *self._fake_AQ_params)260 *self._fake_AQ_params)
@@ -275,8 +269,6 @@
275 self.lr = local_rescan.LocalRescan(self.vm, self.fs,269 self.lr = local_rescan.LocalRescan(self.vm, self.fs,
276 self.event_q, self.action_q)270 self.event_q, self.action_q)
277271
278 self.status_listener = FakeStatusListener()
279
280 def _connect_aq(self, _):272 def _connect_aq(self, _):
281 """Connect the fake action queue."""273 """Connect the fake action queue."""
282 self.action_q.connect()274 self.action_q.connect()
@@ -408,9 +400,8 @@
408 self.patch(platform, "user_home", self.home_dir)400 self.patch(platform, "user_home", self.home_dir)
409401
410 # use the config from the branch402 # use the config from the branch
411 new_get_config_files = lambda: [os.path.join(os.environ['ROOTDIR'],403 self.patch(config, 'get_config_files', lambda: [
412 'data', 'syncdaemon.conf')]404 os.path.join(os.environ['ROOTDIR'], 'data', 'syncdaemon.conf')])
413 self.patch(config, 'get_config_files', new_get_config_files)
414405
415 # fake a very basic config file with sane defaults for the tests406 # fake a very basic config file with sane defaults for the tests
416 config_dir = self.mktemp('config')407 config_dir = self.mktemp('config')
@@ -626,7 +617,7 @@
626 try:617 try:
627 result = super(FakedObject, self).__getattribute__(attr_name)618 result = super(FakedObject, self).__getattribute__(attr_name)
628 except AttributeError:619 except AttributeError:
629 result = lambda *a, **kw: None620 result = NOOP
630 super(FakedObject, self).__setattr__(attr_name, result)621 super(FakedObject, self).__setattr__(attr_name, result)
631622
632 if attr_name == '_called':623 if attr_name == '_called':
633624
=== modified file 'setup.py'
--- setup.py 2018-03-14 21:01:56 +0000
+++ setup.py 2018-04-24 23:14:39 +0000
@@ -71,7 +71,6 @@
71 with open(fname, 'w') as out_file:71 with open(fname, 'w') as out_file:
72 content = content.replace('@VERSION@', VERSION)72 content = content.replace('@VERSION@', VERSION)
73 content = content.replace('@PROJECT_NAME@', PROJECT_NAME)73 content = content.replace('@PROJECT_NAME@', PROJECT_NAME)
74 content = content.replace('@GETTEXT_PACKAGE@', PROJECT_NAME)
75 content = content.replace('@LOG_LEVEL@', LOG_LEVEL)74 content = content.replace('@LOG_LEVEL@', LOG_LEVEL)
76 content = content.replace('@LOG_FILE_SIZE@', LOG_FILE_SIZE)75 content = content.replace('@LOG_FILE_SIZE@', LOG_FILE_SIZE)
77 if prefix is not None:76 if prefix is not None:
7877
=== modified file 'ubuntuone/clientdefs.py.in'
--- ubuntuone/clientdefs.py.in 2016-06-04 23:41:52 +0000
+++ ubuntuone/clientdefs.py.in 2018-04-24 23:14:39 +0000
@@ -1,8 +1,5 @@
1# ubuntuone.clientdefs - Configure-time definitions
2#
3# Author: David Planella <david.planella@ubuntu.com>
4#
5# Copyright 2009-2012 Canonical Ltd.1# Copyright 2009-2012 Canonical Ltd.
2# Copyright 2015-2018 Chicharreros (https://launchpad.net/~chicharreros)
6#3#
7# This program is free software: you can redistribute it and/or modify it4# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published5# under the terms of the GNU General Public License version 3, as published
@@ -30,7 +27,6 @@
30# files in the program, then also delete it here.27# files in the program, then also delete it here.
31"""Configure-time definitions for the client."""28"""Configure-time definitions for the client."""
3229
33import gettext
34import os30import os
35import platform31import platform
36import urllib32import urllib
@@ -39,16 +35,11 @@
39VERSION = "@VERSION@"35VERSION = "@VERSION@"
40LOCALEDIR = "@localedir@"36LOCALEDIR = "@localedir@"
41LIBEXECDIR = "@libexecdir@"37LIBEXECDIR = "@libexecdir@"
42GETTEXT_PACKAGE = "@GETTEXT_PACKAGE@"38PROJECT_NAME = "@PROJECT_NAME@"
43PROJECT_NAME = "@GETTEXT_PACKAGE@"
44PROJECT_DIR = os.path.join('@prefix@', 'share', PROJECT_NAME)39PROJECT_DIR = os.path.join('@prefix@', 'share', PROJECT_NAME)
45BIN_DIR = os.path.join('@prefix@', 'lib', PROJECT_NAME)40BIN_DIR = os.path.join('@prefix@', 'lib', PROJECT_NAME)
4641
4742
48def Q_(string):
49 return gettext.dgettext(GETTEXT_PACKAGE, string)
50
51
52def platform_data():43def platform_data():
53 result = {'platform': platform.system(),44 result = {'platform': platform.system(),
54 'platform_version': platform.release(),45 'platform_version': platform.release(),
5546
=== modified file 'ubuntuone/platform/ipc/ipc_client.py'
--- ubuntuone/platform/ipc/ipc_client.py 2016-09-17 01:06:23 +0000
+++ ubuntuone/platform/ipc/ipc_client.py 2018-04-24 23:14:39 +0000
@@ -1,6 +1,7 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2#2#
3# Copyright 2011-2012 Canonical Ltd.3# Copyright 2011-2012 Canonical Ltd.
4# Copyright 2015-2018 Chicharreros (https://launchpad.net/~chicharreros)
4#5#
5# This program is free software: you can redistribute it and/or modify it6# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published7# under the terms of the GNU General Public License version 3, as published
@@ -197,22 +198,6 @@
197 def current_uploads(self):198 def current_uploads(self):
198 """Return a list of files with a upload in progress."""199 """Return a list of files with a upload in progress."""
199200
200 @remote
201 def sync_menu(self):
202 """
203 This method returns a dictionary, with the following keys and values:
204
205 Key: 'recent-transfers'
206 Value: a list of strings (paths), each being the name of a file that
207 was recently transferred.
208
209 Key: 'uploading'
210 Value: a list of tuples, with each tuple having the following items:
211 * str: the path of a file that's currently being uploaded
212 * int: size of the file
213 * int: bytes written
214 """
215
216 @signal201 @signal
217 def on_content_queue_changed(self):202 def on_content_queue_changed(self):
218 """Emit ContentQueueChanged."""203 """Emit ContentQueueChanged."""
219204
=== modified file 'ubuntuone/platform/ipc/linux.py'
--- ubuntuone/platform/ipc/linux.py 2016-09-17 01:06:23 +0000
+++ ubuntuone/platform/ipc/linux.py 2018-04-24 23:14:39 +0000
@@ -1,6 +1,7 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2#2#
3# Copyright 2009-2012 Canonical Ltd.3# Copyright 2009-2012 Canonical Ltd.
4# Copyright 2015-2018 Chicharreros (https://launchpad.net/~chicharreros)
4#5#
5# This program is free software: you can redistribute it and/or modify it6# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published7# under the terms of the GNU General Public License version 3, as published
@@ -38,10 +39,6 @@
38from xml.etree import ElementTree39from xml.etree import ElementTree
3940
40from ubuntuone.platform import launcher41from ubuntuone.platform import launcher
41from ubuntuone.syncdaemon import (
42 RECENT_TRANSFERS,
43 UPLOADING,
44)
4542
46# Disable the "Invalid Name" check here, as we have lots of DBus style names43# Disable the "Invalid Name" check here, as we have lots of DBus style names
4744
@@ -176,35 +173,6 @@
176 warnings.warn('Use "waiting" method instead.', DeprecationWarning)173 warnings.warn('Use "waiting" method instead.', DeprecationWarning)
177 return self.service.status.waiting_content()174 return self.service.status.waiting_content()
178175
179 @dbus.service.method(DBUS_IFACE_STATUS_NAME, out_signature='a{sv}')
180 def sync_menu(self):
181 """
182 This method returns a dictionary, with the following keys and values:
183
184 Key: 'recent-transfers'
185 Value: a list of strings (paths), each being the name of a file that
186 was recently transferred.
187
188 Key: 'uploading'
189 Value: a list of tuples, with each tuple having the following items:
190 * str: the path of a file that's currently being uploaded
191 * int: size of the file
192 * int: bytes written
193 """
194 data = self.service.status.sync_menu()
195 uploading = data[UPLOADING]
196 transfers = data[RECENT_TRANSFERS]
197 upload_data = dbus.Array(signature="(sii)")
198 transfer_data = dbus.Array(signature="s")
199 for up in uploading:
200 upload_data.append(dbus.Struct(up, signature="sii"))
201 for transfer in transfers:
202 transfer_data.append(transfer)
203 result = dbus.Dictionary(signature="sv")
204 result[UPLOADING] = upload_data
205 result[RECENT_TRANSFERS] = transfer_data
206 return result
207
208 @dbus.service.signal(DBUS_IFACE_STATUS_NAME)176 @dbus.service.signal(DBUS_IFACE_STATUS_NAME)
209 def DownloadStarted(self, path):177 def DownloadStarted(self, path):
210 """Fire a signal to notify that a download has started."""178 """Fire a signal to notify that a download has started."""
211179
=== modified file 'ubuntuone/platform/ipc/perspective_broker.py'
--- ubuntuone/platform/ipc/perspective_broker.py 2016-09-17 01:06:23 +0000
+++ ubuntuone/platform/ipc/perspective_broker.py 2018-04-24 23:14:39 +0000
@@ -1,6 +1,7 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2#2#
3# Copyright 2011-2012 Canonical Ltd.3# Copyright 2011-2012 Canonical Ltd.
4# Copyright 2015-2018 Chicharreros (https://launchpad.net/~chicharreros)
4#5#
5# This program is free software: you can redistribute it and/or modify it6# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published7# under the terms of the GNU General Public License version 3, as published
@@ -235,7 +236,6 @@
235 'waiting',236 'waiting',
236 'waiting_metadata',237 'waiting_metadata',
237 'waiting_content',238 'waiting_content',
238 'sync_menu',
239 ]239 ]
240240
241 signal_mapping = {241 signal_mapping = {
@@ -296,10 +296,6 @@
296 warnings.warn('Use "waiting" method instead.', DeprecationWarning)296 warnings.warn('Use "waiting" method instead.', DeprecationWarning)
297 return self.service.status.waiting_content()297 return self.service.status.waiting_content()
298298
299 def sync_menu(self):
300 """Return the info necessary to construct the menu."""
301 return self.service.status.sync_menu()
302
303 @signal299 @signal
304 def DownloadStarted(self, path):300 def DownloadStarted(self, path):
305 """Fire a signal to notify that a download has started."""301 """Fire a signal to notify that a download has started."""
306302
=== removed directory 'ubuntuone/platform/sync_menu'
=== removed file 'ubuntuone/platform/sync_menu/__init__.py'
--- ubuntuone/platform/sync_menu/__init__.py 2012-09-18 16:28:28 +0000
+++ ubuntuone/platform/sync_menu/__init__.py 1970-01-01 00:00:00 +0000
@@ -1,41 +0,0 @@
1# -*- coding: utf-8 *-*
2#
3# Copyright 2012 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16#
17# In addition, as a special exception, the copyright holders give
18# permission to link the code of portions of this program with the
19# OpenSSL library under certain conditions as described in each
20# individual source file, and distribute linked combinations
21# including the two.
22# You must obey the GNU General Public License in all respects
23# for all of the code used other than OpenSSL. If you modify
24# file(s) with this exception, you may extend this exception to your
25# version of the file(s), but you are not obligated to do so. If you
26# do not wish to do so, delete this exception statement from your
27# version. If you delete this exception statement from all source
28# files in the program, then also delete it here.
29"""Use SyncMenu lib to integrate U1 with the Systray Sync Icon."""
30
31import sys
32
33
34if sys.platform in ("win32", "darwin"):
35 from ubuntuone.platform.sync_menu import common
36 source = common
37else:
38 from ubuntuone.platform.sync_menu import linux
39 source = linux
40
41UbuntuOneSyncMenu = source.UbuntuOneSyncMenu
420
=== removed file 'ubuntuone/platform/sync_menu/common.py'
--- ubuntuone/platform/sync_menu/common.py 2013-01-31 22:39:17 +0000
+++ ubuntuone/platform/sync_menu/common.py 1970-01-01 00:00:00 +0000
@@ -1,41 +0,0 @@
1# -*- coding: utf-8 *-*
2#
3# Copyright 2012 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16#
17# In addition, as a special exception, the copyright holders give
18# permission to link the code of portions of this program with the
19# OpenSSL library under certain conditions as described in each
20# individual source file, and distribute linked combinations
21# including the two.
22# You must obey the GNU General Public License in all respects
23# for all of the code used other than OpenSSL. If you modify
24# file(s) with this exception, you may extend this exception to your
25# version of the file(s), but you are not obligated to do so. If you
26# do not wish to do so, delete this exception statement from your
27# version. If you delete this exception statement from all source
28# files in the program, then also delete it here.
29"""Dummy implementation of sync_menu lib for win32 and darwin."""
30
31
32class UbuntuOneSyncMenu(object):
33 """Integrate U1 with the Ubuntu Sync Menu."""
34 def __init__(self, *args, **kwargs):
35 """Match #args of linux syncmenu and do nothing."""
36
37 def update_transfers(self, *args, **kwargs):
38 """Do nothing."""
39
40 def sync_status_changed(self, *args, **kwargs):
41 """Do nothing."""
420
=== removed file 'ubuntuone/platform/sync_menu/linux.py'
--- ubuntuone/platform/sync_menu/linux.py 2018-03-08 19:39:13 +0000
+++ ubuntuone/platform/sync_menu/linux.py 1970-01-01 00:00:00 +0000
@@ -1,330 +0,0 @@
1# -*- coding: utf-8 *-*
2#
3# Copyright 2012-2013 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16#
17# In addition, as a special exception, the copyright holders give
18# permission to link the code of portions of this program with the
19# OpenSSL library under certain conditions as described in each
20# individual source file, and distribute linked combinations
21# including the two.
22# You must obey the GNU General Public License in all respects
23# for all of the code used other than OpenSSL. If you modify
24# file(s) with this exception, you may extend this exception to your
25# version of the file(s), but you are not obligated to do so. If you
26# do not wish to do so, delete this exception statement from your
27# version. If you delete this exception statement from all source
28# files in the program, then also delete it here.
29"""Use SyncMenu lib to integrate U1 with the Systray Sync Icon."""
30
31import gettext
32import logging
33import time
34from twisted.python.util import OrderedDict
35from operator import itemgetter
36
37try:
38 from gi.repository import GLib as glib
39 from gi.repository import (
40 Dbusmenu,
41 Gdk,
42 Gio,
43 SyncMenu,
44 )
45 use_syncmenu = True
46except ImportError:
47 use_syncmenu = False
48
49from ubuntuone.clientdefs import GETTEXT_PACKAGE, NAME
50from ubuntuone.platform.sync_menu.common import (
51 UbuntuOneSyncMenu as DummySyncMenu,
52)
53
54
55logger = logging.getLogger("ubuntuone.platform.SyncMenu")
56
57
58def Q_(string):
59 return gettext.dgettext(GETTEXT_PACKAGE, string)
60
61
62GET_HELP = Q_("Get Help on the Web")
63GO_TO_WEB = Q_("Go to the main website")
64MORE_STORAGE = Q_("Get More Space")
65OPEN_U1 = Q_("Open")
66OPEN_U1_FOLDER = Q_("Open the main folder")
67SHARE_A_FILE = Q_("Share a File")
68TRANSFERS = Q_("Current and Recent Transfers")
69
70DELAY_BETWEEN_UPDATES = 3
71UBUNTUONE_LINK = u'https://one.ubuntu.com/'
72DASHBOARD = UBUNTUONE_LINK + u'dashboard/'
73HELP_LINK = UBUNTUONE_LINK + u'support/'
74GET_STORAGE_LINK = UBUNTUONE_LINK + u'services/add-storage/'
75CLIENT_COMMAND_LINE = 'ubuntuone-control-panel-qt'
76CLIENT_DESKTOP_ID = 'ubuntuone-installer.desktop'
77
78
79class UbuntuOneSyncMenuLinux(object):
80 """Integrate U1 with the Ubuntu Sync Menu."""
81
82 def __init__(self, status, syncdaemon_service):
83 """Initialize menu."""
84 self._syncdaemon_service = syncdaemon_service
85 self._connected = True
86 self.timer = None
87 self._ignore_status_event = False
88 self.next_update = time.time()
89 self.root_menu = Dbusmenu.Menuitem()
90
91 self.open_u1 = Dbusmenu.Menuitem()
92 self.open_u1.property_set(Dbusmenu.MENUITEM_PROP_LABEL, OPEN_U1)
93 self.open_u1_folder = Dbusmenu.Menuitem()
94 self.open_u1_folder.property_set(
95 Dbusmenu.MENUITEM_PROP_LABEL, OPEN_U1_FOLDER)
96 self.share_file = Dbusmenu.Menuitem()
97 self.share_file.property_set(
98 Dbusmenu.MENUITEM_PROP_LABEL, SHARE_A_FILE)
99
100 self.go_to_web = Dbusmenu.Menuitem()
101 self.go_to_web.property_set(
102 Dbusmenu.MENUITEM_PROP_LABEL, GO_TO_WEB)
103
104 self.transfers = TransfersMenu(status)
105 self.transfers.property_set(
106 Dbusmenu.MENUITEM_PROP_LABEL, TRANSFERS)
107
108 self.more_storage = Dbusmenu.Menuitem()
109 self.more_storage.property_set(
110 Dbusmenu.MENUITEM_PROP_LABEL, MORE_STORAGE)
111
112 self.get_help = Dbusmenu.Menuitem()
113 self.get_help.property_set(
114 Dbusmenu.MENUITEM_PROP_LABEL, GET_HELP)
115
116 # Connect signals
117 self.open_u1.connect(
118 Dbusmenu.MENUITEM_SIGNAL_ITEM_ACTIVATED, self.open_control_panel)
119 self.open_u1_folder.connect(
120 Dbusmenu.MENUITEM_SIGNAL_ITEM_ACTIVATED,
121 self.open_ubuntu_one_folder)
122 self.share_file.connect(
123 Dbusmenu.MENUITEM_SIGNAL_ITEM_ACTIVATED, self.open_share_file_tab)
124 self.go_to_web.connect(
125 Dbusmenu.MENUITEM_SIGNAL_ITEM_ACTIVATED, self.open_go_to_web)
126 self.get_help.connect(
127 Dbusmenu.MENUITEM_SIGNAL_ITEM_ACTIVATED, self.open_web_help)
128 self.more_storage.connect(
129 Dbusmenu.MENUITEM_SIGNAL_ITEM_ACTIVATED,
130 self.open_get_more_storage)
131
132 # Add items
133 self.root_menu.child_append(self.open_u1)
134 self.root_menu.child_append(self.open_u1_folder)
135 self.root_menu.child_append(self.share_file)
136 self.root_menu.child_append(self.go_to_web)
137 self.root_menu.child_append(self.transfers)
138 self.root_menu.child_append(self.more_storage)
139 self.root_menu.child_append(self.get_help)
140
141 self.server = Dbusmenu.Server()
142 self.server.set_root(self.root_menu)
143 self.app = SyncMenu.App.new(CLIENT_DESKTOP_ID)
144 self.app.set_menu(self.server)
145 self.app.connect("notify::paused", self.change_sync_status)
146
147 def sync_status_changed(self, status):
148 """Listen to the changes for the sync status."""
149 if status != self._connected:
150 self._connected = status
151 self._ignore_status_event = True
152 self.app.set_paused(not self._connected)
153
154 def change_sync_status(self, *args):
155 """Triggered when the sync status is changed fromm the menu."""
156 if self._ignore_status_event:
157 self._ignore_status_event = False
158 elif self._connected:
159 self._syncdaemon_service.disconnect()
160 self._connected = False
161 else:
162 self._syncdaemon_service.connect()
163 self._connected = True
164
165 def _get_launch_context(self, timestamp):
166 """Returns the launch context for the current display"""
167 dpy = Gdk.Display.get_default()
168
169 if dpy:
170 context = dpy.get_app_launch_context()
171 context.set_timestamp(timestamp)
172 return context
173
174 return None
175
176 def _open_uri(self, uri, timestamp=0):
177 """Open an uri Using the default handler and the action timestamp"""
178 try:
179 Gio.AppInfo.launch_default_for_uri(
180 uri, self._get_launch_context(timestamp))
181 except glib.GError as e:
182 logger.warning('Failed to open the uri %s: %s.', uri, e)
183
184 def _open_control_panel_by_command_line(self, timestamp, args=''):
185 """Open the control panel by command line"""
186 flags = Gio.AppInfoCreateFlags.SUPPORTS_STARTUP_NOTIFICATION
187 command_line = CLIENT_COMMAND_LINE
188 if len(args):
189 command_line += ' ' + args
190
191 try:
192 app = Gio.AppInfo.create_from_commandline(
193 command_line, NAME, flags)
194
195 if app:
196 app.launch([], self._get_launch_context(timestamp))
197 except glib.GError as e:
198 logger.warning('Failed to open the control panel: %s.' % e)
199
200 def open_control_panel(self, menuitem=None, timestamp=0):
201 """Open the Control Panel."""
202 app = Gio.DesktopAppInfo.new(CLIENT_DESKTOP_ID)
203
204 if app:
205 try:
206 app.launch([], self._get_launch_context(timestamp))
207 except glib.GError as e:
208 logger.warning('Failed to open the control panel: %s.' % e)
209 else:
210 self._open_control_panel_by_command_line(timestamp)
211
212 def open_ubuntu_one_folder(self, menuitem=None, timestamp=0):
213 """Open the folder."""
214 self._open_uri(
215 "file://" + self._syncdaemon_service.get_rootdir(), timestamp)
216
217 def open_share_file_tab(self, menuitem=None, timestamp=0):
218 """Open the Control Panel in the Share Tab."""
219 self._open_control_panel_by_command_line(
220 timestamp, "--switch-to share_links")
221
222 def open_go_to_web(self, menuitem=None, timestamp=0):
223 """Open the Help Page"""
224 self._open_uri(DASHBOARD, timestamp)
225
226 def open_web_help(self, menuitem=None, timestamp=0):
227 """Open the Help Page"""
228 self._open_uri(HELP_LINK, timestamp)
229
230 def open_get_more_storage(self, menuitem=None, timestamp=0):
231 """Open the Help Page"""
232 self._open_uri(GET_STORAGE_LINK, timestamp)
233
234 def _timeout(self, result):
235 """The aggregating timer has expired, so update the UI."""
236 self.next_update = int(time.time()) + DELAY_BETWEEN_UPDATES
237 self.transfers.update_progress()
238
239 def update_transfers(self):
240 """Set up a timer if there isn't one ticking and update the ui.
241
242 NOOP. Left behind for API compatibility, will be removed later when
243 all interaction with old syncmeny and desktop GUIs go away.
244 """
245
246
247class TransfersMenu(Dbusmenu.Menuitem if use_syncmenu else object):
248 """Menu that handles the recent and current transfers."""
249
250 def __init__(self, status_frontend):
251 super(TransfersMenu, self).__init__()
252 self.status_frontend = status_frontend
253 self.uploading = {}
254 self.previous_transfers = []
255 self._transfers_items = {}
256 self._uploading_items = {}
257 self.separator = None
258
259 def update_progress(self):
260 """Update the list of recent transfers and current transfers."""
261 recent_transfers = self.status_frontend.recent_transfers()
262 current_transfers = self.status_frontend.files_uploading()
263 current_transfers.sort(key=itemgetter(2))
264 current_transfers.reverse()
265 uploading_data = OrderedDict()
266 for filename, size, written in current_transfers:
267 uploading_data[filename] = (size, written)
268
269 temp_transfers = {}
270 if recent_transfers != self.previous_transfers:
271 logger.debug("Update recent transfers with: %r", recent_transfers)
272 for item_transfer in self._transfers_items:
273 self.child_delete(self._transfers_items[item_transfer])
274 for item in recent_transfers:
275 recent_file = Dbusmenu.Menuitem()
276 recent_file.property_set(
277 Dbusmenu.MENUITEM_PROP_LABEL, item.replace('_', '__'))
278 self.child_add_position(recent_file, 0)
279 temp_transfers[item] = recent_file
280 self._transfers_items = temp_transfers
281
282 if self.separator is None:
283 self.separator = Dbusmenu.Menuitem()
284 self.separator.property_set(
285 Dbusmenu.MENUITEM_PROP_TYPE, Dbusmenu.CLIENT_TYPES_SEPARATOR)
286 self.child_append(self.separator)
287
288 items_added = 0
289 remove = []
290 for item in self._uploading_items:
291 if item in uploading_data.keys():
292 size, written = uploading_data[item]
293 percentage = written * 100 / size
294 upload_item = self._uploading_items[item]
295 upload_item.property_set_int(
296 SyncMenu.PROGRESS_MENUITEM_PROP_PERCENT_DONE,
297 percentage)
298 logger.debug(
299 "Current transfer %s progress update: %r",
300 item, percentage)
301 items_added += 1
302 else:
303 self.child_delete(self._uploading_items[item])
304 remove.append(item)
305 for item in remove:
306 self._uploading_items.pop(item)
307 if items_added < 5:
308 for item in uploading_data.keys():
309 if item not in self._uploading_items and items_added < 5:
310 size, written = uploading_data[item]
311 percentage = written * 100 / size
312 uploading_file = Dbusmenu.Menuitem()
313 uploading_file.property_set(
314 Dbusmenu.MENUITEM_PROP_LABEL, item.replace('_', '__'))
315 uploading_file.property_set(
316 Dbusmenu.MENUITEM_PROP_TYPE,
317 SyncMenu.PROGRESS_MENUITEM_TYPE)
318 uploading_file.property_set_int(
319 SyncMenu.PROGRESS_MENUITEM_PROP_PERCENT_DONE,
320 percentage)
321 logger.debug("Current transfer %s created", item)
322 self.child_append(uploading_file)
323 self._uploading_items[item] = uploading_file
324 items_added += 1
325
326
327if use_syncmenu:
328 UbuntuOneSyncMenu = UbuntuOneSyncMenuLinux
329else:
330 UbuntuOneSyncMenu = DummySyncMenu
3310
=== modified file 'ubuntuone/platform/tests/ipc/test_external_interface.py'
--- ubuntuone/platform/tests/ipc/test_external_interface.py 2016-09-17 01:06:23 +0000
+++ ubuntuone/platform/tests/ipc/test_external_interface.py 2018-04-24 23:14:39 +0000
@@ -1,6 +1,7 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2#2#
3# Copyright 2011-2012 Canonical Ltd.3# Copyright 2011-2012 Canonical Ltd.
4# Copyright 2015-2018 Chicharreros (https://launchpad.net/~chicharreros)
4#5#
5# This program is free software: you can redistribute it and/or modify it6# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published7# under the terms of the GNU General Public License version 3, as published
@@ -40,10 +41,6 @@
40 StatusTestCase,41 StatusTestCase,
41 SyncDaemonTestCase,42 SyncDaemonTestCase,
42)43)
43from ubuntuone.syncdaemon import (
44 RECENT_TRANSFERS,
45 UPLOADING,
46)
4744
48STR = 'something'45STR = 'something'
49STR_STR_DICT = {'foo': 'bar'}46STR_STR_DICT = {'foo': 'bar'}
@@ -68,7 +65,7 @@
68 ('ContentQueueChanged', ()),65 ('ContentQueueChanged', ()),
69 ('MetaQueueChanged', ()),66 ('MetaQueueChanged', ()),
70 ('RequestQueueAdded', (STR, STR, STR_STR_DICT)),67 ('RequestQueueAdded', (STR, STR, STR_STR_DICT)),
71 ('RequestQueueRemoved', (STR, STR, STR_STR_DICT)),68 ('RequestQueueRemoved', (STR, STR, STR_STR_DICT)),
72 ]69 ]
7370
74 @defer.inlineCallbacks71 @defer.inlineCallbacks
@@ -136,16 +133,6 @@
136 self.assert_remote_method(133 self.assert_remote_method(
137 'waiting_metadata', in_signature=None, out_signature='a(sa{ss})')134 'waiting_metadata', in_signature=None, out_signature='a(sa{ss})')
138135
139 @defer.inlineCallbacks
140 def test_sync_menu(self):
141 """Test sync_menu."""
142 result = {RECENT_TRANSFERS: [], UPLOADING: []}
143 method = 'sync_menu'
144 yield self.assert_method_called(self.service.status,
145 method, result)
146 self.assert_remote_method(
147 method, in_signature=None, out_signature='a{sv}')
148
149136
150class EventsTests(EventsTestCase):137class EventsTests(EventsTestCase):
151 """Basic tests for the Events exposed object."""138 """Basic tests for the Events exposed object."""
152139
=== removed directory 'ubuntuone/platform/tests/sync_menu'
=== removed file 'ubuntuone/platform/tests/sync_menu/__init__.py'
--- ubuntuone/platform/tests/sync_menu/__init__.py 2012-09-18 16:22:15 +0000
+++ ubuntuone/platform/tests/sync_menu/__init__.py 1970-01-01 00:00:00 +0000
@@ -1,27 +0,0 @@
1# Copyright 2012 Canonical Ltd.
2#
3# This program is free software: you can redistribute it and/or modify it
4# under the terms of the GNU General Public License version 3, as published
5# by the Free Software Foundation.
6#
7# This program is distributed in the hope that it will be useful, but
8# WITHOUT ANY WARRANTY; without even the implied warranties of
9# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
10# PURPOSE. See the GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License along
13# with this program. If not, see <http://www.gnu.org/licenses/>.
14#
15# In addition, as a special exception, the copyright holders give
16# permission to link the code of portions of this program with the
17# OpenSSL library under certain conditions as described in each
18# individual source file, and distribute linked combinations
19# including the two.
20# You must obey the GNU General Public License in all respects
21# for all of the code used other than OpenSSL. If you modify
22# file(s) with this exception, you may extend this exception to your
23# version of the file(s), but you are not obligated to do so. If you
24# do not wish to do so, delete this exception statement from your
25# version. If you delete this exception statement from all source
26# files in the program, then also delete it here.
27"""SyncMenu test code."""
280
=== removed file 'ubuntuone/platform/tests/sync_menu/test_common.py'
--- ubuntuone/platform/tests/sync_menu/test_common.py 2012-10-15 21:20:54 +0000
+++ ubuntuone/platform/tests/sync_menu/test_common.py 1970-01-01 00:00:00 +0000
@@ -1,54 +0,0 @@
1# -*- coding: utf-8 *-*
2#
3# Copyright 2012 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16#
17# In addition, as a special exception, the copyright holders give
18# permission to link the code of portions of this program with the
19# OpenSSL library under certain conditions as described in each
20# individual source file, and distribute linked combinations
21# including the two.
22# You must obey the GNU General Public License in all respects
23# for all of the code used other than OpenSSL. If you modify
24# file(s) with this exception, you may extend this exception to your
25# version of the file(s), but you are not obligated to do so. If you
26# do not wish to do so, delete this exception statement from your
27# version. If you delete this exception statement from all source
28# files in the program, then also delete it here.
29"""Test the common dummy Sync Menu implementation for win32/darwin."""
30
31from collections import Callable
32
33from twisted.trial.unittest import TestCase
34
35from ubuntuone.platform.sync_menu import common
36
37
38class SyncMenuDummyTestCase(TestCase):
39 """Test the SyncMenu."""
40
41 def test_dummy_support(self):
42 """Can we create a Dummy with the same #args as the real obj."""
43 dummy = common.UbuntuOneSyncMenu(1, 2)
44 self.assertIsInstance(dummy, common.UbuntuOneSyncMenu)
45
46 def test_dummy_has_update_transfers(self):
47 """Check that the dummy has the proper methods required by the API."""
48 dummy = common.UbuntuOneSyncMenu(1, 2)
49 self.assertIsInstance(dummy.update_transfers, Callable)
50
51 def test_dummy_has_sync_status_changed(self):
52 """Check that the dummy has the proper methods required by the API."""
53 dummy = common.UbuntuOneSyncMenu(1, 2)
54 self.assertIsInstance(dummy.sync_status_changed, Callable)
550
=== removed file 'ubuntuone/platform/tests/sync_menu/test_linux.py'
--- ubuntuone/platform/tests/sync_menu/test_linux.py 2016-09-17 01:06:23 +0000
+++ ubuntuone/platform/tests/sync_menu/test_linux.py 1970-01-01 00:00:00 +0000
@@ -1,586 +0,0 @@
1# -*- coding: utf-8 *-*
2#
3# Copyright 2012 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16#
17# In addition, as a special exception, the copyright holders give
18# permission to link the code of portions of this program with the
19# OpenSSL library under certain conditions as described in each
20# individual source file, and distribute linked combinations
21# including the two.
22# You must obey the GNU General Public License in all respects
23# for all of the code used other than OpenSSL. If you modify
24# file(s) with this exception, you may extend this exception to your
25# version of the file(s), but you are not obligated to do so. If you
26# do not wish to do so, delete this exception statement from your
27# version. If you delete this exception statement from all source
28# files in the program, then also delete it here.
29"""Test the Sync Menu."""
30
31import time
32from collections import Callable
33
34from twisted.internet import defer
35from twisted.trial.unittest import TestCase
36
37from ubuntuone.platform import sync_menu
38from ubuntuone.platform.sync_menu import linux
39
40
41def fake_call_later(*args):
42 """Fake reactor.callLater."""
43
44
45class FakeStatusFrontend(object):
46 """Fake StatusFrontend."""
47
48 def __init__(self):
49 self.recent_transfers_data = []
50 self.uploading_data = []
51
52 def recent_transfers(self):
53 """Return the fake recent transfers files."""
54 return self.recent_transfers_data
55
56 def files_uploading(self):
57 """Return the fake files being upload."""
58 return self.uploading_data
59
60
61class FakeAppLaunchContext(object):
62 def set_timestamp(self, timestamp):
63 self.timestamp = timestamp
64
65
66class FakeGdkDisplay(object):
67 """Fake Gdk.Display"""
68 def get_app_launch_context(self):
69 return FakeAppLaunchContext()
70
71
72class FakeNullGdk(object):
73 """Fake Gdk.Display with no default"""
74 @staticmethod
75 def get_default():
76 return None
77
78
79class FakeAppInfo(object):
80 """Fake Gio.AppInfo"""
81 instance = None
82 name = ""
83 desktop_id = ""
84 command_line = ""
85 opened_uri = ""
86 launched = True
87 context = None
88 files = []
89 flags = 0
90
91 def __new__(cls, *args, **kwargs):
92 cls.instance = super(FakeAppInfo, cls).__new__(cls, *args, **kwargs)
93 return cls.instance
94
95 def __init__(self, command_line="", name="", flags=0):
96 self.command_line = command_line
97 self.name = name
98 self.flags = flags
99
100 @classmethod
101 def launch_default_for_uri(cls, uri, context):
102 cls.opened_uri = uri
103 cls.context = context
104
105 @classmethod
106 def create_from_commandline(cls, command_line, name, flags):
107 cls.instance.__init__(command_line, name, flags)
108 return cls.instance
109
110 def launch(self, files, context):
111 self.launched = True
112 self.files = files
113 self.context = context
114
115
116class FakeDesktopAppInfo(FakeAppInfo):
117 """Fake Gio.DestkopAppInfo"""
118 def __init__(self, desktop_id=""):
119 super(FakeDesktopAppInfo, self).__init__()
120 self.desktop_id = desktop_id
121
122 @classmethod
123 def new(cls, desktop_id):
124 cls.instance.__init__(desktop_id)
125 return cls.instance
126
127
128class FakeSyncdaemonService(object):
129 """Fake SyncdaemonService."""
130
131 def __init__(self):
132 self.connect_called = False
133 self.disconnect_called = False
134 self.fake_root_path = "/home/user/Magicicada"
135
136 def connect(self):
137 """Set connect to True."""
138 self.connect_called = True
139
140 def disconnect(self):
141 """Set connect to True."""
142 self.disconnect_called = True
143
144 def get_rootdir(self):
145 """Return a fake ubuntu one folder path."""
146 return self.fake_root_path
147
148
149class FakeSyncMenuApp(object):
150 """Fake SyncMenu."""
151
152 data = {}
153
154 @classmethod
155 def new(cls, *args):
156 return FakeSyncMenuApp()
157
158 @classmethod
159 def clean(cls):
160 """Clear the values stored in data."""
161 FakeSyncMenuApp.data = {}
162
163 def set_menu(self, server):
164 """Set the menu for SyncMenu App."""
165 self.data['server'] = server
166
167 def connect(self, signal, callback):
168 """Fake connect."""
169 self.data['connect'] = (signal, callback)
170
171 def set_paused(self, status):
172 """Set the pause state."""
173 self.data['paused'] = status
174
175
176class SyncMenuDummyTestCase(TestCase):
177 """Test the SyncMenu."""
178
179 def test_dummy_support(self):
180 """Check that the Dummy object can be created properly."""
181 dummy = linux.DummySyncMenu('random', 'args')
182 self.assertIsInstance(dummy, linux.DummySyncMenu)
183
184 def test_dummy_has_update_transfers(self):
185 """Check that the dummy has the proper methods required by the API."""
186 dummy = linux.DummySyncMenu('random', 'args')
187 self.assertIsInstance(dummy.update_transfers, Callable)
188 self.assertIsInstance(dummy.sync_status_changed, Callable)
189
190
191class SyncMenuTestCase(TestCase):
192 """Test the SyncMenu."""
193
194 skip = None if linux.use_syncmenu else "SyncMenu not installed."
195
196 @defer.inlineCallbacks
197 def setUp(self):
198 yield super(SyncMenuTestCase, self).setUp()
199 self.patch(linux.SyncMenu, "App", FakeSyncMenuApp)
200 self.patch(linux.Gdk.Display, "get_default", FakeGdkDisplay)
201 FakeSyncMenuApp.clean()
202 self.syncdaemon_service = FakeSyncdaemonService()
203 self.status_frontend = FakeStatusFrontend()
204 self._paused = False
205 self.sync_menu = sync_menu.UbuntuOneSyncMenu(
206 self.status_frontend, self.syncdaemon_service)
207
208 def test_init(self):
209 """Check that the menu is properly initialized."""
210 self.assertIsInstance(
211 FakeSyncMenuApp.data['server'], linux.Dbusmenu.Server)
212 self.assertEqual(
213 self.sync_menu.open_u1.get_parent(), self.sync_menu.root_menu)
214 self.assertEqual(
215 self.sync_menu.go_to_web.get_parent(), self.sync_menu.root_menu)
216 self.assertEqual(
217 self.sync_menu.more_storage.get_parent(), self.sync_menu.root_menu)
218 self.assertEqual(
219 self.sync_menu.get_help.get_parent(), self.sync_menu.root_menu)
220 self.assertEqual(
221 self.sync_menu.transfers.get_parent(), self.sync_menu.root_menu)
222 self.assertEqual(
223 self.sync_menu.open_u1_folder.get_parent(),
224 self.sync_menu.root_menu)
225 self.assertEqual(
226 self.sync_menu.share_file.get_parent(), self.sync_menu.root_menu)
227
228 def get_prop(item):
229 return item.property_get(linux.Dbusmenu.MENUITEM_PROP_LABEL)
230
231 self.assertEqual(
232 get_prop(self.sync_menu.open_u1), linux.OPEN_U1)
233 self.assertEqual(
234 get_prop(self.sync_menu.open_u1_folder), linux.OPEN_U1_FOLDER)
235 self.assertEqual(
236 get_prop(self.sync_menu.share_file), linux.SHARE_A_FILE)
237 self.assertEqual(
238 get_prop(self.sync_menu.go_to_web), linux.GO_TO_WEB)
239 self.assertEqual(
240 get_prop(self.sync_menu.transfers), linux.TRANSFERS)
241 self.assertEqual(
242 get_prop(self.sync_menu.more_storage), linux.MORE_STORAGE)
243 self.assertEqual(
244 get_prop(self.sync_menu.get_help), linux.GET_HELP)
245
246 self.sync_menu.transfers.update_progress()
247 self.assertIsInstance(
248 self.sync_menu.transfers.separator, linux.Dbusmenu.Menuitem)
249
250 def test_get_launch_context_with_display(self):
251 """Check that the proper context is returned."""
252 timestamp = time.time()
253 context = self.sync_menu._get_launch_context(timestamp)
254 self.assertEqual(timestamp, context.timestamp)
255
256 def test_get_launch_context_with_no_display(self):
257 """Check that the proper context is returned."""
258 self.patch(linux.Gdk, "Display", FakeNullGdk)
259 context = self.sync_menu._get_launch_context(time.time())
260 self.assertEqual(context, None)
261
262 def test_open_control_panel_by_command_line(self):
263 """Check that the proper action is executed."""
264 appinfo = FakeAppInfo()
265 self.patch(linux.Gio, "AppInfo", appinfo)
266 timestamp = time.time()
267 self.sync_menu._open_control_panel_by_command_line(timestamp)
268
269 self.assertEqual(appinfo.command_line, linux.CLIENT_COMMAND_LINE)
270 self.assertEqual(appinfo.context.timestamp, timestamp)
271
272 def test_open_control_panel_by_command_line_with_arg(self):
273 """Check that the proper action is executed."""
274 appinfo = FakeAppInfo()
275 self.patch(linux.Gio, "AppInfo", appinfo)
276 timestamp = time.time()
277 arg = "--test-arg"
278 self.sync_menu._open_control_panel_by_command_line(timestamp, arg)
279
280 self.assertEqual(
281 appinfo.command_line, "%s %s" % (linux.CLIENT_COMMAND_LINE, arg))
282 self.assertEqual(appinfo.context.timestamp, timestamp)
283
284 def test_open_uri(self):
285 """Check that the proper action is executed."""
286 appinfo = FakeAppInfo()
287 self.patch(linux.Gio, "AppInfo", appinfo)
288 timestamp = time.time()
289
290 self.sync_menu._open_uri(linux.UBUNTUONE_LINK, timestamp)
291 self.assertEqual(appinfo.opened_uri, linux.UBUNTUONE_LINK)
292 self.assertEqual(appinfo.context.timestamp, timestamp)
293
294 def test_open_u1(self):
295 """Check that the proper action is executed."""
296 appinfo = FakeDesktopAppInfo()
297 timestamp = time.time()
298 self.patch(linux.Gio, "DesktopAppInfo", appinfo)
299
300 self.sync_menu.open_control_panel(timestamp=timestamp)
301 self.assertEqual(appinfo.desktop_id, linux.CLIENT_DESKTOP_ID)
302 self.assertTrue(appinfo.launched)
303 self.assertEqual(appinfo.files, [])
304 self.assertEqual(appinfo.context.timestamp, timestamp)
305
306 def test_open_share_tab(self):
307 """Check that the proper action is executed."""
308 timestamp = time.time()
309 data = []
310
311 self.patch(
312 self.sync_menu, "_open_control_panel_by_command_line",
313 lambda t, a: data.append((t, a)))
314 self.sync_menu.open_share_file_tab(timestamp=timestamp)
315 self.assertEqual(data, [(timestamp, "--switch-to share_links")])
316
317 def test_go_to_web(self):
318 """Check that the proper action is executed."""
319 timestamp = time.time()
320 data = []
321
322 self.patch(
323 self.sync_menu, "_open_uri", lambda u, t: data.append((t, u)))
324 self.sync_menu.open_go_to_web(timestamp=timestamp)
325 self.assertEqual(data, [(timestamp, linux.DASHBOARD)])
326
327 def test_open_ubuntu_one_folder(self):
328 """Check that the proper action is executed."""
329 timestamp = time.time()
330 data = []
331
332 self.patch(
333 self.sync_menu, "_open_uri", lambda u, t: data.append((t, u)))
334 self.sync_menu.open_ubuntu_one_folder(timestamp=timestamp)
335 self.assertEqual(
336 data,
337 [(timestamp, "file://" + self.syncdaemon_service.fake_root_path)])
338
339 def test_get_help(self):
340 """Check that the proper action is executed."""
341 timestamp = time.time()
342 data = []
343
344 self.patch(
345 self.sync_menu, "_open_uri", lambda u, t: data.append((t, u)))
346 self.sync_menu.open_web_help(timestamp=timestamp)
347 self.assertEqual(data, [(timestamp, linux.HELP_LINK)])
348
349 def test_more_storage(self):
350 """Check that the proper action is executed."""
351 timestamp = time.time()
352 data = []
353
354 self.patch(
355 self.sync_menu, "_open_uri", lambda u, t: data.append((t, u)))
356 self.sync_menu.open_get_more_storage(timestamp=timestamp)
357 self.assertEqual(data, [(timestamp, linux.GET_STORAGE_LINK)])
358
359 def test_empty_transfers(self):
360 """Check that the Transfers menu is empty."""
361 self.assertEqual(self.sync_menu.transfers.get_children(), [])
362
363 def test_only_recent(self):
364 """Check that only recent transfers items are loaded."""
365 data = ['file1', 'file2', 'file3']
366 self.status_frontend.recent_transfers_data = data
367 self.sync_menu.transfers.update_progress()
368 children = self.sync_menu.transfers.get_children()
369 self.assertEqual(len(children), 4)
370 data.reverse()
371 for itemM, itemD in zip(children, data):
372 self.assertEqual(
373 itemM.property_get(linux.Dbusmenu.MENUITEM_PROP_LABEL), itemD)
374
375 def test_only_progress(self):
376 """Check that only progress items are loaded."""
377 data = [
378 ('file1', 3000, 400),
379 ('file2', 2000, 100),
380 ('file3', 5000, 4600)]
381 uploading_data = {}
382 for filename, size, written in data:
383 uploading_data[filename] = (size, written)
384 self.status_frontend.uploading_data = data
385 self.sync_menu.transfers.update_progress()
386 children = self.sync_menu.transfers.get_children()
387 self.assertEqual(len(children), 4)
388 data.reverse()
389 for item in children:
390 text = item.property_get(linux.Dbusmenu.MENUITEM_PROP_LABEL)
391 if text is None:
392 continue
393 self.assertIn(text, uploading_data)
394 size, written = uploading_data[text]
395 percentage = written * 100 / size
396 self.assertEqual(item.property_get_int(
397 linux.SyncMenu.PROGRESS_MENUITEM_PROP_PERCENT_DONE),
398 percentage)
399
400 def test_full_transfers(self):
401 """Check that the transfers menu contains the maximum transfers."""
402 # The api of recent transfers always returns a maximum of 5 items
403 data_recent = ['file1', 'file2', 'file3', 'file4', 'file5']
404 self.status_frontend.recent_transfers_data = \
405 data_recent
406 self.sync_menu.transfers.update_progress()
407 children = self.sync_menu.transfers.get_children()
408 self.assertEqual(len(children), 6)
409 data_recent.reverse()
410 for itemM, itemD in zip(children, data_recent):
411 self.assertEqual(itemM.property_get(
412 linux.Dbusmenu.MENUITEM_PROP_LABEL), itemD)
413
414 data_current = [
415 ('file0', 1200, 600),
416 ('file1', 3000, 400),
417 ('file2', 2000, 100),
418 ('file3', 2500, 150),
419 ('file4', 1000, 600),
420 ('file5', 5000, 4600)]
421 uploading_data = {}
422 for filename, size, written in data_current:
423 uploading_data[filename] = (size, written)
424 self.status_frontend.uploading_data = data_current
425 self.sync_menu.transfers.update_progress()
426 children = self.sync_menu.transfers.get_children()
427 # The menu should only show 5 current transfers.
428 self.assertEqual(len(children), 11)
429 data_current.reverse()
430 for item in children[6:]:
431 text = item.property_get(linux.Dbusmenu.MENUITEM_PROP_LABEL)
432 self.assertIn(text, uploading_data)
433 size, written = uploading_data[text]
434 percentage = written * 100 / size
435 self.assertEqual(item.property_get_int(
436 linux.SyncMenu.PROGRESS_MENUITEM_PROP_PERCENT_DONE),
437 percentage)
438
439 def test_mnemonics_labels(self):
440 """Check that the transfers menu sanitizes the underscores."""
441 data_recent = ['file_1', 'file__2']
442 self.status_frontend.recent_transfers_data = \
443 data_recent
444 self.sync_menu.transfers.update_progress()
445 children = self.sync_menu.transfers.get_children()
446 data_recent.reverse()
447 for itemM, itemD in zip(children, data_recent):
448 self.assertEqual(itemM.property_get(
449 linux.Dbusmenu.MENUITEM_PROP_LABEL), itemD.replace('_', '__'))
450
451 def test_update_transfers(self):
452 """Check that everything is ok when updating the transfers value."""
453 data_current = [
454 ('file0', 1200, 600),
455 ('file1', 3000, 400),
456 ('file4', 1000, 600),
457 ('file5', 5000, 4600)]
458 uploading_data = {}
459 for filename, size, written in data_current:
460 uploading_data[filename] = (size, written)
461 self.status_frontend.uploading_data = data_current
462 self.sync_menu.transfers.update_progress()
463 children = self.sync_menu.transfers.get_children()
464 # The menu should only show 5 current transfers.
465 self.assertEqual(len(children), 5)
466 data_current.reverse()
467 for item in children:
468 text = item.property_get(linux.Dbusmenu.MENUITEM_PROP_LABEL)
469 if text is None:
470 continue
471 self.assertIn(text, uploading_data)
472 size, written = uploading_data[text]
473 percentage = written * 100 / size
474 self.assertEqual(item.property_get_int(
475 linux.SyncMenu.PROGRESS_MENUITEM_PROP_PERCENT_DONE),
476 percentage)
477
478 data_recent = ['file5']
479 self.status_frontend.recent_transfers_data = data_recent
480 self.sync_menu.transfers.update_progress()
481 children = self.sync_menu.transfers.get_children()
482 self.assertEqual(len(children), 6)
483 data_recent.reverse()
484 for itemM, itemD in zip(children, data_recent):
485 self.assertEqual(itemM.property_get(
486 linux.Dbusmenu.MENUITEM_PROP_LABEL), itemD)
487
488 data_current = [
489 ('file0', 1200, 700),
490 ('file1', 3000, 600),
491 ('file4', 1000, 800)]
492 uploading_data = {}
493 for filename, size, written in data_current:
494 uploading_data[filename] = (size, written)
495 self.status_frontend.uploading_data = data_current
496 self.sync_menu.transfers.update_progress()
497 children = self.sync_menu.transfers.get_children()
498 # The menu should only show 5 current transfers.
499 self.assertEqual(len(children), 5)
500 data_current.reverse()
501 for item in children[6:]:
502 text = item.property_get(linux.Dbusmenu.MENUITEM_PROP_LABEL)
503 self.assertIn(text, uploading_data)
504 size, written = uploading_data[text]
505 percentage = written * 100 / size
506 self.assertEqual(item.property_get_int(
507 linux.SyncMenu.PROGRESS_MENUITEM_PROP_PERCENT_DONE),
508 percentage)
509
510 def test_transfers_order(self):
511 """Check that the proper transfers are shown first."""
512 data_current = [
513 ('file0', 1200, 610),
514 ('file1', 3000, 400),
515 ('file2', 2000, 100),
516 ('file3', 2500, 150),
517 ('file4', 2500, 950),
518 ('file5', 3500, 550),
519 ('file6', 1000, 600),
520 ('file7', 5000, 4600)]
521 expected = [
522 ('file7', 5000, 4600),
523 ('file4', 2500, 950),
524 ('file0', 1200, 610),
525 ('file6', 1000, 600),
526 ('file5', 3500, 550)]
527 self.status_frontend.uploading_data = data_current
528 self.sync_menu.transfers.update_progress()
529 children = self.sync_menu.transfers.get_children()
530 # The menu should only show 5 current transfers and a separator item.
531 self.assertEqual(len(children), 6)
532 i = 0
533 for item in children:
534 text = item.property_get(linux.Dbusmenu.MENUITEM_PROP_LABEL)
535 if text is None:
536 continue
537 percentage = item.property_get_int(
538 linux.SyncMenu.PROGRESS_MENUITEM_PROP_PERCENT_DONE)
539 name, size, written = expected[i]
540 i += 1
541 percentage_expected = written * 100 / size
542 self.assertEqual(text, name)
543 self.assertEqual(percentage, percentage_expected)
544
545 def test_update_transfers_delay(self):
546 """Check that the timer is being handle properly."""
547 self.sync_menu.next_update = time.time()
548 self.sync_menu.update_transfers()
549 self.sync_menu.timer = None
550 self.sync_menu.next_update = time.time() * 2
551 self.sync_menu.update_transfers()
552 self.assertEqual(self.sync_menu.timer.delay, 3)
553
554 def test_status_change_from_menu(self):
555 """Check the behavior when the status is changed from the menu."""
556 self.sync_menu.change_sync_status()
557 self.assertFalse(self.sync_menu._connected)
558 self.assertFalse(self.sync_menu._ignore_status_event)
559 self.assertFalse(self.sync_menu._syncdaemon_service.connect_called)
560 self.assertTrue(self.sync_menu._syncdaemon_service.disconnect_called)
561
562 self.sync_menu._syncdaemon_service.disconnect_called = False
563 self.sync_menu.change_sync_status()
564 self.assertTrue(self.sync_menu._connected)
565 self.assertFalse(self.sync_menu._ignore_status_event)
566 self.assertTrue(self.sync_menu._syncdaemon_service.connect_called)
567 self.assertFalse(self.sync_menu._syncdaemon_service.disconnect_called)
568
569 def test_ignore_status(self):
570 """Check that neither connect or disconnect are called."""
571 self.sync_menu._ignore_status_event = True
572 self.assertTrue(self.sync_menu._ignore_status_event)
573 self.sync_menu.change_sync_status()
574 self.assertTrue(self.sync_menu._connected)
575 self.assertFalse(self.sync_menu._ignore_status_event)
576 self.assertFalse(self.sync_menu._syncdaemon_service.connect_called)
577 self.assertFalse(self.sync_menu._syncdaemon_service.disconnect_called)
578
579 def test_sync_status_changed(self):
580 """Check sync_status_changed behavior."""
581 self.sync_menu.sync_status_changed(True)
582 self.assertNotIn('paused', self.sync_menu.app.data)
583 self.sync_menu.sync_status_changed(False)
584 self.assertFalse(self.sync_menu._connected)
585 self.assertTrue(self.sync_menu._ignore_status_event)
586 self.assertTrue(self.sync_menu.app.data['paused'])
5870
=== modified file 'ubuntuone/platform/tests/test_tools.py'
--- ubuntuone/platform/tests/test_tools.py 2016-09-17 01:06:23 +0000
+++ ubuntuone/platform/tests/test_tools.py 2018-04-24 23:14:39 +0000
@@ -1,6 +1,7 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2#2#
3# Copyright 2009-2012 Canonical Ltd.3# Copyright 2009-2012 Canonical Ltd.
4# Copyright 2015-2018 Chicharreros (https://launchpad.net/~chicharreros)
4#5#
5# This program is free software: you can redistribute it and/or modify it6# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published7# under the terms of the GNU General Public License version 3, as published
@@ -44,8 +45,6 @@
44 interaction_interfaces,45 interaction_interfaces,
45 states,46 states,
46 volume_manager,47 volume_manager,
47 RECENT_TRANSFERS,
48 UPLOADING,
49)48)
50from ubuntuone.platform import tools49from ubuntuone.platform import tools
51from ubuntuone.platform.tests import IPCTestCase50from ubuntuone.platform.tests import IPCTestCase
@@ -253,13 +252,6 @@
253 self.assertEqual('share_id', result['volume_id'])252 self.assertEqual('share_id', result['volume_id'])
254 self.assertEqual(False, self.main.vm.shares['share_id'].accepted)253 self.assertEqual(False, self.main.vm.shares['share_id'].accepted)
255254
256 @defer.inlineCallbacks
257 def test_sync_menu(self):
258 """Test accept_share method."""
259 result = yield self.tool.sync_menu()
260 self.assertIn(RECENT_TRANSFERS, result)
261 self.assertIn(UPLOADING, result)
262
263255
264class TestWaitForSignals(TestToolsBase):256class TestWaitForSignals(TestToolsBase):
265 """Test case for the wait_for_signals method from SyncDaemonTool."""257 """Test case for the wait_for_signals method from SyncDaemonTool."""
@@ -496,8 +488,8 @@
496 """Test SyncDaemonTool.waiting_metadata."""488 """Test SyncDaemonTool.waiting_metadata."""
497 # inject the fake data489 # inject the fake data
498 self.action_q.queue.waiting.extend([490 self.action_q.queue.waiting.extend([
499 FakeCommand("node_a_foo", "node_a_bar", path='path'),491 FakeCommand("node_a_foo", "node_a_bar", path='path'),
500 FakeCommand("node_b_foo", "node_b_bar")])492 FakeCommand("node_b_foo", "node_b_bar")])
501 result = yield self.tool.waiting_metadata()493 result = yield self.tool.waiting_metadata()
502494
503 self.assertEqual(2, len(result))495 self.assertEqual(2, len(result))
@@ -521,8 +513,8 @@
521513
522 # inject the fake data514 # inject the fake data
523 self.action_q.queue.waiting.extend([515 self.action_q.queue.waiting.extend([
524 FakeContentCommand("", "node_id", path='/some/path'),516 FakeContentCommand("", "node_id", path='/some/path'),
525 FakeContentCommand("", "node_id_1", path='/other/path')])517 FakeContentCommand("", "node_id_1", path='/other/path')])
526518
527 result = yield self.tool.waiting_content()519 result = yield self.tool.waiting_content()
528520
529521
=== modified file 'ubuntuone/platform/tools/__init__.py'
--- ubuntuone/platform/tools/__init__.py 2018-03-08 19:39:13 +0000
+++ ubuntuone/platform/tools/__init__.py 2018-04-24 23:14:39 +0000
@@ -1,6 +1,7 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2#2#
3# Copyright 2009-2012 Canonical Ltd.3# Copyright 2009-2012 Canonical Ltd.
4# Copyright 2015-2018 Chicharreros (https://launchpad.net/~chicharreros)
4#5#
5# This program is free software: you can redistribute it and/or modify it6# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published7# under the terms of the GNU General Public License version 3, as published
@@ -269,13 +270,6 @@
269270
270 @defer.inlineCallbacks271 @defer.inlineCallbacks
271 @log_call(logger.debug)272 @log_call(logger.debug)
272 def sync_menu(self):
273 """Return a deferred that will be fired with the sync menu data."""
274 results = yield self.proxy.call_method('status', 'sync_menu')
275 defer.returnValue(results)
276
277 @defer.inlineCallbacks
278 @log_call(logger.debug)
279 def accept_share(self, share_id):273 def accept_share(self, share_id):
280 """Accept the share with id: share_id."""274 """Accept the share with id: share_id."""
281 d = self.wait_for_signals(275 d = self.wait_for_signals(
282276
=== modified file 'ubuntuone/syncdaemon/__init__.py'
--- ubuntuone/syncdaemon/__init__.py 2016-05-30 13:03:37 +0000
+++ ubuntuone/syncdaemon/__init__.py 2018-04-24 23:14:39 +0000
@@ -1,5 +1,5 @@
1# Copyright 2009-2012 Canonical Ltd.1# Copyright 2009-2012 Canonical Ltd.
2# Copyright 2015-2016 Chicharreros (https://launchpad.net/~chicharreros)2# Copyright 2015-2018 Chicharreros (https://launchpad.net/~chicharreros)
3#3#
4# This program is free software: you can redistribute it and/or modify it4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU General Public License version 3, as published5# under the terms of the GNU General Public License version 3, as published
@@ -31,9 +31,3 @@
31REQUIRED_CAPS = frozenset(31REQUIRED_CAPS = frozenset(
32 ["no-content", "account-info", "resumable-uploads", "fix462230", "volumes",32 ["no-content", "account-info", "resumable-uploads", "fix462230", "volumes",
33 "generations"])33 "generations"])
34
35
36# Sync Menu data constants
37RECENT_TRANSFERS = 'recent-transfers'
38UPLOADING = 'uploading'
39DOWNLOADING = 'downloading'
4034
=== modified file 'ubuntuone/syncdaemon/interaction_interfaces.py'
--- ubuntuone/syncdaemon/interaction_interfaces.py 2018-04-14 23:34:20 +0000
+++ ubuntuone/syncdaemon/interaction_interfaces.py 2018-04-24 23:14:39 +0000
@@ -304,10 +304,6 @@
304 waiting_content.append(data)304 waiting_content.append(data)
305 return waiting_content305 return waiting_content
306306
307 def sync_menu(self):
308 """Return the info necessary to construct the menu."""
309 return self.main.status_listener.menu_data()
310
311307
312class SyncdaemonFileSystem(SyncdaemonObject):308class SyncdaemonFileSystem(SyncdaemonObject):
313 """An interface to the FileSystem Manager."""309 """An interface to the FileSystem Manager."""

Subscribers

People subscribed via source and target branches

to all changes: