--- a/ui.py Wed Jan 24 09:19:42 2018 +0000 +++ b/ui.py Wed Jan 24 20:18:45 2018 +0000 @@ -14,26 +14,32 @@ logger=borgend.logger.getChild(__name__) -traynames={ - backup.INACTIVE: 'B.', - backup.SCHEDULED: 'B.', - backup.QUEUED: 'B:', - backup.ACTIVE: 'B!', - backup.BUSY: 'B⦙', - backup.OFFLINE: 'B⦙', - backup.ERRORS: 'B?' +traynames_ok={ + backup.State.INACTIVE: 'B.', + backup.State.SCHEDULED: 'B.', + backup.State.QUEUED: 'B:', + backup.State.ACTIVE: 'B!', } -statestring={ - backup.INACTIVE: 'inactive', - backup.SCHEDULED: 'scheduled', - backup.QUEUED: 'queued', - backup.ACTIVE: 'active', - backup.BUSY: 'busy', - backup.OFFLINE: 'offline', - backup.ERRORS: 'errors' +traynames_errors={ + # The first one should never be used + backup.Errors.OK: traynames_ok[backup.State.INACTIVE], + backup.Errors.BUSY: 'B⦙', + backup.Errors.OFFLINE: 'B⦙', + backup.Errors.ERRORS: 'B?' } +def trayname(ste): + state=ste[0] + errors=ste[1] + if not errors.ok(): + return traynames_errors[errors] + else: + return traynames_ok[state] + +def combine_state(a, b): + return (max(a[0], b[0]), max(a[1], b[1])) + # Refresh the menu at most once a second to reduce flicker refresh_interval=1.0 @@ -70,9 +76,19 @@ return '{0:.2f}TB'.format(B/TB) def make_title(status): - state=status['state'] - detail='' - if status['type']=='scheduled': + def add_detail(detail, new): + if detail: + return "%s; %s" % (detail, new) + else: + return new + + errors=status['errors'] + detail=None + + if not errors.ok(): + detail=add_detail(detail, str(errors)) + + if status['state']==backup.State.SCHEDULED: # Operation scheduled when=status['when'] now=time.time() @@ -91,15 +107,17 @@ twhen=time.localtime(when+30) whenstr='at %02d:%02d' % (twhen.tm_hour, twhen.tm_min) - detail='' - if state>=backup.BUSY and state in statestring: - detail=statestring[state] + '; ' + this_detail='' if status['detail']!='normal': - detail=detail+status['detail']+' ' - title="%s (%s%s %s)" % (status['name'], detail, status['operation'], whenstr) - elif status['type']=='queued': - title="%s (queued)" % status['name'] - elif status['type']=='current': + this_detail=status['detail'] + ' ' + + when_how_sched= "%s%s %s" % (this_detail, status['operation'], whenstr) + + detail=add_detail(detail, when_how_sched) + + elif status['state']==backup.State.QUEUED: + detail=add_detail(detail, "queued") + elif status['state']==backup.State.ACTIVE: # Operation running progress='' if 'progress_current' in status and 'progress_total' in status: @@ -107,15 +125,19 @@ elif 'original_size' in status and 'deduplicated_size' in status: progress=' %s→%s' % (humanbytes(status['original_size']), humanbytes(status['deduplicated_size'])) - title="%s (running: %s%s)" % (status['name'], status['operation'], progress) - else: # status['type']=='nothing': - # Should be unscheduled, nothing running - detail='' - if state>=backup.BUSY and state in statestring: - detail=' (' + statestring[state] + ')' - title=status['name'] + detail + + howrunning = "running %s%s" % (status['operation'], progress) + + detail=add_detail(detail, howrunning) + else: + pass - return title, state + if detail: + title=status['name'] + ' (' + detail + ')' + else: + title=status['name'] + + return title, (status['state'], status['errors']) class BorgendTray(rumps.App): def __init__(self, backups): @@ -143,11 +165,11 @@ self.refresh_timer=None - super().__init__(traynames[state], menu=menu, quit_button=None) + super().__init__(trayname(state), menu=menu, quit_button=None) def __rebuild_menu(self): menu=[] - state=backup.INACTIVE + state=(backup.State.INACTIVE, backup.Errors.OK) for index in range(len(self.backups)): b=self.backups[index] title, this_state=make_title(self.statuses[index]) @@ -156,12 +178,12 @@ # fixes this brain damage cbm=lambda sender, _b=b: self.__menu_select_backup(sender, _b) item=rumps.MenuItem(title, callback=cbm) - if this_state==backup.SCHEDULED: + if not this_state[1].ok(): + item.state=-1 + elif this_state[0]==backup.State.SCHEDULED or this_state[0]==backup.State.QUEUED: item.state=1 - elif this_state>=backup.BUSY: - item.state=-1 menu.append(item) - state=backup.combine_state(state, this_state) + state=combine_state(state, this_state) menu_log=rumps.MenuItem("Show log", callback=lambda _: showlog()) menu.append(menu_log) @@ -176,10 +198,10 @@ with self.lock: self.refresh_timer=None logger.debug('Rebuilding menu') - menu, active=self.__rebuild_menu() + menu, state=self.__rebuild_menu() self.menu.clear() self.menu.update(menu) - self.title=traynames[active] + self.title=trayname(state) def __status_callback(self, index, status, errorlog=None): logger.debug('Status callback: %s' % str(status))