Merge lp:~thisfred/ubuntuone-client/tune-notifications into lp:ubuntuone-client
- tune-notifications
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Eric Casteleijn | ||||
Approved revision: | 935 | ||||
Merged at revision: | 927 | ||||
Proposed branch: | lp:~thisfred/ubuntuone-client/tune-notifications | ||||
Merge into: | lp:ubuntuone-client | ||||
Diff against target: |
789 lines (+75/-392) 4 files modified
tests/status/test_aggregator.py (+28/-270) tests/syncdaemon/test_status_listener.py (+0/-26) ubuntuone/status/aggregator.py (+46/-91) ubuntuone/syncdaemon/status_listener.py (+1/-5) |
||||
To merge this branch: | bzr merge lp:~thisfred/ubuntuone-client/tune-notifications | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
dobey (community) | Approve | ||
Natalia Bidart (community) | Approve | ||
Review via email: mp+54510@code.launchpad.net |
Commit message
* removed progress notifications
* don't show empty notifications
* only show queue_done notifications after a delay where no new events came in
Description of the change
* removed progress notifications
* don't show empty notifications
* only show queue_done notifications after a delay where no new events came in. (set to 5 seconds which seems to work well OMM)
To test:
u1sdtool -q
PYTHONPATH=. bin/ubuntuone-
now on a different machine, do a bzr checkout in your Ubuntu One folder. (Or do something else that adds a lot of small files relatively quickly.)
On the receiving machine, you should now no longer see many download finished messages popping up one after the other, but rather one at the end. If your connection is slow or the servers are having trouble, you *might* see more than one, but never more than one per 5 seconds. Let me know if we should tune that number further.
Natalia Bidart (nataliabidart) : | # |
Ubuntu One Auto Pilot (otto-pilot) wrote : | # |
The attempt to merge lp:~thisfred/ubuntuone-client/tune-notifications into lp:ubuntuone-client failed. Below is the output from the failed tests.
/usr/bin/
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_
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 ...
- 935. By Eric Casteleijn
-
set the property before calling reset.
Preview Diff
1 | === modified file 'tests/status/test_aggregator.py' | |||
2 | --- tests/status/test_aggregator.py 2011-03-22 16:59:19 +0000 | |||
3 | +++ tests/status/test_aggregator.py 2011-03-23 20:01:28 +0000 | |||
4 | @@ -200,7 +200,6 @@ | |||
5 | 200 | """Initialize this instance.""" | 200 | """Initialize this instance.""" |
6 | 201 | self.discovered = 0 | 201 | self.discovered = 0 |
7 | 202 | self.completed = 0 | 202 | self.completed = 0 |
8 | 203 | self.restart_progress_bubble_called = False | ||
9 | 204 | self.notification_switch = aggregator.NotificationSwitch() | 203 | self.notification_switch = aggregator.NotificationSwitch() |
10 | 205 | 204 | ||
11 | 206 | def get_discovery_message(self): | 205 | def get_discovery_message(self): |
12 | @@ -226,10 +225,6 @@ | |||
13 | 226 | """Return the final status message.""" | 225 | """Return the final status message.""" |
14 | 227 | return "a lot of files completed.""" | 226 | return "a lot of files completed.""" |
15 | 228 | 227 | ||
16 | 229 | def restart_progress_bubble(self): | ||
17 | 230 | """Reset the progress bubble.""" | ||
18 | 231 | self.restart_progress_bubble_called = True | ||
19 | 232 | |||
20 | 233 | def get_notification(self): | 228 | def get_notification(self): |
21 | 234 | """Create a new toggleable notification object.""" | 229 | """Create a new toggleable notification object.""" |
22 | 235 | return self.notification_switch.get_notification() | 230 | return self.notification_switch.get_notification() |
23 | @@ -340,12 +335,6 @@ | |||
24 | 340 | notification = (aggregator.UBUNTUONE_TITLE, message, None, False) | 335 | notification = (aggregator.UBUNTUONE_TITLE, message, None, False) |
25 | 341 | self.assertIn(notification, self.get_notifications_shown()) | 336 | self.assertIn(notification, self.get_notifications_shown()) |
26 | 342 | 337 | ||
27 | 343 | def test_popup_resets_progress_bubble(self): | ||
28 | 344 | """The popup callback resets the progress bubble.""" | ||
29 | 345 | self.bubble.new_file_found() | ||
30 | 346 | self.bubble._popup() | ||
31 | 347 | self.assertTrue(self.aggregator.restart_progress_bubble_called) | ||
32 | 348 | |||
33 | 349 | def test_notification_is_logged_in_debug(self): | 338 | def test_notification_is_logged_in_debug(self): |
34 | 350 | """The notification is printed in the debug log.""" | 339 | """The notification is printed in the debug log.""" |
35 | 351 | self.bubble.new_file_found() | 340 | self.bubble.new_file_found() |
36 | @@ -430,14 +419,6 @@ | |||
37 | 430 | self.clock.advance(self.updates_delay) | 419 | self.clock.advance(self.updates_delay) |
38 | 431 | self.assertEqual(2, len(self.get_notifications_shown())) | 420 | self.assertEqual(2, len(self.get_notifications_shown())) |
39 | 432 | 421 | ||
40 | 433 | def test_update_resets_progress_bubble(self): | ||
41 | 434 | """The update callback resets the progress bubble.""" | ||
42 | 435 | self.bubble.new_file_found() | ||
43 | 436 | self.bubble._popup() | ||
44 | 437 | self.bubble.new_file_found() | ||
45 | 438 | self.bubble._update() | ||
46 | 439 | self.assertTrue(self.aggregator.restart_progress_bubble_called) | ||
47 | 440 | |||
48 | 441 | def test_update_modifies_notification(self): | 422 | def test_update_modifies_notification(self): |
49 | 442 | """The update callback updates notifications.""" | 423 | """The update callback updates notifications.""" |
50 | 443 | self.bubble.new_file_found() | 424 | self.bubble.new_file_found() |
51 | @@ -458,91 +439,6 @@ | |||
52 | 458 | self.assertTrue(self.handler.check_debug(msg)) | 439 | self.assertTrue(self.handler.check_debug(msg)) |
53 | 459 | 440 | ||
54 | 460 | 441 | ||
55 | 461 | class ProgressBubbleTestCase(TestCase): | ||
56 | 462 | """Tests for the progress bubble.""" | ||
57 | 463 | |||
58 | 464 | def setUp(self): | ||
59 | 465 | """Initialize this test instance.""" | ||
60 | 466 | self.patch(aggregator, "ToggleableNotification", | ||
61 | 467 | FakeNotificationSingleton()) | ||
62 | 468 | self.clock = PatchedClock() | ||
63 | 469 | self.aggregator = FakeStatusAggregator(clock=self.clock) | ||
64 | 470 | self.bubble = aggregator.ProgressBubble(self.aggregator, | ||
65 | 471 | clock=self.clock) | ||
66 | 472 | self.addCleanup(self.bubble.cleanup) | ||
67 | 473 | self.smaller_delay = aggregator.ProgressBubble.sleep_delay * 0.8 | ||
68 | 474 | self.right_delay = aggregator.ProgressBubble.sleep_delay | ||
69 | 475 | self.longer_delay = aggregator.ProgressBubble.sleep_delay * 1.2 | ||
70 | 476 | |||
71 | 477 | def test_is_created_successfully(self): | ||
72 | 478 | """The progress bubble is created and idle.""" | ||
73 | 479 | self.assertEqual(None, self.bubble.timer) | ||
74 | 480 | |||
75 | 481 | def test_restart_creates_timer(self): | ||
76 | 482 | """Restarting creates a timer.""" | ||
77 | 483 | self.bubble.restart() | ||
78 | 484 | self.assertNotEqual(None, self.bubble.timer) | ||
79 | 485 | |||
80 | 486 | def test_not_shown_initially(self): | ||
81 | 487 | """The bubble is not shown initially.""" | ||
82 | 488 | self.bubble.restart() | ||
83 | 489 | self.assertEqual(None, self.bubble.notification) | ||
84 | 490 | |||
85 | 491 | def test_not_shown_immediately(self): | ||
86 | 492 | """The bubble is not shown immediately.""" | ||
87 | 493 | self.bubble.restart() | ||
88 | 494 | self.clock.advance(self.smaller_delay) | ||
89 | 495 | self.assertEqual(None, self.bubble.notification) | ||
90 | 496 | |||
91 | 497 | def test_shown_after_delay(self): | ||
92 | 498 | """The bubble is shown after the standard delay.""" | ||
93 | 499 | self.bubble.restart() | ||
94 | 500 | self.clock.advance(self.longer_delay) | ||
95 | 501 | self.assertEqual(1, len(self.bubble.notification.notifications_shown)) | ||
96 | 502 | |||
97 | 503 | def test_not_shown_if_restarted(self): | ||
98 | 504 | """The delay is adjusted when restarting.""" | ||
99 | 505 | self.bubble.restart() | ||
100 | 506 | self.clock.advance(self.smaller_delay) | ||
101 | 507 | self.bubble.restart() | ||
102 | 508 | self.clock.advance(self.smaller_delay) | ||
103 | 509 | self.assertEqual(None, self.bubble.notification) | ||
104 | 510 | |||
105 | 511 | def test_delay_reached_after_restart(self): | ||
106 | 512 | """The timeout is still reached after a restart.""" | ||
107 | 513 | self.bubble.restart() | ||
108 | 514 | self.clock.advance(self.smaller_delay) | ||
109 | 515 | self.bubble.restart() | ||
110 | 516 | self.clock.advance(self.longer_delay) | ||
111 | 517 | self.assertEqual(1, len(self.bubble.notification.notifications_shown)) | ||
112 | 518 | |||
113 | 519 | def test_can_be_stopped(self): | ||
114 | 520 | """The timeout can be stopped.""" | ||
115 | 521 | self.bubble.restart() | ||
116 | 522 | self.clock.advance(self.smaller_delay) | ||
117 | 523 | self.bubble.stop() | ||
118 | 524 | self.clock.advance(self.longer_delay) | ||
119 | 525 | self.assertEqual(None, self.bubble.notification) | ||
120 | 526 | |||
121 | 527 | def test_delay_reached_after_stopping_then_restarting(self): | ||
122 | 528 | """The timeout is still reached after a stop followed by a restart.""" | ||
123 | 529 | self.bubble.restart() | ||
124 | 530 | self.clock.advance(self.smaller_delay) | ||
125 | 531 | self.bubble.stop() | ||
126 | 532 | self.clock.advance(self.longer_delay) | ||
127 | 533 | self.bubble.restart() | ||
128 | 534 | self.clock.advance(self.longer_delay) | ||
129 | 535 | self.assertEqual(1, len(self.bubble.notification.notifications_shown)) | ||
130 | 536 | |||
131 | 537 | def test_restarts_automatically(self): | ||
132 | 538 | """The timer is restarted automatically.""" | ||
133 | 539 | self.bubble.restart() | ||
134 | 540 | self.clock.advance(self.right_delay) | ||
135 | 541 | self.assertEqual(1, len(self.bubble.notification.notifications_shown)) | ||
136 | 542 | self.clock.advance(self.right_delay) | ||
137 | 543 | self.assertEqual(2, len(self.bubble.notification.notifications_shown)) | ||
138 | 544 | |||
139 | 545 | |||
140 | 546 | class FinalBubbleTestCase(TestCase): | 442 | class FinalBubbleTestCase(TestCase): |
141 | 547 | """Test for the final status notification bubble.""" | 443 | """Test for the final status notification bubble.""" |
142 | 548 | 444 | ||
143 | @@ -788,14 +684,6 @@ | |||
144 | 788 | """The queue completed all operations.""" | 684 | """The queue completed all operations.""" |
145 | 789 | self.queued_commands.clear() | 685 | self.queued_commands.clear() |
146 | 790 | 686 | ||
147 | 791 | def misc_command_queued(self, command): | ||
148 | 792 | """A new command was queued.""" | ||
149 | 793 | self.queued_commands.add(command) | ||
150 | 794 | |||
151 | 795 | def misc_command_unqueued(self, command): | ||
152 | 796 | """A new command was unqueued.""" | ||
153 | 797 | self.queued_commands.discard(command) | ||
154 | 798 | |||
155 | 799 | def get_notification(self): | 687 | def get_notification(self): |
156 | 800 | """Create a new toggleable notification object.""" | 688 | """Create a new toggleable notification object.""" |
157 | 801 | return self.notification_switch.get_notification() | 689 | return self.notification_switch.get_notification() |
158 | @@ -803,24 +691,24 @@ | |||
159 | 803 | def download_started(self, command): | 691 | def download_started(self, command): |
160 | 804 | """A download just started.""" | 692 | """A download just started.""" |
161 | 805 | self.files_downloading.append(command) | 693 | self.files_downloading.append(command) |
163 | 806 | self.misc_command_queued(command) | 694 | self.queued_commands.add(command) |
164 | 807 | 695 | ||
165 | 808 | def download_finished(self, command): | 696 | def download_finished(self, command): |
166 | 809 | """A download just finished.""" | 697 | """A download just finished.""" |
167 | 810 | if command in self.files_downloading: | 698 | if command in self.files_downloading: |
168 | 811 | self.files_downloading.remove(command) | 699 | self.files_downloading.remove(command) |
170 | 812 | self.misc_command_unqueued(command) | 700 | self.queued_commands.discard(command) |
171 | 813 | 701 | ||
172 | 814 | def upload_started(self, command): | 702 | def upload_started(self, command): |
173 | 815 | """An upload just started.""" | 703 | """An upload just started.""" |
174 | 816 | self.files_uploading.append(command) | 704 | self.files_uploading.append(command) |
176 | 817 | self.misc_command_queued(command) | 705 | self.queued_commands.add(command) |
177 | 818 | 706 | ||
178 | 819 | def upload_finished(self, command): | 707 | def upload_finished(self, command): |
179 | 820 | """An upload just finished.""" | 708 | """An upload just finished.""" |
180 | 821 | if command in self.files_uploading: | 709 | if command in self.files_uploading: |
181 | 822 | self.files_uploading.remove(command) | 710 | self.files_uploading.remove(command) |
183 | 823 | self.misc_command_unqueued(command) | 711 | self.queued_commands.discard(command) |
184 | 824 | 712 | ||
185 | 825 | def connection_made(self): | 713 | def connection_made(self): |
186 | 826 | """The client made the connection to the server.""" | 714 | """The client made the connection to the server.""" |
187 | @@ -914,21 +802,6 @@ | |||
188 | 914 | qc = self.status_frontend.aggregator.queued_commands | 802 | qc = self.status_frontend.aggregator.queued_commands |
189 | 915 | self.assertNotIn(fake_command, qc) | 803 | self.assertNotIn(fake_command, qc) |
190 | 916 | 804 | ||
191 | 917 | def test_queue_added(self): | ||
192 | 918 | """A command was added to the queue.""" | ||
193 | 919 | fake_command = FakeCommand() | ||
194 | 920 | self.listener.handle_SYS_QUEUE_ADDED(fake_command) | ||
195 | 921 | qc = self.status_frontend.aggregator.queued_commands | ||
196 | 922 | self.assertIn(fake_command, qc) | ||
197 | 923 | |||
198 | 924 | def test_queue_removed(self): | ||
199 | 925 | """A command has finished and is removed from the queue.""" | ||
200 | 926 | fake_command = FakeCommand() | ||
201 | 927 | self.listener.handle_SYS_QUEUE_ADDED(fake_command) | ||
202 | 928 | self.listener.handle_SYS_QUEUE_REMOVED(fake_command) | ||
203 | 929 | qc = self.status_frontend.aggregator.queued_commands | ||
204 | 930 | self.assertNotIn(fake_command, qc) | ||
205 | 931 | |||
206 | 932 | def test_queue_done(self): | 805 | def test_queue_done(self): |
207 | 933 | """The queue is empty.""" | 806 | """The queue is empty.""" |
208 | 934 | fake_command = FakeCommand() | 807 | fake_command = FakeCommand() |
209 | @@ -1161,27 +1034,6 @@ | |||
210 | 1161 | """Cleanup this instance.""" | 1034 | """Cleanup this instance.""" |
211 | 1162 | 1035 | ||
212 | 1163 | 1036 | ||
213 | 1164 | class FakeProgressBubble(object): | ||
214 | 1165 | """A fake ProgressBubble object.""" | ||
215 | 1166 | |||
216 | 1167 | started = False | ||
217 | 1168 | stopped = False | ||
218 | 1169 | |||
219 | 1170 | def __init__(self, status_aggregator, clock=None): | ||
220 | 1171 | """Initialize this instance.""" | ||
221 | 1172 | self.status_aggregator = status_aggregator | ||
222 | 1173 | |||
223 | 1174 | def cleanup(self): | ||
224 | 1175 | """Cleanup this instance.""" | ||
225 | 1176 | |||
226 | 1177 | def restart(self): | ||
227 | 1178 | """Start this bubble waiting.""" | ||
228 | 1179 | self.started = True | ||
229 | 1180 | |||
230 | 1181 | def stop(self): | ||
231 | 1182 | """Make this bubble stop.""" | ||
232 | 1183 | |||
233 | 1184 | |||
234 | 1185 | class FakeFinalBubble(object): | 1037 | class FakeFinalBubble(object): |
235 | 1186 | """A fake FinalStatusBubble.""" | 1038 | """A fake FinalStatusBubble.""" |
236 | 1187 | 1039 | ||
237 | @@ -1206,15 +1058,14 @@ | |||
238 | 1206 | """Initialize this test instance.""" | 1058 | """Initialize this test instance.""" |
239 | 1207 | self.patch(aggregator, "FileDiscoveryBubble", | 1059 | self.patch(aggregator, "FileDiscoveryBubble", |
240 | 1208 | FakeFileDiscoveryBubble) | 1060 | FakeFileDiscoveryBubble) |
241 | 1209 | self.patch(aggregator, "ProgressBubble", | ||
242 | 1210 | FakeProgressBubble) | ||
243 | 1211 | self.patch(aggregator, "FinalStatusBubble", | 1061 | self.patch(aggregator, "FinalStatusBubble", |
244 | 1212 | FakeFinalBubble) | 1062 | FakeFinalBubble) |
245 | 1213 | self.patch(aggregator, "ToggleableNotification", | 1063 | self.patch(aggregator, "ToggleableNotification", |
246 | 1214 | FakeNotificationSingleton()) | 1064 | FakeNotificationSingleton()) |
247 | 1215 | self.patch(aggregator, "UbuntuOneLauncher", FakeLauncher) | 1065 | self.patch(aggregator, "UbuntuOneLauncher", FakeLauncher) |
248 | 1216 | self.patch(aggregator.session, "Inhibitor", FakeInhibitor) | 1066 | self.patch(aggregator.session, "Inhibitor", FakeInhibitor) |
250 | 1217 | self.status_frontend = aggregator.StatusFrontend() | 1067 | clock = PatchedClock() |
251 | 1068 | self.status_frontend = aggregator.StatusFrontend(clock=clock) | ||
252 | 1218 | self.aggregator = self.status_frontend.aggregator | 1069 | self.aggregator = self.status_frontend.aggregator |
253 | 1219 | self.fake_bubble = self.aggregator.file_discovery_bubble | 1070 | self.fake_bubble = self.aggregator.file_discovery_bubble |
254 | 1220 | 1071 | ||
255 | @@ -1253,21 +1104,6 @@ | |||
256 | 1253 | """Test that the counters start at zero.""" | 1104 | """Test that the counters start at zero.""" |
257 | 1254 | self.assertStatusReset() | 1105 | self.assertStatusReset() |
258 | 1255 | 1106 | ||
259 | 1256 | def test_misc_command_queue(self): | ||
260 | 1257 | """Test that a misc command was queued.""" | ||
261 | 1258 | fc = FakeCommand() | ||
262 | 1259 | self.status_frontend.queue_added(fc) | ||
263 | 1260 | self.assertMiscCommandQueued(fc) | ||
264 | 1261 | self.assertEqual(0, self.aggregator.progress_bar.progress) | ||
265 | 1262 | |||
266 | 1263 | def test_misc_command_unqueue(self): | ||
267 | 1264 | """Test that a misc command was unqueued.""" | ||
268 | 1265 | fc = FakeCommand() | ||
269 | 1266 | self.status_frontend.queue_added(fc) | ||
270 | 1267 | self.status_frontend.queue_removed(fc) | ||
271 | 1268 | self.assertMiscCommandUnqueued(fc) | ||
272 | 1269 | self.assertEqual(1.0, self.aggregator.progress_bar.progress) | ||
273 | 1270 | |||
274 | 1271 | def test_file_download_started(self): | 1107 | def test_file_download_started(self): |
275 | 1272 | """Test that a file has started download.""" | 1108 | """Test that a file has started download.""" |
276 | 1273 | fc = FakeCommand(path='testfile.txt') | 1109 | fc = FakeCommand(path='testfile.txt') |
277 | @@ -1323,76 +1159,6 @@ | |||
278 | 1323 | result = self.aggregator.get_discovery_message() | 1159 | result = self.aggregator.get_discovery_message() |
279 | 1324 | self.assertEqual(expected, result) | 1160 | self.assertEqual(expected, result) |
280 | 1325 | 1161 | ||
281 | 1326 | def test_get_progress_message(self): | ||
282 | 1327 | """Test the message that's shown on the progress bubble.""" | ||
283 | 1328 | self.aggregator.upload_done = 5 | ||
284 | 1329 | self.aggregator.upload_total = 10 | ||
285 | 1330 | self.aggregator.uploading_filename = FILENAME | ||
286 | 1331 | self.aggregator.download_done = 3 | ||
287 | 1332 | self.aggregator.download_total = 8 | ||
288 | 1333 | self.aggregator.downloading_filename = FILENAME2 | ||
289 | 1334 | self.aggregator.done_counter = 9 | ||
290 | 1335 | self.aggregator.total_counter = 20 | ||
291 | 1336 | percentage = int(100.0 * self.aggregator.done_counter / | ||
292 | 1337 | self.aggregator.total_counter) | ||
293 | 1338 | |||
294 | 1339 | expected = ( | ||
295 | 1340 | aggregator.files_being_uploaded( | ||
296 | 1341 | FILENAME, self.aggregator.upload_total) + "\n" + | ||
297 | 1342 | aggregator.files_being_downloaded( | ||
298 | 1343 | FILENAME2, self.aggregator.download_total) + "\n" + | ||
299 | 1344 | aggregator.PROGRESS_COMPLETED) % { | ||
300 | 1345 | 'percentage_completed': percentage} | ||
301 | 1346 | |||
302 | 1347 | result = self.aggregator.get_progress_message() | ||
303 | 1348 | self.assertEqual(expected, result) | ||
304 | 1349 | |||
305 | 1350 | def test_get_progress_message_no_uploads(self): | ||
306 | 1351 | """The progress message when no uploads are going on.""" | ||
307 | 1352 | |||
308 | 1353 | self.aggregator.upload_done = 0 | ||
309 | 1354 | self.aggregator.upload_total = 0 | ||
310 | 1355 | self.aggregator.downloading_filename = FILENAME | ||
311 | 1356 | self.aggregator.download_done = 3 | ||
312 | 1357 | self.aggregator.download_total = 8 | ||
313 | 1358 | self.aggregator.done_counter = 9 | ||
314 | 1359 | self.aggregator.total_counter = 20 | ||
315 | 1360 | percentage = int(100.0 * self.aggregator.done_counter / | ||
316 | 1361 | self.aggregator.total_counter) | ||
317 | 1362 | expected = ( | ||
318 | 1363 | aggregator.files_being_downloaded( | ||
319 | 1364 | FILENAME, self.aggregator.download_total) + "\n" + | ||
320 | 1365 | aggregator.PROGRESS_COMPLETED) % { | ||
321 | 1366 | 'percentage_completed': percentage} | ||
322 | 1367 | |||
323 | 1368 | result = self.aggregator.get_progress_message() | ||
324 | 1369 | self.assertEqual(expected, result) | ||
325 | 1370 | |||
326 | 1371 | def test_get_progress_message_no_downloads(self): | ||
327 | 1372 | """The progress message when no downloads are going on.""" | ||
328 | 1373 | self.aggregator.upload_done = 5 | ||
329 | 1374 | self.aggregator.upload_total = 10 | ||
330 | 1375 | self.aggregator.uploading_filename = FILENAME | ||
331 | 1376 | self.aggregator.download_done = 0 | ||
332 | 1377 | self.aggregator.download_total = 0 | ||
333 | 1378 | self.aggregator.done_counter = 9 | ||
334 | 1379 | self.aggregator.total_counter = 20 | ||
335 | 1380 | percentage = int(100.0 * self.aggregator.done_counter / | ||
336 | 1381 | self.aggregator.total_counter) | ||
337 | 1382 | expected = ( | ||
338 | 1383 | aggregator.files_being_uploaded( | ||
339 | 1384 | FILENAME, self.aggregator.upload_total) + | ||
340 | 1385 | "\n" + aggregator.PROGRESS_COMPLETED) % { | ||
341 | 1386 | 'percentage_completed': percentage} | ||
342 | 1387 | |||
343 | 1388 | result = self.aggregator.get_progress_message() | ||
344 | 1389 | self.assertEqual(expected, result) | ||
345 | 1390 | |||
346 | 1391 | def test_get_progress_message_no_total(self): | ||
347 | 1392 | """No progress message possible if total counter is zero.""" | ||
348 | 1393 | self.aggregator.total_counter = 0 | ||
349 | 1394 | self.assertRaises(AssertionError, self.aggregator.get_progress_message) | ||
350 | 1395 | |||
351 | 1396 | def test_get_final_status_message(self): | 1162 | def test_get_final_status_message(self): |
352 | 1397 | """The final status message.""" | 1163 | """The final status message.""" |
353 | 1398 | done = (5, 10) | 1164 | done = (5, 10) |
354 | @@ -1438,11 +1204,6 @@ | |||
355 | 1438 | result = self.aggregator.get_final_status_message() | 1204 | result = self.aggregator.get_final_status_message() |
356 | 1439 | self.assertEqual(expected, result) | 1205 | self.assertEqual(expected, result) |
357 | 1440 | 1206 | ||
358 | 1441 | def test_started_progress_bubble(self): | ||
359 | 1442 | """The progress bubble is started.""" | ||
360 | 1443 | self.aggregator.restart_progress_bubble() | ||
361 | 1444 | self.assertTrue(self.aggregator.progress_bubble.started) | ||
362 | 1445 | |||
363 | 1446 | def test_queue_done_shows_bubble_when_downloads_happened(self): | 1207 | def test_queue_done_shows_bubble_when_downloads_happened(self): |
364 | 1447 | """On queue done, show final bubble if downloads happened.""" | 1208 | """On queue done, show final bubble if downloads happened.""" |
365 | 1448 | fc = FakeCommand() | 1209 | fc = FakeCommand() |
366 | @@ -1450,6 +1211,7 @@ | |||
367 | 1450 | self.status_frontend.download_finished(fc) | 1211 | self.status_frontend.download_finished(fc) |
368 | 1451 | old_final_bubble = self.aggregator.final_status_bubble | 1212 | old_final_bubble = self.aggregator.final_status_bubble |
369 | 1452 | self.aggregator.queue_done() | 1213 | self.aggregator.queue_done() |
370 | 1214 | self.aggregator.clock.advance(self.aggregator.finished_delay + 1) | ||
371 | 1453 | self.assertTrue(old_final_bubble.shown) | 1215 | self.assertTrue(old_final_bubble.shown) |
372 | 1454 | 1216 | ||
373 | 1455 | def test_queue_done_shows_bubble_when_uploads_happened(self): | 1217 | def test_queue_done_shows_bubble_when_uploads_happened(self): |
374 | @@ -1459,6 +1221,24 @@ | |||
375 | 1459 | self.status_frontend.upload_finished(fc) | 1221 | self.status_frontend.upload_finished(fc) |
376 | 1460 | old_final_bubble = self.aggregator.final_status_bubble | 1222 | old_final_bubble = self.aggregator.final_status_bubble |
377 | 1461 | self.aggregator.queue_done() | 1223 | self.aggregator.queue_done() |
378 | 1224 | self.aggregator.clock.advance(self.aggregator.finished_delay + 1) | ||
379 | 1225 | self.assertTrue(old_final_bubble.shown) | ||
380 | 1226 | |||
381 | 1227 | def test_queue_done_shows_bubble_only_after_delay(self): | ||
382 | 1228 | """On queue_done, show final bubble only after a delay.""" | ||
383 | 1229 | fc = FakeCommand() | ||
384 | 1230 | self.status_frontend.upload_started(fc) | ||
385 | 1231 | self.status_frontend.upload_finished(fc) | ||
386 | 1232 | old_final_bubble = self.aggregator.final_status_bubble | ||
387 | 1233 | self.aggregator.queue_done() | ||
388 | 1234 | self.assertFalse(old_final_bubble.shown) | ||
389 | 1235 | self.aggregator.clock.advance(self.aggregator.finished_delay - 1) | ||
390 | 1236 | self.assertFalse(old_final_bubble.shown) | ||
391 | 1237 | self.aggregator.queue_done() | ||
392 | 1238 | self.assertFalse(old_final_bubble.shown) | ||
393 | 1239 | self.aggregator.clock.advance(2) | ||
394 | 1240 | self.assertFalse(old_final_bubble.shown) | ||
395 | 1241 | self.aggregator.clock.advance(self.aggregator.finished_delay + 1) | ||
396 | 1462 | self.assertTrue(old_final_bubble.shown) | 1242 | self.assertTrue(old_final_bubble.shown) |
397 | 1463 | 1243 | ||
398 | 1464 | def test_queue_done_does_not_show_bubble_when_no_transfers_happened(self): | 1244 | def test_queue_done_does_not_show_bubble_when_no_transfers_happened(self): |
399 | @@ -1474,6 +1254,7 @@ | |||
400 | 1474 | fc = FakeCommand() | 1254 | fc = FakeCommand() |
401 | 1475 | self.status_frontend.upload_started(fc) | 1255 | self.status_frontend.upload_started(fc) |
402 | 1476 | self.aggregator.queue_done() | 1256 | self.aggregator.queue_done() |
403 | 1257 | self.aggregator.clock.advance(self.aggregator.finished_delay + 1) | ||
404 | 1477 | self.assertStatusReset() | 1258 | self.assertStatusReset() |
405 | 1478 | self.assertEqual(0.0, self.aggregator.progress_bar.progress) | 1259 | self.assertEqual(0.0, self.aggregator.progress_bar.progress) |
406 | 1479 | self.assertFalse(self.aggregator.progress_bar.visible) | 1260 | self.assertFalse(self.aggregator.progress_bar.visible) |
407 | @@ -1524,7 +1305,6 @@ | |||
408 | 1524 | sf = aggregator.StatusFrontend(clock=clock) | 1305 | sf = aggregator.StatusFrontend(clock=clock) |
409 | 1525 | sf.set_show_all_notifications(True) | 1306 | sf.set_show_all_notifications(True) |
410 | 1526 | 1307 | ||
411 | 1527 | clock.advance(aggregator.ProgressBubble.sleep_delay) | ||
412 | 1528 | # the progress bar is not visible yet | 1308 | # the progress bar is not visible yet |
413 | 1529 | self.assertFalse(sf.aggregator.progress_bar.visible) | 1309 | self.assertFalse(sf.aggregator.progress_bar.visible) |
414 | 1530 | sf.upload_started(upload) | 1310 | sf.upload_started(upload) |
415 | @@ -1548,25 +1328,12 @@ | |||
416 | 1548 | clock.advance(aggregator.FileDiscoveryUpdateState.updates_timeout - | 1328 | clock.advance(aggregator.FileDiscoveryUpdateState.updates_timeout - |
417 | 1549 | aggregator.FileDiscoveryUpdateState.updates_delay) | 1329 | aggregator.FileDiscoveryUpdateState.updates_delay) |
418 | 1550 | sf.upload_finished(upload) | 1330 | sf.upload_finished(upload) |
419 | 1551 | # the progress bubble has no notifications yet | ||
420 | 1552 | self.assertEqual(None, sf.aggregator.progress_bubble.notification) | ||
421 | 1553 | clock.advance(aggregator.ProgressBubble.sleep_delay) | ||
422 | 1554 | # the progress bubble is shown | ||
423 | 1555 | self.assertEqual(3, len(notifications_shown)) | ||
424 | 1556 | sf.upload_finished(download) | 1331 | sf.upload_finished(download) |
425 | 1557 | # the progress still is now 100% | 1332 | # the progress still is now 100% |
426 | 1558 | self.assertEqual(1.0, sf.aggregator.progress_bar.progress) | 1333 | self.assertEqual(1.0, sf.aggregator.progress_bar.progress) |
427 | 1559 | # progress, but the progress bubble is not updated immediately | ||
428 | 1560 | self.assertEqual(3, len(notifications_shown)) | ||
429 | 1561 | clock.advance(aggregator.ProgressBubble.sleep_delay) | ||
430 | 1562 | # the progress bubble is updated after a delay | ||
431 | 1563 | self.assertEqual(4, len(notifications_shown)) | ||
432 | 1564 | sf.queue_done() | 1334 | sf.queue_done() |
438 | 1565 | # the final bubble is shown immediately | 1335 | clock.advance(sf.aggregator.finished_delay + 1) |
439 | 1566 | self.assertEqual(5, len(notifications_shown)) | 1336 | self.assertEqual(3, len(notifications_shown)) |
435 | 1567 | clock.advance(aggregator.ProgressBubble.sleep_delay * 2) | ||
436 | 1568 | # no more notifications are shown | ||
437 | 1569 | self.assertEqual(5, len(notifications_shown)) | ||
440 | 1570 | 1337 | ||
441 | 1571 | def test_all_together_now_off(self): | 1338 | def test_all_together_now_off(self): |
442 | 1572 | """Make all parts work together, but with notifications off.""" | 1339 | """Make all parts work together, but with notifications off.""" |
443 | @@ -1579,7 +1346,6 @@ | |||
444 | 1579 | sf = aggregator.StatusFrontend(clock=clock) | 1346 | sf = aggregator.StatusFrontend(clock=clock) |
445 | 1580 | sf.set_show_all_notifications(False) | 1347 | sf.set_show_all_notifications(False) |
446 | 1581 | 1348 | ||
447 | 1582 | clock.advance(aggregator.ProgressBubble.sleep_delay) | ||
448 | 1583 | # the progress bar is not visible yet | 1349 | # the progress bar is not visible yet |
449 | 1584 | self.assertFalse(sf.aggregator.progress_bar.visible) | 1350 | self.assertFalse(sf.aggregator.progress_bar.visible) |
450 | 1585 | sf.upload_started(upload) | 1351 | sf.upload_started(upload) |
451 | @@ -1601,17 +1367,9 @@ | |||
452 | 1601 | clock.advance(aggregator.FileDiscoveryUpdateState.updates_timeout - | 1367 | clock.advance(aggregator.FileDiscoveryUpdateState.updates_timeout - |
453 | 1602 | aggregator.FileDiscoveryUpdateState.updates_delay) | 1368 | aggregator.FileDiscoveryUpdateState.updates_delay) |
454 | 1603 | sf.upload_finished(upload) | 1369 | sf.upload_finished(upload) |
455 | 1604 | # the progress bubble has no notifications yet | ||
456 | 1605 | self.assertEqual(None, sf.aggregator.progress_bubble.notification) | ||
457 | 1606 | clock.advance(aggregator.ProgressBubble.sleep_delay) | ||
458 | 1607 | self.assertEqual(0, len(notifications_shown)) | ||
459 | 1608 | sf.upload_finished(download) | 1370 | sf.upload_finished(download) |
460 | 1609 | # the progress still is now 100% | 1371 | # the progress still is now 100% |
461 | 1610 | self.assertEqual(1.0, sf.aggregator.progress_bar.progress) | 1372 | self.assertEqual(1.0, sf.aggregator.progress_bar.progress) |
462 | 1611 | self.assertEqual(0, len(notifications_shown)) | 1373 | self.assertEqual(0, len(notifications_shown)) |
463 | 1612 | clock.advance(aggregator.ProgressBubble.sleep_delay) | ||
464 | 1613 | self.assertEqual(0, len(notifications_shown)) | ||
465 | 1614 | sf.queue_done() | 1374 | sf.queue_done() |
466 | 1615 | self.assertEqual(0, len(notifications_shown)) | 1375 | self.assertEqual(0, len(notifications_shown)) |
467 | 1616 | clock.advance(aggregator.ProgressBubble.sleep_delay * 2) | ||
468 | 1617 | self.assertEqual(0, len(notifications_shown)) | ||
469 | 1618 | 1376 | ||
470 | === modified file 'tests/syncdaemon/test_status_listener.py' | |||
471 | --- tests/syncdaemon/test_status_listener.py 2011-02-09 08:23:04 +0000 | |||
472 | +++ tests/syncdaemon/test_status_listener.py 2011-03-23 20:01:28 +0000 | |||
473 | @@ -250,32 +250,6 @@ | |||
474 | 250 | self.assertIn(call, self.status_frontend.call_log) | 250 | self.assertIn(call, self.status_frontend.call_log) |
475 | 251 | 251 | ||
476 | 252 | @defer.inlineCallbacks | 252 | @defer.inlineCallbacks |
477 | 253 | def test_queue_added_is_forwarded(self): | ||
478 | 254 | """A misc queue added event is forwarded.""" | ||
479 | 255 | fake_command = object() | ||
480 | 256 | |||
481 | 257 | d = defer.Deferred() | ||
482 | 258 | self._listen_for('SYS_QUEUE_ADDED', d.callback) | ||
483 | 259 | self.main.event_q.push('SYS_QUEUE_ADDED', command=fake_command) | ||
484 | 260 | yield d | ||
485 | 261 | |||
486 | 262 | call = ("queue_added", (fake_command,), {}) | ||
487 | 263 | self.assertIn(call, self.status_frontend.call_log) | ||
488 | 264 | |||
489 | 265 | @defer.inlineCallbacks | ||
490 | 266 | def test_queue_removed_is_forwarded(self): | ||
491 | 267 | """A queue removed event is forwarded.""" | ||
492 | 268 | fake_command = object() | ||
493 | 269 | |||
494 | 270 | d = defer.Deferred() | ||
495 | 271 | self._listen_for('SYS_QUEUE_REMOVED', d.callback) | ||
496 | 272 | self.main.event_q.push('SYS_QUEUE_REMOVED', command=fake_command) | ||
497 | 273 | yield d | ||
498 | 274 | |||
499 | 275 | call = ("queue_removed", (fake_command,), {}) | ||
500 | 276 | self.assertIn(call, self.status_frontend.call_log) | ||
501 | 277 | |||
502 | 278 | @defer.inlineCallbacks | ||
503 | 279 | def test_queue_done_is_forwarded(self): | 253 | def test_queue_done_is_forwarded(self): |
504 | 280 | """A queue done event is forwarded.""" | 254 | """A queue done event is forwarded.""" |
505 | 281 | d = defer.Deferred() | 255 | d = defer.Deferred() |
506 | 282 | 256 | ||
507 | === modified file 'ubuntuone/status/aggregator.py' | |||
508 | --- ubuntuone/status/aggregator.py 2011-03-22 17:20:50 +0000 | |||
509 | +++ ubuntuone/status/aggregator.py 2011-03-23 20:01:28 +0000 | |||
510 | @@ -465,17 +465,17 @@ | |||
511 | 465 | def _popup(self): | 465 | def _popup(self): |
512 | 466 | """Display the notification.""" | 466 | """Display the notification.""" |
513 | 467 | text = self.status_aggregator.get_discovery_message() | 467 | text = self.status_aggregator.get_discovery_message() |
517 | 468 | self.notification.send_notification(UBUNTUONE_TITLE, text) | 468 | if text: |
518 | 469 | self.status_aggregator.restart_progress_bubble() | 469 | self.notification.send_notification(UBUNTUONE_TITLE, text) |
519 | 470 | logger.debug("notification shown: %s", text) | 470 | logger.debug("notification shown: %s", text) |
520 | 471 | self._change_state(FileDiscoveryUpdateState) | 471 | self._change_state(FileDiscoveryUpdateState) |
521 | 472 | 472 | ||
522 | 473 | def _update(self): | 473 | def _update(self): |
523 | 474 | """Update the notification.""" | 474 | """Update the notification.""" |
524 | 475 | text = self.status_aggregator.get_discovery_message() | 475 | text = self.status_aggregator.get_discovery_message() |
528 | 476 | logger.debug("notification updated: %s", text) | 476 | if text: |
529 | 477 | self.status_aggregator.restart_progress_bubble() | 477 | logger.debug("notification updated: %s", text) |
530 | 478 | self.notification.send_notification(UBUNTUONE_TITLE, text) | 478 | self.notification.send_notification(UBUNTUONE_TITLE, text) |
531 | 479 | 479 | ||
532 | 480 | def start_sleeping(self): | 480 | def start_sleeping(self): |
533 | 481 | """Wait for 10 minutes before annoying again.""" | 481 | """Wait for 10 minutes before annoying again.""" |
534 | @@ -490,39 +490,6 @@ | |||
535 | 490 | self.state.new_file_found() | 490 | self.state.new_file_found() |
536 | 491 | 491 | ||
537 | 492 | 492 | ||
538 | 493 | class ProgressBubble(object): | ||
539 | 494 | """Show a notification for transfer progress.""" | ||
540 | 495 | |||
541 | 496 | sleep_delay = 600 | ||
542 | 497 | notification = None | ||
543 | 498 | timer = None | ||
544 | 499 | |||
545 | 500 | def __init__(self, status_aggregator, clock=reactor): | ||
546 | 501 | """Initialize this instance.""" | ||
547 | 502 | self.status_aggregator = status_aggregator | ||
548 | 503 | self.clock = clock | ||
549 | 504 | |||
550 | 505 | def restart(self): | ||
551 | 506 | """Start running the timer.""" | ||
552 | 507 | self.cleanup() | ||
553 | 508 | self.timer = Timer(self.sleep_delay, clock=self.clock) | ||
554 | 509 | self.timer.addCallback(self._timeout) | ||
555 | 510 | |||
556 | 511 | def _timeout(self, _): | ||
557 | 512 | """Show the bubble.""" | ||
558 | 513 | self.notification = self.status_aggregator.get_notification() | ||
559 | 514 | text = self.status_aggregator.get_progress_message() | ||
560 | 515 | self.notification.send_notification(UBUNTUONE_TITLE, text) | ||
561 | 516 | self.restart() | ||
562 | 517 | |||
563 | 518 | def cleanup(self): | ||
564 | 519 | """Cleanup this instance.""" | ||
565 | 520 | if self.timer: | ||
566 | 521 | self.timer.cleanup() | ||
567 | 522 | |||
568 | 523 | stop = cleanup | ||
569 | 524 | |||
570 | 525 | |||
571 | 526 | class ProgressBar(object): | 493 | class ProgressBar(object): |
572 | 527 | """Update a progressbar no more than 10 times a second.""" | 494 | """Update a progressbar no more than 10 times a second.""" |
573 | 528 | pulsating = True | 495 | pulsating = True |
574 | @@ -624,15 +591,16 @@ | |||
575 | 624 | """The status aggregator backend.""" | 591 | """The status aggregator backend.""" |
576 | 625 | 592 | ||
577 | 626 | file_discovery_bubble = None | 593 | file_discovery_bubble = None |
578 | 627 | progress_bubble = None | ||
579 | 628 | final_status_bubble = None | 594 | final_status_bubble = None |
580 | 629 | 595 | ||
581 | 630 | def __init__(self, clock=reactor): | 596 | def __init__(self, clock=reactor): |
582 | 631 | """Initialize this instance.""" | 597 | """Initialize this instance.""" |
583 | 632 | self.clock = clock | 598 | self.clock = clock |
584 | 633 | self.notification_switch = NotificationSwitch() | 599 | self.notification_switch = NotificationSwitch() |
585 | 600 | self.queue_done_timer = None | ||
586 | 634 | self.reset() | 601 | self.reset() |
587 | 635 | self.progress_bar = ProgressBar(clock=self.clock) | 602 | self.progress_bar = ProgressBar(clock=self.clock) |
588 | 603 | self.finished_delay = 10 | ||
589 | 636 | 604 | ||
590 | 637 | def get_notification(self): | 605 | def get_notification(self): |
591 | 638 | """Create a new toggleable notification object.""" | 606 | """Create a new toggleable notification object.""" |
592 | @@ -651,16 +619,14 @@ | |||
593 | 651 | self.uploading_filename = '' | 619 | self.uploading_filename = '' |
594 | 652 | self.files_downloading = [] | 620 | self.files_downloading = [] |
595 | 653 | self.downloading_filename = '' | 621 | self.downloading_filename = '' |
596 | 622 | if self.queue_done_timer is not None: | ||
597 | 623 | self.queue_done_timer.cleanup() | ||
598 | 654 | 624 | ||
599 | 655 | if self.file_discovery_bubble: | 625 | if self.file_discovery_bubble: |
600 | 656 | self.file_discovery_bubble.cleanup() | 626 | self.file_discovery_bubble.cleanup() |
601 | 657 | self.file_discovery_bubble = FileDiscoveryBubble(self, | 627 | self.file_discovery_bubble = FileDiscoveryBubble(self, |
602 | 658 | clock=self.clock) | 628 | clock=self.clock) |
603 | 659 | 629 | ||
604 | 660 | if self.progress_bubble: | ||
605 | 661 | self.progress_bubble.cleanup() | ||
606 | 662 | self.progress_bubble = ProgressBubble(self, clock=self.clock) | ||
607 | 663 | |||
608 | 664 | if self.final_status_bubble: | 630 | if self.final_status_bubble: |
609 | 665 | self.final_status_bubble.cleanup() | 631 | self.final_status_bubble.cleanup() |
610 | 666 | self.final_status_bubble = FinalStatusBubble(self) | 632 | self.final_status_bubble = FinalStatusBubble(self) |
611 | @@ -681,23 +647,6 @@ | |||
612 | 681 | self.downloading_filename, files_downloading)) | 647 | self.downloading_filename, files_downloading)) |
613 | 682 | return "\n".join(lines) | 648 | return "\n".join(lines) |
614 | 683 | 649 | ||
615 | 684 | def get_progress_message(self): | ||
616 | 685 | """Get some lines describing the progress.""" | ||
617 | 686 | assert self.total_counter > 0 | ||
618 | 687 | parts = [] | ||
619 | 688 | upload_total = self.upload_total | ||
620 | 689 | if upload_total: | ||
621 | 690 | parts.append(files_being_uploaded( | ||
622 | 691 | self.uploading_filename, upload_total)) | ||
623 | 692 | download_total = self.download_total | ||
624 | 693 | if download_total: | ||
625 | 694 | parts.append(files_being_downloaded( | ||
626 | 695 | self.downloading_filename, download_total)) | ||
627 | 696 | progress_percentage = 100.0 * self.done_counter / self.total_counter | ||
628 | 697 | format_args = {"percentage_completed": int(progress_percentage)} | ||
629 | 698 | parts.append(PROGRESS_COMPLETED % format_args) | ||
630 | 699 | return "\n".join(parts) | ||
631 | 700 | |||
632 | 701 | def get_final_status_message(self): | 650 | def get_final_status_message(self): |
633 | 702 | """Get some lines describing all we did.""" | 651 | """Get some lines describing all we did.""" |
634 | 703 | parts = [] | 652 | parts = [] |
635 | @@ -713,45 +662,48 @@ | |||
636 | 713 | self.downloading_filename, download_done)) | 662 | self.downloading_filename, download_done)) |
637 | 714 | return "\n".join(parts) | 663 | return "\n".join(parts) |
638 | 715 | 664 | ||
644 | 716 | def restart_progress_bubble(self): | 665 | def _queue_done(self, _): |
640 | 717 | """Restart the progress bubble.""" | ||
641 | 718 | self.progress_bubble.restart() | ||
642 | 719 | |||
643 | 720 | def queue_done(self): | ||
645 | 721 | """Show final bubble and reset counters.""" | 666 | """Show final bubble and reset counters.""" |
646 | 667 | self.queue_done_timer.cleanup() | ||
647 | 668 | self.queue_done_timer = None | ||
648 | 669 | logger.debug("queue done callback fired") | ||
649 | 722 | if self.upload_done + self.download_done > 0: | 670 | if self.upload_done + self.download_done > 0: |
650 | 723 | self.final_status_bubble.show() | 671 | self.final_status_bubble.show() |
651 | 724 | self.progress_bar.completed() | 672 | self.progress_bar.completed() |
652 | 725 | self.reset() | 673 | self.reset() |
653 | 726 | 674 | ||
660 | 727 | def misc_command_queued(self, command): | 675 | def queue_done(self): |
661 | 728 | """A miscellaneous command was queued.""" | 676 | """Queue is finished.""" |
662 | 729 | self.total_counter += 1 | 677 | if not self.total_counter: |
663 | 730 | logger.debug("queueing command (%d/%d): %s", self.done_counter, | 678 | return |
664 | 731 | self.total_counter, command.__class__.__name__) | 679 | if self.queue_done_timer is None: |
665 | 732 | self.update_progressbar() | 680 | logger.debug("queue done callback added") |
666 | 681 | self.queue_done_timer = Timer( | ||
667 | 682 | self.finished_delay, clock=self.clock) | ||
668 | 683 | self.queue_done_timer.addCallback(self._queue_done) | ||
669 | 684 | return | ||
670 | 685 | logger.debug("queue done callback reset") | ||
671 | 686 | self.queue_done_timer.reset() | ||
672 | 733 | 687 | ||
673 | 734 | def update_progressbar(self): | 688 | def update_progressbar(self): |
674 | 735 | """Update the counters of the progressbar.""" | 689 | """Update the counters of the progressbar.""" |
675 | 736 | self.progress_bar.progress_made(self.done_counter, self.total_counter) | 690 | self.progress_bar.progress_made(self.done_counter, self.total_counter) |
676 | 737 | 691 | ||
677 | 738 | def misc_command_unqueued(self, command): | ||
678 | 739 | """A miscellaneous command was unqueued.""" | ||
679 | 740 | self.done_counter += 1 | ||
680 | 741 | logger.debug("unqueueing command (%d/%d): %s", self.done_counter, | ||
681 | 742 | self.total_counter, command.__class__.__name__) | ||
682 | 743 | self.update_progressbar() | ||
683 | 744 | |||
684 | 745 | def download_started(self, command): | 692 | def download_started(self, command): |
685 | 746 | """A download just started.""" | 693 | """A download just started.""" |
686 | 694 | if self.queue_done_timer is not None: | ||
687 | 695 | self.queue_done_timer.reset() | ||
688 | 747 | self.files_downloading.append(command) | 696 | self.files_downloading.append(command) |
689 | 748 | self.download_total += 1 | 697 | self.download_total += 1 |
690 | 698 | self.total_counter += 1 | ||
691 | 749 | # pylint: disable=W0201 | 699 | # pylint: disable=W0201 |
692 | 750 | if not self.downloading_filename: | 700 | if not self.downloading_filename: |
693 | 751 | self.downloading_filename = self.files_downloading[0].path.split( | 701 | self.downloading_filename = self.files_downloading[0].path.split( |
694 | 752 | os.path.sep)[-1] | 702 | os.path.sep)[-1] |
695 | 753 | # pylint: enable=W0201 | 703 | # pylint: enable=W0201 |
697 | 754 | self.misc_command_queued(command) | 704 | self.update_progressbar() |
698 | 705 | logger.debug("queueing command (%d/%d): %s", self.done_counter, | ||
699 | 706 | self.total_counter, command.__class__.__name__) | ||
700 | 755 | self.file_discovery_bubble.new_file_found() | 707 | self.file_discovery_bubble.new_file_found() |
701 | 756 | 708 | ||
702 | 757 | def download_finished(self, command): | 709 | def download_finished(self, command): |
703 | @@ -759,18 +711,26 @@ | |||
704 | 759 | if command in self.files_downloading: | 711 | if command in self.files_downloading: |
705 | 760 | self.files_downloading.remove(command) | 712 | self.files_downloading.remove(command) |
706 | 761 | self.download_done += 1 | 713 | self.download_done += 1 |
708 | 762 | self.misc_command_unqueued(command) | 714 | self.done_counter += 1 |
709 | 715 | logger.debug("unqueueing command (%d/%d): %s", self.done_counter, | ||
710 | 716 | self.total_counter, command.__class__.__name__) | ||
711 | 717 | self.update_progressbar() | ||
712 | 763 | 718 | ||
713 | 764 | def upload_started(self, command): | 719 | def upload_started(self, command): |
714 | 765 | """An upload just started.""" | 720 | """An upload just started.""" |
715 | 721 | if self.queue_done_timer is not None: | ||
716 | 722 | self.queue_done_timer.reset() | ||
717 | 766 | self.files_uploading.append(command) | 723 | self.files_uploading.append(command) |
718 | 767 | self.upload_total += 1 | 724 | self.upload_total += 1 |
719 | 725 | self.total_counter += 1 | ||
720 | 768 | # pylint: disable=W0201 | 726 | # pylint: disable=W0201 |
721 | 769 | if not self.uploading_filename: | 727 | if not self.uploading_filename: |
722 | 770 | self.uploading_filename = self.files_uploading[0].path.split( | 728 | self.uploading_filename = self.files_uploading[0].path.split( |
723 | 771 | os.path.sep)[-1] | 729 | os.path.sep)[-1] |
724 | 772 | # pylint: enable=W0201 | 730 | # pylint: enable=W0201 |
726 | 773 | self.misc_command_queued(command) | 731 | self.update_progressbar() |
727 | 732 | logger.debug("queueing command (%d/%d): %s", self.done_counter, | ||
728 | 733 | self.total_counter, command.__class__.__name__) | ||
729 | 774 | self.file_discovery_bubble.new_file_found() | 734 | self.file_discovery_bubble.new_file_found() |
730 | 775 | 735 | ||
731 | 776 | def upload_finished(self, command): | 736 | def upload_finished(self, command): |
732 | @@ -778,7 +738,10 @@ | |||
733 | 778 | if command in self.files_uploading: | 738 | if command in self.files_uploading: |
734 | 779 | self.files_uploading.remove(command) | 739 | self.files_uploading.remove(command) |
735 | 780 | self.upload_done += 1 | 740 | self.upload_done += 1 |
737 | 781 | self.misc_command_unqueued(command) | 741 | self.done_counter += 1 |
738 | 742 | logger.debug("unqueueing command (%d/%d): %s", self.done_counter, | ||
739 | 743 | self.total_counter, command.__class__.__name__) | ||
740 | 744 | self.update_progressbar() | ||
741 | 782 | 745 | ||
742 | 783 | def connection_lost(self): | 746 | def connection_lost(self): |
743 | 784 | """The connection to the server was lost.""" | 747 | """The connection to the server was lost.""" |
744 | @@ -826,14 +789,6 @@ | |||
745 | 826 | """A file upload was unqueued.""" | 789 | """A file upload was unqueued.""" |
746 | 827 | self.aggregator.upload_finished(command) | 790 | self.aggregator.upload_finished(command) |
747 | 828 | 791 | ||
748 | 829 | def queue_added(self, command): | ||
749 | 830 | """A command was added to the queue.""" | ||
750 | 831 | self.aggregator.misc_command_queued(command) | ||
751 | 832 | |||
752 | 833 | def queue_removed(self, command): | ||
753 | 834 | """A command was removed from the queue.""" | ||
754 | 835 | self.aggregator.misc_command_unqueued(command) | ||
755 | 836 | |||
756 | 837 | def queue_done(self): | 792 | def queue_done(self): |
757 | 838 | """The queue is empty.""" | 793 | """The queue is empty.""" |
758 | 839 | self.aggregator.queue_done() | 794 | self.aggregator.queue_done() |
759 | 840 | 795 | ||
760 | === modified file 'ubuntuone/syncdaemon/status_listener.py' | |||
761 | --- ubuntuone/syncdaemon/status_listener.py 2011-02-09 08:23:04 +0000 | |||
762 | +++ ubuntuone/syncdaemon/status_listener.py 2011-03-23 20:01:28 +0000 | |||
763 | @@ -60,7 +60,7 @@ | |||
764 | 60 | set_show_all_notifications) | 60 | set_show_all_notifications) |
765 | 61 | 61 | ||
766 | 62 | def handle_AQ_CHANGE_PUBLIC_ACCESS_OK(self, share_id, node_id, is_public, | 62 | def handle_AQ_CHANGE_PUBLIC_ACCESS_OK(self, share_id, node_id, is_public, |
768 | 63 | public_url): | 63 | public_url): |
769 | 64 | """The status of a published resource changed.""" | 64 | """The status of a published resource changed.""" |
770 | 65 | if is_public: | 65 | if is_public: |
771 | 66 | self.status_frontend.file_published(public_url) | 66 | self.status_frontend.file_published(public_url) |
772 | @@ -73,8 +73,6 @@ | |||
773 | 73 | self.status_frontend.download_started(command) | 73 | self.status_frontend.download_started(command) |
774 | 74 | elif isinstance(command, action_queue.Upload): | 74 | elif isinstance(command, action_queue.Upload): |
775 | 75 | self.status_frontend.upload_started(command) | 75 | self.status_frontend.upload_started(command) |
776 | 76 | else: | ||
777 | 77 | self.status_frontend.queue_added(command) | ||
778 | 78 | 76 | ||
779 | 79 | def handle_SYS_QUEUE_REMOVED(self, command): | 77 | def handle_SYS_QUEUE_REMOVED(self, command): |
780 | 80 | """A command has been removed from the queue.""" | 78 | """A command has been removed from the queue.""" |
781 | @@ -82,8 +80,6 @@ | |||
782 | 82 | self.status_frontend.download_finished(command) | 80 | self.status_frontend.download_finished(command) |
783 | 83 | elif isinstance(command, action_queue.Upload): | 81 | elif isinstance(command, action_queue.Upload): |
784 | 84 | self.status_frontend.upload_finished(command) | 82 | self.status_frontend.upload_finished(command) |
785 | 85 | else: | ||
786 | 86 | self.status_frontend.queue_removed(command) | ||
787 | 87 | 83 | ||
788 | 88 | def handle_SYS_QUEUE_DONE(self): | 84 | def handle_SYS_QUEUE_DONE(self): |
789 | 89 | """The queue has finished processing everything.""" | 85 | """The queue has finished processing everything.""" |
Looks sane to me. I might have picked 10s from past experience with this exact problem, but we'll see how 5s works. :)