ui.py

changeset 14
5a988a2c2624
parent 11
0bff53095f28
child 15
aaf1a281a3fe
equal deleted inserted replaced
13:1813654427d7 14:5a988a2c2624
6 import time 6 import time
7 import datetime 7 import datetime
8 import logging 8 import logging
9 from threading import Lock 9 from threading import Lock
10 10
11 traynames={False: 'B.', True: 'B!'} 11 INACTIVE=0
12 ACTIVE=1
13 ERROR=2
14
15 traynames={INACTIVE: 'B.', ACTIVE: 'B!', ERROR: 'B?'}
16
17 def combine_state(state1, state2):
18 if state1==ERROR or state2==ERROR:
19 return ERROR
20 elif state1==ACTIVE or state2==ACTIVE:
21 return ACTIVE
22 else:
23 return INACTIVE
12 24
13 def make_title(status): 25 def make_title(status):
14 active=False 26 state=INACTIVE
15 if status['type']=='scheduled': 27 if status['type']=='scheduled':
16 # Operation scheduled 28 # Operation scheduled
17 when=status['when'] 29 when=status['when']
18 now=time.time() 30 now=time.time()
19 if when<now: 31 if when<now:
29 # Round up minute display to avoid user confusion 41 # Round up minute display to avoid user confusion
30 twhen=time.localtime(when+30) 42 twhen=time.localtime(when+30)
31 whenstr='at %02d:%02d' % (twhen.tm_hour, twhen.tm_min) 43 whenstr='at %02d:%02d' % (twhen.tm_hour, twhen.tm_min)
32 detail='' 44 detail=''
33 if 'detail' in status and status['detail']: 45 if 'detail' in status and status['detail']:
46 if status['detail']=='retry':
47 state=ERROR
34 detail=status['detail']+' ' 48 detail=status['detail']+' '
35 title="%s (%s%s %s)" % (status['name'], detail, status['operation'], whenstr) 49 title="%s (%s%s %s)" % (status['name'], detail, status['operation'], whenstr)
36 elif status['type']=='current': 50 elif status['type']=='current':
37 # Operation running 51 # Operation running
38 title="%s (running: %s)" % (status['name'], status['operation']) 52 progress=''
39 active=True 53 if 'progress_current' in status and 'progress_total' in status:
54 progress='%d%%' % (status.progress_current/status.progress_total)
55 title="%s (running: %s%s)" % (status['name'], status['operation'], progress)
56 active=ACTIVE
40 else: # status['type']=='nothing': 57 else: # status['type']=='nothing':
41 # Should be unscheduled, nothing running 58 # Should be unscheduled, nothing running
42 title=status['name'] 59 title=status['name']
43 60
44 return title, active 61 return title, state
45 62
46 63
47 class BorgendTray(rumps.App): 64 class BorgendTray(rumps.App):
48 def __init__(self, name, backups): 65 def __init__(self, name, backups):
49 self.lock=Lock() 66 self.lock=Lock()
64 cb=(lambda obj, status, _index=index: 81 cb=(lambda obj, status, _index=index:
65 self.__status_callback(obj, _index, status)) 82 self.__status_callback(obj, _index, status))
66 b.set_status_update_callback(cb) 83 b.set_status_update_callback(cb)
67 self.statuses[index]=b.status() 84 self.statuses[index]=b.status()
68 85
69 menu, active=self.__rebuild_menu() 86 menu, state=self.__rebuild_menu()
70 87
71 super().__init__(traynames[active], menu=menu, quit_button=None) 88 super().__init__(traynames[state], menu=menu, quit_button=None)
72 89
73 def __rebuild_menu(self): 90 def __rebuild_menu(self):
74 menu=[] 91 menu=[]
75 active=False 92 state=INACTIVE
76 for index in range(len(self.backups)): 93 for index in range(len(self.backups)):
77 b=self.backups[index] 94 b=self.backups[index]
78 title, this_active=make_title(self.statuses[index]) 95 title, this_state=make_title(self.statuses[index])
79 logging.info('TITLE: %s' % title) 96 logging.info('TITLE: %s' % title)
80 # Python closures suck dog's balls... 97 # Python closures suck dog's balls...
81 # first and the last program I write in Python until somebody 98 # first and the last program I write in Python until somebody
82 # fixes this brain damage 99 # fixes this brain damage
83 cbm=lambda sender, _b=b: self.__menu_select_backup(sender, _b) 100 cbm=lambda sender, _b=b: self.__menu_select_backup(sender, _b)
84 item=rumps.MenuItem(title, callback=cbm) 101 item=rumps.MenuItem(title, callback=cbm)
85 menu.append(item) 102 menu.append(item)
86 active=active or this_active 103 state=combine_state(state, this_state)
87 104
88 menu_quit=rumps.MenuItem("Quit...", callback=self.my_quit) 105 menu_quit=rumps.MenuItem("Quit...", callback=self.my_quit)
89 menu.append(menu_quit) 106 menu.append(menu_quit)
90 107
91 return menu, active 108 return menu, state
92 109
93 110
94 def my_quit(self, _): 111 def my_quit(self, _):
95 rumps.quit_application() 112 rumps.quit_application()
96 113
104 with self.lock: 121 with self.lock:
105 self.statuses[index]=status 122 self.statuses[index]=status
106 logging.debug('Rebuilding menu') 123 logging.debug('Rebuilding menu')
107 self.menu.clear() 124 self.menu.clear()
108 menu, active=self.__rebuild_menu() 125 menu, active=self.__rebuild_menu()
109 print(active)
110 self.menu.update(menu) 126 self.menu.update(menu)
111 self.title=traynames[active] 127 self.title=traynames[active]
112 128
113 129
114 130

mercurial