Page MenuHomePhabricator

workrave-auto.py
No OneTemporary

workrave-auto.py

#!/usr/bin/env python
from PyQt5.QtCore import QTimer, pyqtSignal, QObject, pyqtSlot, QCoreApplication, QMetaObject, Qt
from dbus.mainloop.pyqt5 import DBusQtMainLoop
import dbus
import os
import configparser
import datetime
import time
import sys
import signal
def wk2int(day):
if day == 'mon':
return 0
elif day == 'tue':
return 1
elif day == 'wed':
return 2
elif day == 'thu':
return 3
elif day == 'fri':
return 4
elif day == 'sat':
return 5
elif day == 'sun':
return 6
else:
return -1
def time2diff(now, time):
datetime.datetime.now()
to = time.split(':')
hr = int(to[0])
mi = 0
sec = 0
if len(to) == 2:
mi = int(to[1])
if len(to) == 3:
sec = int(to[2])
return datetime.datetime.combine(datetime.date.today(), datetime.time(hr, mi, sec)) - now
class autoEntry:
def __init__(self, options):
self.options = options
self.next_action = options['default']
self.next_run = 0
self.in_interval = False
self.update()
def print_options(self):
print(self.options)
def update(self):
self.in_interval = False
now = datetime.datetime.now()
days = 0
starttime = time2diff(now, '00:00')
endtime = time2diff(now, '23:59')
if 'weekday' in self.options:
curr_day = now.weekday()
wanted_day = wk2int(self.options['weekday'])
if wanted_day == -1:
print('Error parsing weekday')
return -1
diff_day = wanted_day - curr_day
if diff_day < 0:
diff_day += 7
days = diff_day
if 'starttime' in self.options:
starttime = time2diff(now, self.options['starttime'])
if 'endtime' in self.options:
endtime = time2diff(now, self.options['endtime'])
if starttime.total_seconds() < 0 and endtime.total_seconds() < 0:
# After interval, if it's today, we need to add a week
if days == 0:
starttime = starttime + datetime.timedelta(days=7)
endtime = endtime + datetime.timedelta(days=7)
self.next_run = days * 24 * 60 * 60 + starttime.total_seconds()
self.next_action = self.options['mode']
elif starttime.total_seconds() < 0 and endtime.total_seconds() >= 0:
# Inside of interval
if days == 0:
self.next_action = self.options['default']
self.next_run = endtime.total_seconds()
self.in_interval = True
else:
self.next_run = days * 24 * 60 * 60 + starttime.total_seconds()
self.next_action = self.options['mode']
elif starttime.total_seconds() >= 0 and endtime.total_seconds() >= 0:
# Before interval
self.next_action = self.options['mode']
self.next_run = days * 24 * 60 * 60 + starttime.total_seconds()
else:
print('Invalid settings detected!')
def get_next_action(self):
self.update()
return self.next_action
def get_interval_action(self):
return self.options['mode']
def get_next_run(self):
self.update()
return int(self.next_run)
def is_in_interval(self):
self.update()
return self.in_interval
def load_config(cfgFile):
config = configparser.ConfigParser()
config.read(cfgFile)
return config
def save_config(config, cfgFile):
with open(cfgFile, 'w') as configFile:
config.write(configFile)
def recreate_config(cfgFile):
config = configparser.ConfigParser()
config['general'] = {
'mode' : 'normal'
}
config['entry1'] = {
'name' : 'workrave',
'mode' : 'suspended',
'weekday' : 'wed',
'starttime' : '07:00',
'endtime' : '15:10'
}
config['entry2'] = {
'name' : 'workrave',
'mode' : 'suspended',
'weekday' : 'thu',
'starttime' : '07:00',
'endtime' : '18:00'
}
save_config(config, cfgFile)
class workraveManager(QObject):
def __init__(self, cfg):
QObject.__init__(self)
self.cfg = cfg
entries = self.parse_config(cfg)
self.entryobjects = []
self.default_mode = cfg['general']['mode']
self.timer = QTimer()
self.timer.setSingleShot(True)
self.timer.timeout.connect(self.run_action)
for entry in entries:
entryCfg = entries[entry]
entryCfg['default'] = self.default_mode
self.entryobjects.append(autoEntry(entryCfg))
@pyqtSlot()
def run_action(self):
print('Timer fired, about to run action: ' + self.action)
self.set_workrave_mode(self.action)
# This prevents the timer from firing several times
time.sleep(1000)
self.setup_timer()
def suspend_handler(self, suspended):
if suspended:
print('Going to sleep...')
self.timer.stop()
else:
print('Resuming, doing the recalculation math!')
self.startup_check()
self.setup_timer()
def init_dbus(self):
dbus_loop = DBusQtMainLoop(set_as_default=True)
self.system_bus = dbus.SystemBus(mainloop = dbus_loop)
manager_interface = 'org.freedesktop.login1.Manager'
self.system_bus.add_signal_receiver(self.suspend_handler, 'PrepareForSleep', manager_interface)
def parse_config(self, cfg):
ret = {}
for sec in cfg.sections():
if sec != 'general':
ret[sec] = {}
for key in cfg[sec]:
ret[sec][key] = cfg[sec][key]
return ret
def startup_check(self):
print('Startup check...')
in_interval = False
for entry in self.entryobjects:
if entry.is_in_interval():
action = entry.get_interval_action()
print('Interval currently running, setting mode: ' + action)
self.set_workrave_mode(action)
in_interval = True
if not in_interval:
print('Not in interval, setting default workrave mode: ' + self.default_mode)
self.set_workrave_mode(self.default_mode)
def set_workrave_mode(self, action):
wr = dbus.SessionBus().get_object('org.workrave.Workrave', '/org/workrave/Workrave/Core')
iface = dbus.Interface(wr, 'org.workrave.CoreInterface')
mode = iface.GetOperationMode()
if mode == action:
print('Mode already set, no action')
else:
iface.SetOperationMode(action)
@pyqtSlot()
def startup(self):
self.init_dbus()
self.startup_check()
self.setup_timer()
def setup_timer(self):
self.timer.stop()
next_action_list = []
next_run_list = []
for entry in self.entryobjects:
next_action_list.append(entry.get_next_action())
next_run_list.append(entry.get_next_run())
sleep_time = min(next_run_list)
self.action = next_action_list[next_run_list.index(sleep_time)]
print('Setting up timer for ' + str(sleep_time) + ' seconds and then running action: ' + self.action)
self.timer.start(sleep_time * 1000)
def main():
signal.signal(signal.SIGINT, signal.SIG_DFL)
cfgPath = os.path.expanduser("~") + "/.workrave-auto/"
if not os.path.isdir(cfgPath):
os.makedirs(cfgPath)
cfgFile = cfgPath + "config.ini"
if not os.path.exists(cfgFile):
recreate_config(cfgFile)
cfg = load_config(cfgFile)
m = workraveManager(cfg)
QMetaObject.invokeMethod(m, "startup", Qt.QueuedConnection)
app = QCoreApplication(sys.argv)
sys.exit(app.exec_())
if __name__ == '__main__':
main()

File Metadata

Mime Type
text/x-python
Expires
Thu, Dec 5, 5:50 AM (2 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
913556
Default Alt Text
workrave-auto.py (7 KB)

Event Timeline