Skip to content

Instantly share code, notes, and snippets.

@hamidzr
Last active May 7, 2021 04:21
Show Gist options
  • Save hamidzr/dbef38ebae990e7c186dae444187935a to your computer and use it in GitHub Desktop.
Save hamidzr/dbef38ebae990e7c186dae444187935a to your computer and use it in GitHub Desktop.
Parse, merge, and output multiple workrave history usages. https://workrave.org/
#!/usr/bin/env python3
from typing import Any, Dict, List, Union, Optional, cast
import datetime
import os.path
"""
Parse, merge, and output multiple workrave history usages. https://workrave.org/
history file format:
d m year (start at 0)
D 19 4 120 9 28 20 4 120 0 49
secs msecs mouse kbd
m 6 21971 3534639 2025992 7376 14847 26676
"""
Stat = Dict[str, Union[int, datetime.date]]
Stats = List[Stat]
def load_stats(path: str = '~/.workrave/historystats') -> List[Stat]:
with open(path, 'r') as f:
lines = f.readlines()
recs: Stats = []
rec: Stat = {}
for l in lines:
p = l.split(' ')
if l.startswith('B '): continue
if l.startswith('D '):
day = int(p[1])
month = int(p[2]) + 1
year = int(p[3][1:]) + 2000
rec['date'] = datetime.datetime(year, month, day)
if l.startswith('m '):
rec['usage'] = int(p[2])
rec['mouse_usage'] = int(p[5])
rec['mouse_clicks'] = int(p[6])
rec['kbd_presses'] = int(p[7])
recs.append(rec)
rec = {}
return recs
def merge_stat(a: Optional[Stat], b: Optional[Stat]) -> Stat:
if a is None: return b
if b is None: return a
date = a['date']
rv = {}
for key in b.keys():
if key == 'date': continue
rv[key] = a[key] + b[key]
rv['date'] = date
return rv
def merge_stat_lists(stats_list: List[Stats]) -> Stats:
rv: Dict[datetime.datetime, Stat] = {}
for stats in stats_list:
for s in stats:
key = s['date']
acc = merge_stat(rv[key] if key in rv else None, s)
rv[key] = acc
return sort_stats(list(rv.values()))
def sort_stats(stats: Stats) -> Stats:
return sorted(stats, key=lambda x: x['date'])
def _week_number(stat: Stat) -> int:
year, week, *_ = cast(datetime.datetime, stat['date']).isocalendar()
key = (year * 54) + week
return key
def reduce_stats(stats: Stats) -> Stats:
"""
Reduce daily stats to weekly stats.
"""
rv: Dict[int, Stat] = {}
for s in sort_stats(stats):
key = _week_number(s)
rv[key] = merge_stat(rv[key] if key in rv else None, s)
return sort_stats(list(rv.values()))
def print_stats(stats: Stats):
keys = ['date', 'usage', 'mouse_usage', 'mouse_clicks', 'kbd_presses']
print(', '.join(keys))
for rec in stats:
line = ', '.join([str(rec[k]) for k in keys])
print(line)
if __name__ == '__main__':
stats = merge_stat_lists(
[
load_stats(os.path.expanduser('~/.workrave/historystats')),
load_stats(os.path.expanduser('~/dl/historystats')),
]
)
print_stats(reduce_stats(stats))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment