# HG changeset patch # User Tuomo Valkonen # Date 1516556755 0 # Node ID 085a635f23f5f5d3575537317225d811395838b7 # Parent 9fab8200f7ebe8e11f84c18934f73899510b55ab Improved error indicators diff -r 9fab8200f7eb -r 085a635f23f5 backup.py --- a/backup.py Sun Jan 21 17:36:03 2018 +0000 +++ b/backup.py Sun Jan 21 17:45:55 2018 +0000 @@ -111,7 +111,7 @@ self.config=config self.lastrun_when=None - self.lastrun_success=None + self.lastrun_errors=None self.borg_instance=None self.current_operation=None self.thread_log=None @@ -210,25 +210,25 @@ res=self.borg_instance.read_result() - success=True + errors=False logger.debug('Borg result: %s' % str(res)) - if res==None: - success=False + if res is None: + errors=True logger.debug('Waiting for borg subprocess to terminate in result thread') - success=success and self.borg_instance.wait() + errors=errors or not self.borg_instance.wait() - logger.debug('Borg subprocess terminated (success: %s); terminating result listener thread' % str(success)) + logger.debug('Borg subprocess terminated (errors: %s); terminating result listener thread' % str(errors)) self.thread_log.join() with self.lock: if self.current_operation['operation']=='create': self.lastrun_when=self.current_operation['when_monotonic'] - self.lastrun_success=success + self.lastrun_errors=errors self.thread_res=None self.thread_log=None self.borg_instance=None @@ -294,7 +294,7 @@ except Exception as err: logger.debug('Rescheduling after failure') self.lastrun_when=time.monotonic() - self.lastrun_success=False + self.lastrun_errors=True self.__schedule_unlocked() raise err @@ -369,7 +369,7 @@ return {'operation': 'create', 'detail': 'initial', 'when_monotonic': now+initial_interval} - elif not self.lastrun_success: + elif self.lastrun_errors: if self.retry_interval==0: return None else: @@ -381,7 +381,7 @@ return None else: return {'operation': 'create', - 'detail': None, + 'detail': 'normal', 'when_monotonic': self.lastrun_when+self.backup_interval} def __schedule_unlocked(self): @@ -413,20 +413,29 @@ def __status_unlocked(self): callback=self.__status_update_callback + if self.current_operation: status=self.current_operation status['type']='current' - elif self.scheduled_operation: - status=self.scheduled_operation - status['type']='scheduled' + # Errors should be set by listeners else: - status={'type': 'nothing'} + if self.scheduled_operation: + status=self.scheduled_operation + status['type']='scheduled' + else: + status={'type': 'nothing'} - status['name']=self.name + if self.lastrun_errors is not None: + status['errors']=self.lastrun_errors + + if 'detail' not in status: + status['detail']='NONE' if 'errors' not in status: status['errors']=False + status['name']=self.name + if 'when_monotonic' in status: status['when']=(status['when_monotonic'] -time.monotonic()+time.time()) diff -r 9fab8200f7eb -r 085a635f23f5 ui.py --- a/ui.py Sun Jan 21 17:36:03 2018 +0000 +++ b/ui.py Sun Jan 21 17:45:55 2018 +0000 @@ -14,12 +14,14 @@ logger=borgend.logger.getChild(__name__) INACTIVE=0 -ACTIVE=1 -OFFLINE=2 -ERRORS=3 +SCHEDULED_OK=1 +ACTIVE=2 +OFFLINE=3 +ERRORS=4 traynames={ INACTIVE: 'B.', + SCHEDULED_OK: 'B.', ACTIVE: 'B!', OFFLINE: 'B⦙', ERRORS: 'B?' @@ -83,11 +85,14 @@ # Round up minute display to avoid user confusion twhen=time.localtime(when+30) whenstr='at %02d:%02d' % (twhen.tm_hour, twhen.tm_min) - detail='' - if 'detail' in status and status['detail']: - if status['detail']=='retry': - state=ERRORS - detail=status['detail']+' ' + + if status['detail']=='normal': + state=SCHEDULED_OK + detail='' + else: + if status['detail']=='retry': + state=ERRORS + detail=status['detail']+' ' title="%s (%s%s %s)" % (status['name'], detail, status['operation'], whenstr) elif status['type']=='current': # Operation running @@ -102,6 +107,8 @@ else: # status['type']=='nothing': # Should be unscheduled, nothing running title=status['name'] + if status['errors']: + title=title + " (errors)" if status['errors']: state=ERRORS @@ -148,6 +155,10 @@ # fixes this brain damage cbm=lambda sender, _b=b: self.__menu_select_backup(sender, _b) item=rumps.MenuItem(title, callback=cbm) + if this_state==SCHEDULED_OK: + item.state=1 + elif this_state>=OFFLINE: + item.state=-1 menu.append(item) state=combine_state(state, this_state)