18 |
18 |
19 logger=logging.getLogger(__name__) |
19 logger=logging.getLogger(__name__) |
20 |
20 |
21 traynames_ok={ |
21 traynames_ok={ |
22 backup.State.INACTIVE: 'B.', |
22 backup.State.INACTIVE: 'B.', |
|
23 backup.State.PAUSED: 'B‖', |
23 backup.State.SCHEDULED: 'B.', |
24 backup.State.SCHEDULED: 'B.', |
24 backup.State.QUEUED: 'B:', |
25 backup.State.QUEUED: 'B:', |
25 backup.State.ACTIVE: 'B!', |
26 backup.State.ACTIVE: 'B!', |
26 } |
27 } |
27 |
28 |
113 this_need_reconstruct=None |
114 this_need_reconstruct=None |
114 |
115 |
115 if not status.errors.ok(): |
116 if not status.errors.ok(): |
116 info=add_info(info, str(status.errors)) |
117 info=add_info(info, str(status.errors)) |
117 |
118 |
118 if status.state==backup.State.SCHEDULED: |
119 if status.state==backup.State.PAUSED: |
|
120 info=add_info(info, "paused") |
|
121 elif status.state==backup.State.SCHEDULED: |
119 # Operation scheduled |
122 # Operation scheduled |
120 when=status.when() |
123 when=status.when() |
121 now=time.time() |
124 now=time.time() |
122 |
125 |
123 if when<now: |
126 if when<now: |
208 |
211 |
209 def __rebuild_menu(self): |
212 def __rebuild_menu(self): |
210 menu=[] |
213 menu=[] |
211 state=(backup.State.INACTIVE, backup.Errors.OK) |
214 state=(backup.State.INACTIVE, backup.Errors.OK) |
212 need_reconstruct=None |
215 need_reconstruct=None |
|
216 all_paused=True |
|
217 |
213 for index in range(len(self.backups)): |
218 for index in range(len(self.backups)): |
214 b=self.backups[index] |
219 b=self.backups[index] |
215 title, this_state, this_need_reconstruct=make_title(self.statuses[index]) |
220 title, this_state, this_need_reconstruct=make_title(self.statuses[index]) |
216 # Python closures suck dog's balls... |
221 # Python closures suck dog's balls... |
217 # first and the last program I write in Python until somebody |
222 # first and the last program I write in Python until somebody |
223 elif this_state[0]==backup.State.SCHEDULED or this_state[0]==backup.State.QUEUED: |
228 elif this_state[0]==backup.State.SCHEDULED or this_state[0]==backup.State.QUEUED: |
224 item.state=1 |
229 item.state=1 |
225 menu.append(item) |
230 menu.append(item) |
226 state=combine_state(state, this_state) |
231 state=combine_state(state, this_state) |
227 |
232 |
|
233 all_paused=(all_paused and this_state[0]==backup.State.PAUSED) |
|
234 |
228 # Do we have to automatically update menu display? |
235 # Do we have to automatically update menu display? |
229 if not need_reconstruct: |
236 if not need_reconstruct: |
230 need_reconstruct=this_need_reconstruct |
237 need_reconstruct=this_need_reconstruct |
231 elif this_need_reconstruct: |
238 elif this_need_reconstruct: |
232 need_reconstruct=min(need_reconstruct, this_need_reconstruct) |
239 need_reconstruct=min(need_reconstruct, this_need_reconstruct) |
233 |
240 |
234 menu_log=rumps.MenuItem("Show log", callback=lambda _: showlog()) |
241 menu_log=rumps.MenuItem("Show log", callback=lambda _: showlog()) |
235 menu.append(menu_log) |
242 menu.append(menu_log) |
|
243 |
|
244 if all_paused: |
|
245 pausename='Resume all' |
|
246 else: |
|
247 pausename="Pause all" |
|
248 menu_pause=rumps.MenuItem(pausename, callback=lambda _: self.pause_resume_all()) |
|
249 menu.append(menu_pause) |
236 |
250 |
237 if not settings['no_quit_menu_entry']: |
251 if not settings['no_quit_menu_entry']: |
238 menu_quit=rumps.MenuItem("Quit...", callback=lambda _: self.quit()) |
252 menu_quit=rumps.MenuItem("Quit...", callback=lambda _: self.quit()) |
239 menu.append(menu_quit) |
253 menu.append(menu_quit) |
240 |
254 |
287 logger.debug("Opening notification for error %s '%s'", |
301 logger.debug("Opening notification for error %s '%s'", |
288 msgid, errorlog['message']) |
302 msgid, errorlog['message']) |
289 |
303 |
290 notification_workaround(branding.appname_stylised, |
304 notification_workaround(branding.appname_stylised, |
291 msgid, errorlog['message']) |
305 msgid, errorlog['message']) |
|
306 |
|
307 def pause_resume_all(self): |
|
308 with self.lock: |
|
309 try: |
|
310 all_paused=True |
|
311 for b in self.backups: |
|
312 all_paused=all_paused and b.is_paused() |
|
313 if all_paused: |
|
314 logger.debug('Pausing all') |
|
315 for b in self.backups: |
|
316 b.resume() |
|
317 else: |
|
318 logger.debug('Resuming all') |
|
319 for b in self.backups: |
|
320 b.pause() |
|
321 except: |
|
322 logger.exception("Pause/resume error") |
292 |
323 |
293 def quit(self): |
324 def quit(self): |
294 rumps.quit_application() |
325 rumps.quit_application() |
295 |
326 |
296 def __menu_select_backup(self, sender, b): |
327 def __menu_select_backup(self, sender, b): |