74 return '{0:.2f}GB'.format(B/GB) |
74 return '{0:.2f}GB'.format(B/GB) |
75 elif TB <= B: |
75 elif TB <= B: |
76 return '{0:.2f}TB'.format(B/TB) |
76 return '{0:.2f}TB'.format(B/TB) |
77 |
77 |
78 def make_title(status): |
78 def make_title(status): |
79 def add_detail(detail, new): |
79 def add_info(info, new): |
80 if detail: |
80 if info: |
81 return "%s; %s" % (detail, new) |
81 return "%s; %s" % (info, new) |
82 else: |
82 else: |
83 return new |
83 return new |
84 |
84 |
85 errors=status['errors'] |
85 info=None |
86 detail=None |
86 |
87 |
87 if not status.errors.ok(): |
88 if not errors.ok(): |
88 info=add_info(info, str(status.errors)) |
89 detail=add_detail(detail, str(errors)) |
89 |
90 |
90 if status.state==backup.State.SCHEDULED: |
91 if status['state']==backup.State.SCHEDULED: |
|
92 # Operation scheduled |
91 # Operation scheduled |
93 when=status['when'] |
92 when=status.when() |
94 now=time.time() |
93 now=time.time() |
95 if when<now: |
94 if when<now: |
96 whenstr='overdue' |
95 whenstr='overdue' |
97 detail='' |
96 info='' |
98 else: |
97 else: |
99 diff=datetime.timedelta(seconds=when-now) |
98 diff=datetime.timedelta(seconds=when-now) |
100 if diff.days>0: |
99 if diff.days>0: |
101 whenday=datetime.date.fromtimestamp(when) |
100 whenday=datetime.date.fromtimestamp(when) |
102 whenstr='on %s' % whenday.isoformat() |
101 whenstr='on %s' % whenday.isoformat() |
105 if twhen.tm_sec>30: |
104 if twhen.tm_sec>30: |
106 # Round up minute display to avoid user confusion |
105 # Round up minute display to avoid user confusion |
107 twhen=time.localtime(when+30) |
106 twhen=time.localtime(when+30) |
108 whenstr='at %02d:%02d' % (twhen.tm_hour, twhen.tm_min) |
107 whenstr='at %02d:%02d' % (twhen.tm_hour, twhen.tm_min) |
109 |
108 |
110 this_detail='' |
109 this_info='' |
111 if status['detail']!='normal': |
110 if 'reason' in status.detail: |
112 this_detail=status['detail'] + ' ' |
111 this_info=status.detail['reason'] + ' ' |
113 |
112 |
114 when_how_sched= "%s%s %s" % (this_detail, status['operation'], whenstr) |
113 when_how_sched= "%s%s %s" % (this_info, status.operation, whenstr) |
115 |
114 |
116 detail=add_detail(detail, when_how_sched) |
115 info=add_info(info, when_how_sched) |
117 |
116 |
118 elif status['state']==backup.State.QUEUED: |
117 elif status.state==backup.State.QUEUED: |
119 detail=add_detail(detail, "queued") |
118 info=add_info(info, "queued") |
120 elif status['state']==backup.State.ACTIVE: |
119 elif status.state==backup.State.ACTIVE: |
121 # Operation running |
120 # Operation running |
122 progress='' |
121 progress='' |
123 if 'progress_current' in status and 'progress_total' in status: |
122 d=status.detail |
124 progress=' %d%%' % (status['progress_current']/status['progress_total']) |
123 if 'progress_current' in d and 'progress_total' in d: |
125 elif 'original_size' in status and 'deduplicated_size' in status: |
124 progress=' %d%%' % (d['progress_current']/d['progress_total']) |
126 progress=' %s→%s' % (humanbytes(status['original_size']), |
125 elif 'original_size' in d and 'deduplicated_size' in d: |
127 humanbytes(status['deduplicated_size'])) |
126 progress=' %s→%s' % (humanbytes(d['original_size']), |
128 |
127 humanbytes(d['deduplicated_size'])) |
129 howrunning = "running %s%s" % (status['operation'], progress) |
128 |
130 |
129 howrunning = "running %s%s" % (status.operation, progress) |
131 detail=add_detail(detail, howrunning) |
130 |
|
131 info=add_info(info, howrunning) |
132 else: |
132 else: |
133 pass |
133 pass |
134 |
134 |
135 if detail: |
135 if info: |
136 title=status['name'] + ' (' + detail + ')' |
136 title=status.name + ' (' + info + ')' |
137 else: |
137 else: |
138 title=status['name'] |
138 title=status.name |
139 |
139 |
140 return title, (status['state'], status['errors']) |
140 return title, (status.state, status.errors) |
141 |
141 |
142 class BorgendTray(rumps.App): |
142 class BorgendTray(rumps.App): |
143 def __init__(self, backups): |
143 def __init__(self, backups): |
144 self.lock=Lock() |
144 self.lock=Lock() |
145 self.backups=backups |
145 self.backups=backups |