Merge lp:~alecu/ubuntuone-client/config-notifications-2 into lp:ubuntuone-client

Proposed by Alejandro J. Cura on 2011-02-16
Status: Merged
Approved by: dobey on 2011-02-16
Approved revision: 870
Merged at revision: 870
Proposed branch: lp:~alecu/ubuntuone-client/config-notifications-2
Merge into: lp:ubuntuone-client
Diff against target: 524 lines (+286/-35)
2 files modified
tests/status/test_aggregator.py (+226/-19)
ubuntuone/status/aggregator.py (+60/-16)
To merge this branch: bzr merge lp:~alecu/ubuntuone-client/config-notifications-2
Reviewer Review Type Date Requested Status
Eric Casteleijn (community) Approve on 2011-02-16
Martin Albisetti (community) 2011-02-16 Approve on 2011-02-16
Review via email: mp+49904@code.launchpad.net

Commit message

disable notifications according to config, don't show partial count of files done (LP:#717172, LP:#715842, LP:#715887)

Description of the change

disable notifications according to config, don't show partial count of files done (LP:#717172, LP:#715842, LP:#715887)

To post a comment you must log in.
Martin Albisetti (beuno) :
review: Approve
Eric Casteleijn (thisfred) wrote :

Great branch! +1

review: Approve
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (32.0 KiB)

The attempt to merge lp:~alecu/ubuntuone-client/config-notifications-2 into lp:ubuntuone-client failed. Below is the output from the failed tests.

/usr/bin/gnome-autogen.sh
checking for autoconf >= 2.53...
  testing autoconf2.50... not found.
  testing autoconf... found 2.67
checking for automake >= 1.10...
  testing automake-1.11... found 1.11.1
checking for libtool >= 1.5...
  testing libtoolize... found 2.2.6b
checking for intltool >= 0.30...
  testing intltoolize... found 0.41.1
checking for pkg-config >= 0.14.0...
  testing pkg-config... found 0.25
checking for gtk-doc >= 1.0...
  testing gtkdocize... found 1.16
Checking for required M4 macros...
Checking for forbidden M4 macros...
Processing ./configure.ac
Running libtoolize...
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `m4'.
libtoolize: copying file `m4/libtool.m4'
libtoolize: copying file `m4/ltoptions.m4'
libtoolize: copying file `m4/ltsugar.m4'
libtoolize: copying file `m4/ltversion.m4'
libtoolize: copying file `m4/lt~obsolete.m4'
Running intltoolize...
Running gtkdocize...
Running aclocal-1.11...
Running autoconf...
Running autoheader...
Running automake-1.11...
Running ./configure --enable-gtk-doc --enable-debug ...
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking for library containing strerror... none required
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ISO C89... (cached) none needed
checking dependency style of gcc... (cached) gcc3
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent...

Ubuntu One Auto Pilot (otto-pilot) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/status/test_aggregator.py'
2--- tests/status/test_aggregator.py 2011-02-11 22:01:23 +0000
3+++ tests/status/test_aggregator.py 2011-02-16 19:09:08 +0000
4@@ -132,18 +132,27 @@
5 def __init__(self, application_name="fake app"):
6 """Initialize this instance."""
7 self.notifications_shown = []
8+ self.notification_switch = None
9 self.application_name = application_name
10
11 def send_notification(self, title, message, icon=None, append=False):
12 """Show a notification to the user."""
13+ if (self.notification_switch is not None
14+ and not self.notification_switch.enabled):
15+ return
16 self.notifications_shown.append((title, message, icon, append))
17 return len(self.notifications_shown) - 1
18
19- def update_notification(self, notification, new_title, new_message,
20+ def update_notification(self, notification_id, new_title, new_message,
21 new_icon=None):
22 """Update the notification with a new message body."""
23+ if (self.notification_switch is not None
24+ and not self.notification_switch.enabled):
25+ return
26+ if notification_id is None:
27+ return
28 title, old_message, icon, append = self.notifications_shown[
29- notification]
30+ notification_id]
31 if new_icon is not None:
32 icon = new_icon
33 # we store it as a new notification, to ease testing
34@@ -155,8 +164,9 @@
35 """Builds a notification singleton, that logs all notifications shown."""
36 instance = FakeNotification()
37
38- def get_instance():
39+ def get_instance(notification_switch):
40 """Returns the single instance."""
41+ instance.notification_switch = notification_switch
42 return instance
43
44 return get_instance
45@@ -192,6 +202,7 @@
46 self.discovered = 0
47 self.completed = 0
48 self.restart_progress_bubble_called = False
49+ self.notification_switch = aggregator.NotificationSwitch()
50
51 def get_discovery_message(self):
52 """Return the file discovery message."""
53@@ -220,13 +231,122 @@
54 """Reset the progress bubble."""
55 self.restart_progress_bubble_called = True
56
57+ def build_notification(self):
58+ """Create a new toggleable notification object."""
59+ return self.notification_switch.build_notification()
60+
61+
62+class ToggleableNotificationTestCase(TestCase):
63+ """Test the ToggleableNotification class."""
64+
65+ def setUp(self):
66+ """Initialize this test instance."""
67+ self.patch(aggregator, "Notification", FakeNotification)
68+ self.notification_switch = aggregator.NotificationSwitch()
69+ self.toggleable = self.notification_switch.build_notification()
70+
71+ def assertShown(self, notification):
72+ """Assert that the notification was shown."""
73+ self.assertIn(notification,
74+ self.toggleable.notification.notifications_shown)
75+
76+ def assertNotShown(self, notification):
77+ """Assert that the notification was shown."""
78+ self.assertNotIn(notification,
79+ self.toggleable.notification.notifications_shown)
80+
81+ def test_send_notification_passes_thru(self):
82+ """The send_notification method passes thru."""
83+ args = (1, 2, 3, 4)
84+ self.toggleable.send_notification(*args)
85+ self.assertShown(args)
86+
87+ def test_update_notification_passes_thru(self):
88+ """The update_notification method passes thru."""
89+ show_args = ("title", "body", "icon", "append")
90+ update_args = ("other title", "other body")
91+ expected = update_args + show_args[2:]
92+ notification_id = self.toggleable.send_notification(*show_args)
93+ self.toggleable.update_notification(notification_id, *update_args)
94+ self.assertShown(expected)
95+
96+ def test_send_notification_honored_when_enabled(self):
97+ """The send_notification method is honored when enabled."""
98+ self.notification_switch.enable_notifications()
99+ args = (aggregator.UBUNTUONE_TITLE, "hello", None, False)
100+ self.toggleable.send_notification(*args)
101+ self.assertShown(args)
102+
103+ def test_send_notification_ignored_when_disabled(self):
104+ """The send_notification method is ignored when disabled."""
105+ self.notification_switch.disable_notifications()
106+ args = (aggregator.UBUNTUONE_TITLE, "hello", None, False)
107+ self.toggleable.send_notification(*args)
108+ self.assertNotShown(args)
109+
110+ def test_update_notification_honored_when_enabled(self):
111+ """The update_notification method is honored when enabled."""
112+ self.notification_switch.enable_notifications()
113+ show_args = ("title", "body", "icon", "append")
114+ update_args = ("other title", "other body")
115+ expected = update_args + show_args[2:]
116+ notification_id = self.toggleable.send_notification(*show_args)
117+ self.toggleable.update_notification(notification_id, *update_args)
118+ self.assertShown(expected)
119+
120+ def test_update_notification_ignored_when_disabled(self):
121+ """The update_notification method is ignored when disabled."""
122+ self.notification_switch.disable_notifications()
123+ show_args = ("title", "body", "icon", "append")
124+ update_args = ("other title", "other body")
125+ expected = update_args + show_args[2:]
126+ notification_id = self.toggleable.send_notification(*show_args)
127+ self.toggleable.update_notification(notification_id, *update_args)
128+ self.assertNotShown(expected)
129+
130+ def test_update_after_disabled_show(self):
131+ """An update is ignored if the corresponding show was disabled."""
132+ self.notification_switch.disable_notifications()
133+ show_args = ("title", "body", "icon", "append")
134+ update_args = ("other title", "other body")
135+ expected = update_args + show_args[2:]
136+ notification_id = self.toggleable.send_notification(*show_args)
137+ self.notification_switch.enable_notifications()
138+ self.toggleable.update_notification(notification_id, *update_args)
139+ self.assertNotShown(expected)
140+
141+
142+class NotificationSwitchTestCase(TestCase):
143+ """Test the NotificationSwitch class."""
144+
145+ def setUp(self):
146+ """Initialize this test instance."""
147+ self.notification_switch = aggregator.NotificationSwitch()
148+
149+ def test_build_notification(self):
150+ """A new notification instance is returned."""
151+ notification = self.notification_switch.build_notification()
152+ self.assertEqual(notification.notification_switch,
153+ self.notification_switch)
154+
155+ def test_enable_notifications(self):
156+ """The switch is turned on."""
157+ self.notification_switch.enable_notifications()
158+ self.assertTrue(self.notification_switch.enabled)
159+
160+ def test_disable_notifications(self):
161+ """The switch is turned off."""
162+ self.notification_switch.disable_notifications()
163+ self.assertFalse(self.notification_switch.enabled)
164+
165
166 class FileDiscoveryBubbleTestCase(TestCase):
167 """Test the FileDiscoveryBubble class."""
168
169 def setUp(self):
170 """Initialize this test instance."""
171- self.patch(aggregator, "Notification", FakeNotificationSingleton())
172+ self.patch(aggregator, "ToggleableNotification",
173+ FakeNotificationSingleton())
174 self.clock = PatchedClock()
175 self.aggregator = FakeStatusAggregator(clock=self.clock)
176 self.bubble = aggregator.FileDiscoveryBubble(self.aggregator,
177@@ -384,7 +504,8 @@
178
179 def setUp(self):
180 """Initialize this test instance."""
181- self.patch(aggregator, "Notification", FakeNotificationSingleton())
182+ self.patch(aggregator, "ToggleableNotification",
183+ FakeNotificationSingleton())
184 self.clock = PatchedClock()
185 self.aggregator = FakeStatusAggregator(clock=self.clock)
186 self.bubble = aggregator.ProgressBubble(self.aggregator,
187@@ -468,7 +589,8 @@
188
189 def setUp(self):
190 """Initialize this test instance."""
191- self.patch(aggregator, "Notification", FakeNotificationSingleton())
192+ self.patch(aggregator, "ToggleableNotification",
193+ FakeNotificationSingleton())
194 self.clock = PatchedClock()
195 self.aggregator = FakeStatusAggregator(clock=self.clock)
196 self.bubble = aggregator.FinalStatusBubble(self.aggregator)
197@@ -611,6 +733,7 @@
198 def __init__(self, clock):
199 """Initialize this fake instance."""
200 self.queued_commands = set()
201+ self.notification_switch = aggregator.NotificationSwitch()
202
203 def queue_done(self):
204 """The queue completed all operations."""
205@@ -624,6 +747,10 @@
206 """A new command was unqueued."""
207 self.queued_commands.discard(command)
208
209+ def build_notification(self):
210+ """Create a new toggleable notification object."""
211+ return self.notification_switch.build_notification()
212+
213 download_started = misc_command_queued
214 download_finished = misc_command_unqueued
215 upload_started = misc_command_queued
216@@ -637,7 +764,8 @@
217 """Initialize this test instance."""
218 BaseTwistedTestCase.setUp(self)
219 self.patch(aggregator, "StatusAggregator", FakeAggregator)
220- self.patch(aggregator, "Notification", FakeNotificationSingleton())
221+ self.patch(aggregator, "ToggleableNotification",
222+ FakeNotificationSingleton())
223 self.patch(aggregator, "Messaging", FakeMessaging)
224 self.fakefsm = None
225 self.fakevm = FakeVolumeManager()
226@@ -827,6 +955,12 @@
227 aggregator.ConnectionMadeStatus.MESSAGE_ONE, None, False),
228 self.status_frontend.notification.notifications_shown[0])
229
230+ def test_set_show_all_notifications(self):
231+ """Test the set_show_all_notifications method."""
232+ self.status_frontend.set_show_all_notifications(False)
233+ self.assertFalse(self.status_frontend.aggregator.
234+ notification_switch.enabled)
235+
236
237 class StatusEventTestCase(TestCase):
238 """Test the status event class and children."""
239@@ -1119,8 +1253,8 @@
240 self.aggregator.download_total = 8
241 self.aggregator.done_counter = 9
242 self.aggregator.total_counter = 20
243- expected = (aggregator.PROGRESS_UPLOADED % (5, 10) + " " +
244- aggregator.PROGRESS_DOWNLOADED % (3, 8) + " " +
245+ expected = (aggregator.FILES_UPLOADING % 10 + " " +
246+ aggregator.FILES_DOWNLOADING % 8 + " " +
247 aggregator.PROGRESS_COMPLETED % int(100.0 * 9 / 20))
248 result = self.aggregator.get_progress_message()
249 self.assertEqual(expected, result)
250@@ -1133,7 +1267,7 @@
251 self.aggregator.download_total = 8
252 self.aggregator.done_counter = 9
253 self.aggregator.total_counter = 20
254- expected = (aggregator.PROGRESS_DOWNLOADED % (3, 8) + " " +
255+ expected = (aggregator.FILES_DOWNLOADING % 8 + " " +
256 aggregator.PROGRESS_COMPLETED % int(100.0 * 9 / 20))
257 result = self.aggregator.get_progress_message()
258 self.assertEqual(expected, result)
259@@ -1146,7 +1280,7 @@
260 self.aggregator.download_total = 0
261 self.aggregator.done_counter = 9
262 self.aggregator.total_counter = 20
263- expected = (aggregator.PROGRESS_UPLOADED % (5, 10) + " " +
264+ expected = (aggregator.FILES_UPLOADING % 10 + " " +
265 aggregator.PROGRESS_COMPLETED % int(100.0 * 9 / 20))
266 result = self.aggregator.get_progress_message()
267 self.assertEqual(expected, result)
268@@ -1189,13 +1323,37 @@
269 self.aggregator.restart_progress_bubble()
270 self.assertTrue(self.aggregator.progress_bubble.started)
271
272- def test_queue_done(self):
273- """On queue done, show final bubble and reset counters."""
274- fc = FakeCommand()
275- self.status_frontend.upload_started(fc)
276- old_final_bubble = self.aggregator.final_status_bubble
277- self.aggregator.queue_done()
278- self.assertTrue(old_final_bubble.shown)
279+ def test_queue_done_shows_bubble_when_downloads_happened(self):
280+ """On queue done, show final bubble if downloads happened."""
281+ fc = FakeCommand()
282+ self.status_frontend.download_started(fc)
283+ self.status_frontend.download_finished(fc)
284+ old_final_bubble = self.aggregator.final_status_bubble
285+ self.aggregator.queue_done()
286+ self.assertTrue(old_final_bubble.shown)
287+
288+ def test_queue_done_shows_bubble_when_uploads_happened(self):
289+ """On queue done, show final bubble if uploads happened."""
290+ fc = FakeCommand()
291+ self.status_frontend.upload_started(fc)
292+ self.status_frontend.upload_finished(fc)
293+ old_final_bubble = self.aggregator.final_status_bubble
294+ self.aggregator.queue_done()
295+ self.assertTrue(old_final_bubble.shown)
296+
297+ def test_queue_done_does_not_show_bubble_when_no_transfers_happened(self):
298+ """On queue done, don't show final bubble if no transfers happened."""
299+ fc = FakeCommand()
300+ self.status_frontend.upload_started(fc)
301+ old_final_bubble = self.aggregator.final_status_bubble
302+ self.aggregator.queue_done()
303+ self.assertFalse(old_final_bubble.shown)
304+
305+ def test_queue_done_resets_status_and_hides_progressbar(self):
306+ """On queue done, reset counters and hide progressbar."""
307+ fc = FakeCommand()
308+ self.status_frontend.upload_started(fc)
309+ self.aggregator.queue_done()
310 self.assertStatusReset()
311 self.assertEqual(0.0, self.aggregator.progress_bar.percentage)
312 self.assertFalse(self.aggregator.progress_bar.visible)
313@@ -1229,10 +1387,13 @@
314
315 def test_all_together_now(self):
316 """Make all parts work together."""
317- self.patch(aggregator, "Notification", FakeNotificationSingleton())
318+ self.patch(aggregator, "ToggleableNotification",
319+ FakeNotificationSingleton())
320 clock = PatchedClock()
321 upload = FakeCommand()
322 sf = aggregator.StatusFrontend(clock=clock)
323+ sf.set_show_all_notifications(True)
324+
325 clock.advance(aggregator.ProgressBubble.sleep_delay)
326 # the progress bar is not visible yet
327 self.assertFalse(sf.aggregator.progress_bar.visible)
328@@ -1276,3 +1437,49 @@
329 clock.advance(aggregator.ProgressBubble.sleep_delay * 2)
330 # no more notifications are shown
331 self.assertEqual(5, len(notifications_shown))
332+
333+ def test_all_together_now_off(self):
334+ """Make all parts work together, but with notifications off."""
335+ self.patch(aggregator, "ToggleableNotification",
336+ FakeNotificationSingleton())
337+ clock = PatchedClock()
338+ upload = FakeCommand()
339+ sf = aggregator.StatusFrontend(clock=clock)
340+ sf.set_show_all_notifications(False)
341+
342+ clock.advance(aggregator.ProgressBubble.sleep_delay)
343+ # the progress bar is not visible yet
344+ self.assertFalse(sf.aggregator.progress_bar.visible)
345+ sf.upload_started(upload)
346+ # the progress bar is now shown
347+ self.assertTrue(sf.aggregator.progress_bar.visible)
348+ notifications_shown = (sf.aggregator.file_discovery_bubble.
349+ notification.notifications_shown)
350+ # no notifications shown, never
351+ self.assertEqual(0, len(notifications_shown))
352+ clock.advance(aggregator.FileDiscoveryGatheringState.initial_delay)
353+ self.assertEqual(0, len(notifications_shown))
354+ download = FakeCommand()
355+ sf.download_started(download)
356+ self.assertEqual(0, len(notifications_shown))
357+ # the progress still is zero
358+ self.assertEqual(0.0, sf.aggregator.progress_bar.percentage)
359+ clock.advance(aggregator.FileDiscoveryUpdateState.updates_delay)
360+ self.assertEqual(0, len(notifications_shown))
361+ clock.advance(aggregator.FileDiscoveryUpdateState.updates_timeout -
362+ aggregator.FileDiscoveryUpdateState.updates_delay)
363+ sf.upload_finished(upload)
364+ # the progress bubble has no notifications yet
365+ self.assertEqual(None, sf.aggregator.progress_bubble.notification)
366+ clock.advance(aggregator.ProgressBubble.sleep_delay)
367+ self.assertEqual(0, len(notifications_shown))
368+ sf.upload_finished(download)
369+ # the progress still is now 100%
370+ self.assertEqual(100.0, sf.aggregator.progress_bar.percentage)
371+ self.assertEqual(0, len(notifications_shown))
372+ clock.advance(aggregator.ProgressBubble.sleep_delay)
373+ self.assertEqual(0, len(notifications_shown))
374+ sf.queue_done()
375+ self.assertEqual(0, len(notifications_shown))
376+ clock.advance(aggregator.ProgressBubble.sleep_delay * 2)
377+ self.assertEqual(0, len(notifications_shown))
378
379=== modified file 'ubuntuone/status/aggregator.py'
380--- ubuntuone/status/aggregator.py 2011-02-14 19:16:19 +0000
381+++ ubuntuone/status/aggregator.py 2011-02-16 19:09:08 +0000
382@@ -39,16 +39,52 @@
383 logger.addHandler(debug_handler)
384
385 UBUNTUONE_TITLE = "Ubuntu One"
386-NEW_UDFS_SENDER = "New Cloud Folder(s) Available"
387+NEW_UDFS_SENDER = "New cloud folder(s) available"
388 FINAL_COMPLETED = "File synchronization completed."
389-FINAL_UPLOADED = "%d files were uploaded to your cloud."
390-FINAL_DOWNLOADED = "%d files were downloaded to your computer."
391-FILES_UPLOADING = "%d files are uploading to your cloud."
392-FILES_DOWNLOADING = "%d files are downloading to your computer."
393-PROGRESS_UPLOADED = "Uploaded %d/%d files."
394-PROGRESS_DOWNLOADED = "Downloaded %d/%d files."
395+FINAL_UPLOADED = "%d file(s) were uploaded to your personal cloud."
396+FINAL_DOWNLOADED = "%d file(s) were downloaded to your computer."
397+FILES_UPLOADING = "%d file(s) are uploading to your personal cloud."
398+FILES_DOWNLOADING = "%d file(s) are downloading to your computer."
399+PROGRESS_UPLOADED = "Uploaded %d/%d file(s)."
400 PROGRESS_COMPLETED = "%d%% completed."
401
402+class ToggleableNotification(object):
403+ """A controller for notifications that can be turned off."""
404+
405+ def __init__(self, notification_switch):
406+ """Initialize this instance."""
407+ self.notification_switch = notification_switch
408+ self.notification = Notification()
409+
410+ def send_notification(self, *args):
411+ """Passthru the notification."""
412+ if self.notification_switch.enabled:
413+ return self.notification.send_notification(*args)
414+
415+ def update_notification(self, notification_id, *args):
416+ """Passthru the update."""
417+ if notification_id is not None and self.notification_switch.enabled:
418+ return self.notification.update_notification(notification_id,
419+ *args)
420+
421+
422+class NotificationSwitch(object):
423+ """A switch that turns notifications on and off."""
424+
425+ enabled = True
426+
427+ def build_notification(self):
428+ """Return a new notification instance."""
429+ return ToggleableNotification(self)
430+
431+ def enable_notifications(self):
432+ """Turn the switch on."""
433+ self.enabled = True
434+
435+ def disable_notifications(self):
436+ """Turn the switch off."""
437+ self.enabled = False
438+
439
440 class StatusEvent(object):
441 """An event representing a status change."""
442@@ -328,7 +364,7 @@
443
444 def _start(self):
445 """The first file was found, so start gathering."""
446- self.notification = Notification()
447+ self.notification = self.status_aggregator.build_notification()
448 self._change_state(FileDiscoveryGatheringState)
449
450 def _popup(self):
451@@ -381,7 +417,7 @@
452
453 def _timeout(self, result):
454 """Show the bubble."""
455- self.notification = Notification()
456+ self.notification = self.status_aggregator.build_notification()
457 text = self.status_aggregator.get_progress_message()
458 self.notification.send_notification(UBUNTUONE_TITLE, text)
459 self.restart()
460@@ -453,7 +489,7 @@
461
462 def show(self):
463 """Show the final status notification."""
464- self.notification = Notification()
465+ self.notification = self.status_aggregator.build_notification()
466 text = self.status_aggregator.get_final_status_message()
467 self.notification.send_notification(UBUNTUONE_TITLE, text)
468
469@@ -475,9 +511,14 @@
470 def __init__(self, clock=reactor):
471 """Initialize this instance."""
472 self.clock = clock
473+ self.notification_switch = NotificationSwitch()
474 self.reset()
475 self.progress_bar = ProgressBar(clock=self.clock)
476
477+ def build_notification(self):
478+ """Create a new toggleable notification object."""
479+ return self.notification_switch.build_notification()
480+
481 def reset(self):
482 """Reset all counters and notifications."""
483 self.total_counter = 0
484@@ -521,11 +562,9 @@
485 assert self.total_counter > 0
486 parts = []
487 if self.upload_total:
488- parts.append(PROGRESS_UPLOADED % (self.upload_done,
489- self.upload_total))
490+ parts.append(FILES_UPLOADING % self.upload_total)
491 if self.download_total:
492- parts.append(PROGRESS_DOWNLOADED % (self.download_done,
493- self.download_total))
494+ parts.append(FILES_DOWNLOADING % self.download_total)
495 progress_percentage = 100.0 * self.done_counter / self.total_counter
496 parts.append(PROGRESS_COMPLETED % int(progress_percentage))
497 return " ".join(parts)
498@@ -546,7 +585,8 @@
499
500 def queue_done(self):
501 """Show final bubble and reset counters."""
502- self.final_status_bubble.show()
503+ if self.upload_done + self.download_done > 0:
504+ self.final_status_bubble.show()
505 self.progress_bar.completed()
506 self.reset()
507
508@@ -603,7 +643,7 @@
509 def __init__(self, clock=reactor):
510 """Initialize this instance."""
511 self.aggregator = StatusAggregator(clock=clock)
512- self.notification = Notification()
513+ self.notification = self.aggregator.build_notification()
514 self.messaging = Messaging()
515 self.udf_message = None
516
517@@ -681,3 +721,7 @@
518
519 def set_show_all_notifications(self, value):
520 """Set the flag to show all notifications."""
521+ if value:
522+ self.aggregator.notification_switch.enable_notifications()
523+ else:
524+ self.aggregator.notification_switch.disable_notifications()

Subscribers

People subscribed via source and target branches