ui.py

changeset 34
9fce700d42de
parent 33
91421eeb4426
child 38
085a635f23f5
equal deleted inserted replaced
33:91421eeb4426 34:9fce700d42de
4 4
5 import rumps 5 import rumps
6 import time 6 import time
7 import datetime 7 import datetime
8 import logging 8 import logging
9 import borgend
9 from threading import Lock, Timer 10 from threading import Lock, Timer
10 from config import settings, appname_stylised 11 from config import settings
11 import objc 12 import objc
12 13
13 logger=logging.getLogger(__name__) 14 logger=borgend.logger.getChild(__name__)
14 15
15 INACTIVE=0 16 INACTIVE=0
16 ACTIVE=1 17 ACTIVE=1
17 OFFLINE=2 18 OFFLINE=2
18 ERRORS=3 19 ERRORS=3
31 return max(state1, state2) 32 return max(state1, state2)
32 33
33 # Workaround to rumps brokenness; 34 # Workaround to rumps brokenness;
34 # see https://github.com/jaredks/rumps/issues/59 35 # see https://github.com/jaredks/rumps/issues/59
35 def notification_workaround(title, subtitle, message): 36 def notification_workaround(title, subtitle, message):
36 NSDictionary = objc.lookUpClass("NSDictionary") 37 try:
37 d=NSDictionary() 38 NSDictionary = objc.lookUpClass("NSDictionary")
38 39 d=NSDictionary()
39 rumps.notification(title, subtitle, message, data=d) 40
41 rumps.notification(title, subtitle, message, data=d)
42 except Exception as err:
43 logger.debug('Unable to display notificaton:%s:%s',err.__class__.__name__, str(err))
40 44
41 # Based on code snatched from 45 # Based on code snatched from
42 # https://stackoverflow.com/questions/12523586/python-format-size-application-converting-b-to-kb-mb-gb-tb/37423778 46 # https://stackoverflow.com/questions/12523586/python-format-size-application-converting-b-to-kb-mb-gb-tb/37423778
43 def humanbytes(B): 47 def humanbytes(B):
44 'Return the given bytes as a human friendly KB, MB, GB, or TB string' 48 'Return the given bytes as a human friendly KB, MB, GB, or TB string'
102 if status['errors']: 106 if status['errors']:
103 state=ERRORS 107 state=ERRORS
104 108
105 return title, state 109 return title, state
106 110
107
108 class BorgendTray(rumps.App): 111 class BorgendTray(rumps.App):
109 def __init__(self, backups): 112 def __init__(self, backups):
110 self.lock=Lock() 113 self.lock=Lock()
111 self.backups=backups 114 self.backups=backups
112 self.statuses=[None]*len(backups) 115 self.statuses=[None]*len(backups)
128 self.statuses[index]=b.status() 131 self.statuses[index]=b.status()
129 132
130 menu, state=self.__rebuild_menu() 133 menu, state=self.__rebuild_menu()
131 134
132 self.refresh_timer=None 135 self.refresh_timer=None
136 self.logwindow=None
133 137
134 super().__init__(traynames[state], menu=menu, quit_button=None) 138 super().__init__(traynames[state], menu=menu, quit_button=None)
135 139
136 def __rebuild_menu(self): 140 def __rebuild_menu(self):
137 menu=[] 141 menu=[]
145 cbm=lambda sender, _b=b: self.__menu_select_backup(sender, _b) 149 cbm=lambda sender, _b=b: self.__menu_select_backup(sender, _b)
146 item=rumps.MenuItem(title, callback=cbm) 150 item=rumps.MenuItem(title, callback=cbm)
147 menu.append(item) 151 menu.append(item)
148 state=combine_state(state, this_state) 152 state=combine_state(state, this_state)
149 153
154 menu_log=rumps.MenuItem("Show log", callback=self.showlog)
155 menu.append(menu_log)
156
150 if not settings['no_quit_menu_entry']: 157 if not settings['no_quit_menu_entry']:
151 menu_quit=rumps.MenuItem("Quit...", callback=self.my_quit) 158 menu_quit=rumps.MenuItem("Quit...", callback=self.my_quit)
152 menu.append(menu_quit) 159 menu.append(menu_quit)
153 160
154 return menu, state 161 return menu, state
178 msgid=errorlog['msgid'] 185 msgid=errorlog['msgid']
179 186
180 logger.debug("Opening notification for error %s '%s'", 187 logger.debug("Opening notification for error %s '%s'",
181 msgid, errorlog['message']) 188 msgid, errorlog['message'])
182 189
183 notification_workaround(appname_stylised, 190 notification_workaround(borgend.appname_stylised,
184 msgid, errorlog['message']) 191 msgid, errorlog['message'])
185 192
186 def my_quit(self, _): 193 def my_quit(self, _):
194 logging.shutdown()
187 rumps.quit_application() 195 rumps.quit_application()
188 196
189 def __menu_select_backup(self, sender, b): 197 def __menu_select_backup(self, sender, b):
190 #sender.state=not sender.state 198 #sender.state=not sender.state
191 logger.debug("Manually backup '%s'", b.name) 199 logger.debug("Manually backup '%s'", b.name)
192 try: 200 try:
193 b.create(None) 201 b.create(None)
194 except Exception as err: 202 except Exception as err:
195 logger.debug("Opening notification for exception %s '%s'", 203 logger.debug("Opening notification for exception %s '%s'",
196 err.__class__.__name__, str(err)) 204 err.__class__.__name__, str(err))
197 notification_workaround(appname_stylised, 205 notification_workaround(borgend.appname_stylised,
198 err.__class__.__name__, str(err)) 206 err.__class__.__name__, str(err))
199 207
200 @rumps.notifications 208 @rumps.notifications
201 def notification_center(data): 209 def notification_center(data):
202 pass 210 pass
203 211
212 def showlog(self, _):
213 try:
214 if not self.logwindow:
215 lines=borgend.fifolog.formatAll()
216 msg="\n".join(lines[0:])
217 self.logwindow=rumps.Window(title=borgend.appname_stylised+' log',
218 default_text=msg,
219 ok='Close',
220 dimensions=(640,320))
221 self.logwindow.run()
222 # Does not return until closed
223 self.logwindow=None
224 except Exception as err:
225 logger.critical('%s:%s', err.__class__.__name__, str(err))
226

mercurial