# -*- python -*-
from common import *
from datetime import datetime
class MyTimer(Entry):
def __init__(self, *args, alarms = [], **kwargs):
self.start = None
self.length = None
self.notified = False
self.pause_text = None
self.triggered_alarm = None
self.alarms = []
for alarm in alarms:
alarm = alarm.split(': ')
text = ': '.join(alarm[1:])
if not text:
text = alarm
weekday = None
alarm = alarm[0].split(':')
if not alarm[0].isdigit():
weekday, alarm[0] = alarm[0].split(' ')
weekday = {'mon' : 0,
'tue' : 1,
'wed' : 2,
'thu' : 3,
'fri' : 4,
'sat' : 5,
'sun' : 6}[weekday.lower()[:3]]
time = (int(alarm[0]) * 60 + int(alarm[1])) * 60
if len(alarm) > 2:
time += int(alarm[2])
self.alarms.append([False, time, weekday, text])
mqueue_map['timer'] = self.mqueue
Entry.__init__(self, *args, **kwargs)
def mqueue(self, args):
if args[1] == 'stop':
self.stop()
elif args[1] in ('pause', 'resume'):
self.pause()
else:
duration = args[1].split(':')
duration.reverse()
seconds = 0
if len(duration) > 0: seconds += int(duration[0])
if len(duration) > 1: seconds += int(duration[1]) * 60
if len(duration) > 2: seconds += int(duration[2]) * 60 * 60
if len(duration) > 3: seconds += int(duration[3]) * 60 * 60 * 24
self.start = time.time()
self.length = seconds
self.notified = False
self.pause_text = None
self.invalidate()
def action(self, col, button, x, y):
if self.triggered_alarm is not None:
self.triggered_alarm = None
self.invalidate()
elif button == LEFT_BUTTON:
self.pause()
elif button == RIGHT_BUTTON:
self.stop()
def pause(self):
if self.pause_text is not None:
self.start = time.time()
self.pause_text = None
elif self.length is None:
pass
elif self.length - int(time.time() - self.start) < 0:
self.start, self.length, self.notified, self.pause_text = None, None, False, None
else:
self.pause_text = ''
self.length -= int(time.time() - self.start)
self.pause_text = self.dur(self.length)
self.invalidate()
def stop(self):
self.start = None
self.length = None
self.notified = False
self.pause_text = None
self.invalidate()
def dur(self, t):
s, t = t % 60, t // 60
m, t = t % 60, t // 60
h, d = t % 24, t // 24
if d > 0:
return '%id %i:%02i:%02i' % (d, h, m, s)
elif h > 0:
return '%i:%02i:%02i' % (h, m, s)
else:
return '%i:%02i' % (m, s)
def notify(self, text = 'You are done with your task'):
subprocess.Popen(['notify-send', '-u', 'critical', text]).wait()
def wall(self, text = 'You are done with your task'):
subprocess.Popen(['wall', text]).wait()
def function(self):
now = datetime.now()
weekday = now.weekday()
now = now.hour * 60 * 60 + now.minute * 60 + now.second
if self.triggered_alarm is not None:
countdown = int(self.alarms[self.triggered_alarm][1] - now) % 2
if countdown == 0:
return '\033[37;41m%s\033[00m' % self.alarms[self.triggered_alarm][3]
else:
return '\033[31m%s\033[00m' % self.alarms[self.triggered_alarm][3]
for i, alarm in enumerate(self.alarms):
if (alarm[2] is None or weekday == alarm[2]) and now >= alarm[1] and now < alarm[1] + 30 * 60:
if not alarm[0]:
alarm[0] = True
xasync(lambda : self.notify(alarm[3]), name = 'alarm notify')
xasync(lambda : self.wall(alarm[3]), name = 'alarm wall')
self.triggered_alarm = i
return self.function()
else:
alarm[0] = False
if self.pause_text is not None:
return '%s (paused)' % self.pause_text
if self.start is None:
return 'Timer inactive'
countdown = self.length - int(time.time() - self.start)
if countdown > 0:
return self.dur(countdown)
if not self.notified:
self.notified = True
xasync(self.notify, name = 'timer notify')
xasync(self.wall, name = 'timer wall')
countdown %= 2
if countdown == 0:
return '\033[37;41mYou are done\033[00m'
else:
return '\033[31mYou are done\033[00m'