aboutsummaryrefslogblamecommitdiffstats
path: root/xpybar/config/mytimer.py
blob: e886ed3be3f50663e8647237ce829eaf52ba8723 (plain) (tree)













































































































































                                                                                                          
# -*- 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'