Sat, 20 Jan 2018 21:27:05 +0000
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
1
4cdc9c1f6b28
basic scheduler structure draft, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
1 | # |
4cdc9c1f6b28
basic scheduler structure draft, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
2 | # MacOS UI |
4cdc9c1f6b28
basic scheduler structure draft, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
3 | # |
4cdc9c1f6b28
basic scheduler structure draft, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
4 | |
4cdc9c1f6b28
basic scheduler structure draft, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
5 | import rumps |
10 | 6 | import time |
7 | import datetime | |
8 | import logging | |
9 | from threading import Lock | |
10 | ||
14
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
11 | INACTIVE=0 |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
12 | ACTIVE=1 |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
13 | ERROR=2 |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
14 | |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
15 | traynames={INACTIVE: 'B.', ACTIVE: 'B!', ERROR: 'B?'} |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
16 | |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
17 | def combine_state(state1, state2): |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
18 | if state1==ERROR or state2==ERROR: |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
19 | return ERROR |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
20 | elif state1==ACTIVE or state2==ACTIVE: |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
21 | return ACTIVE |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
22 | else: |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
23 | return INACTIVE |
11
0bff53095f28
New tray title: B. or B! depending on activity
Tuomo Valkonen <tuomov@iki.fi>
parents:
10
diff
changeset
|
24 | |
10 | 25 | def make_title(status): |
14
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
26 | state=INACTIVE |
10 | 27 | if status['type']=='scheduled': |
28 | # Operation scheduled | |
29 | when=status['when'] | |
30 | now=time.time() | |
31 | if when<now: | |
32 | whenstr='overdue' | |
33 | else: | |
34 | diff=datetime.timedelta(seconds=when-now) | |
35 | if diff.days>0: | |
36 | whenday=datetime.date.fromtimestamp(when) | |
37 | whenstr='on %s' % whenday.isoformat() | |
38 | else: | |
39 | twhen=time.localtime(when) | |
40 | if twhen.tm_sec>30: | |
41 | # Round up minute display to avoid user confusion | |
42 | twhen=time.localtime(when+30) | |
43 | whenstr='at %02d:%02d' % (twhen.tm_hour, twhen.tm_min) | |
44 | detail='' | |
45 | if 'detail' in status and status['detail']: | |
14
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
46 | if status['detail']=='retry': |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
47 | state=ERROR |
10 | 48 | detail=status['detail']+' ' |
11
0bff53095f28
New tray title: B. or B! depending on activity
Tuomo Valkonen <tuomov@iki.fi>
parents:
10
diff
changeset
|
49 | title="%s (%s%s %s)" % (status['name'], detail, status['operation'], whenstr) |
10 | 50 | elif status['type']=='current': |
51 | # Operation running | |
14
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
52 | progress='' |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
53 | if 'progress_current' in status and 'progress_total' in status: |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
54 | progress='%d%%' % (status.progress_current/status.progress_total) |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
55 | title="%s (running: %s%s)" % (status['name'], status['operation'], progress) |
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
56 | active=ACTIVE |
10 | 57 | else: # status['type']=='nothing': |
58 | # Should be unscheduled, nothing running | |
11
0bff53095f28
New tray title: B. or B! depending on activity
Tuomo Valkonen <tuomov@iki.fi>
parents:
10
diff
changeset
|
59 | title=status['name'] |
0bff53095f28
New tray title: B. or B! depending on activity
Tuomo Valkonen <tuomov@iki.fi>
parents:
10
diff
changeset
|
60 | |
14
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
61 | return title, state |
10 | 62 | |
1
4cdc9c1f6b28
basic scheduler structure draft, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
63 | |
4cdc9c1f6b28
basic scheduler structure draft, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
64 | class BorgendTray(rumps.App): |
9
aa121291eb0e
Rumps/Mac UI stuff is fucked and disables ^C etc.; threading doesn't help
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
65 | def __init__(self, name, backups): |
10 | 66 | self.lock=Lock() |
67 | self.backups=backups | |
68 | self.statuses=[None]*len(backups) | |
69 | ||
70 | with self.lock: | |
71 | # Initialise reporting callbacks and local status copy | |
72 | # (since rumps doesn't seem to be able to update menu items | |
73 | # without rebuilding the whole menu, and we don't want to lock | |
74 | # when calling Backup.status(), especially as we will be called | |
75 | # from Backup reporting its status, we keep a copy to allow | |
76 | # rebuilding the entire menu | |
77 | for index in range(len(backups)): | |
78 | b=backups[index] | |
79 | # Python closures suck dog's balls; hence the _index=index hack | |
80 | # See also http://math.andrej.com/2009/04/09/pythons-lambda-is-broken/ | |
81 | cb=(lambda obj, status, _index=index: | |
82 | self.__status_callback(obj, _index, status)) | |
83 | b.set_status_update_callback(cb) | |
84 | self.statuses[index]=b.status() | |
85 | ||
14
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
86 | menu, state=self.__rebuild_menu() |
9
aa121291eb0e
Rumps/Mac UI stuff is fucked and disables ^C etc.; threading doesn't help
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
87 | |
14
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
88 | super().__init__(traynames[state], menu=menu, quit_button=None) |
10 | 89 | |
90 | def __rebuild_menu(self): | |
91 | menu=[] | |
14
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
92 | state=INACTIVE |
10 | 93 | for index in range(len(self.backups)): |
94 | b=self.backups[index] | |
14
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
95 | title, this_state=make_title(self.statuses[index]) |
10 | 96 | logging.info('TITLE: %s' % title) |
97 | # Python closures suck dog's balls... | |
98 | # first and the last program I write in Python until somebody | |
99 | # fixes this brain damage | |
100 | cbm=lambda sender, _b=b: self.__menu_select_backup(sender, _b) | |
101 | item=rumps.MenuItem(title, callback=cbm) | |
102 | menu.append(item) | |
14
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
103 | state=combine_state(state, this_state) |
10 | 104 | |
105 | menu_quit=rumps.MenuItem("Quit...", callback=self.my_quit) | |
106 | menu.append(menu_quit) | |
107 | ||
14
5a988a2c2624
UI: progress percentange support (Borg doesn't seem to be reporting) + error indicator in tray: B?
Tuomo Valkonen <tuomov@iki.fi>
parents:
11
diff
changeset
|
108 | return menu, state |
10 | 109 | |
110 | ||
111 | def my_quit(self, _): | |
9
aa121291eb0e
Rumps/Mac UI stuff is fucked and disables ^C etc.; threading doesn't help
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
112 | rumps.quit_application() |
aa121291eb0e
Rumps/Mac UI stuff is fucked and disables ^C etc.; threading doesn't help
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
113 | |
10 | 114 | def __menu_select_backup(self, sender, b): |
115 | #sender.state=not sender.state | |
116 | logging.debug("Manually backup '%s'", b.name) | |
117 | b.create(None) | |
9
aa121291eb0e
Rumps/Mac UI stuff is fucked and disables ^C etc.; threading doesn't help
Tuomo Valkonen <tuomov@iki.fi>
parents:
1
diff
changeset
|
118 | |
10 | 119 | def __status_callback(self, obj, index, status): |
120 | logging.debug('Status callbackup %s' % str(status)) | |
121 | with self.lock: | |
122 | self.statuses[index]=status | |
123 | logging.debug('Rebuilding menu') | |
124 | self.menu.clear() | |
11
0bff53095f28
New tray title: B. or B! depending on activity
Tuomo Valkonen <tuomov@iki.fi>
parents:
10
diff
changeset
|
125 | menu, active=self.__rebuild_menu() |
0bff53095f28
New tray title: B. or B! depending on activity
Tuomo Valkonen <tuomov@iki.fi>
parents:
10
diff
changeset
|
126 | self.menu.update(menu) |
0bff53095f28
New tray title: B. or B! depending on activity
Tuomo Valkonen <tuomov@iki.fi>
parents:
10
diff
changeset
|
127 | self.title=traynames[active] |
10 | 128 | |
129 | ||
130 |