timetracker

suckless timetracking
git clone https://tongong.net/git/timetracker.git
Log | Files | Refs | README

commit c690f56af6eb4029ba438b9efdb7e31f250c539c
parent 1cdb1ef1324f5c920ad9e3048c676f97ba6429fb
Author: tongong <tongong@gmx.net>
Date:   Thu, 10 Jun 2021 21:38:39 +0200

added python script to analyze data

Diffstat:
Atimetracker-report | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+), 0 deletions(-)

diff --git a/timetracker-report b/timetracker-report @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +import os +from datetime import datetime +from math import floor +import subprocess + +# TODO +# - only show one week or so +# - add more graphs +# - average daily time for week/month/year +# - total time per program +# - check if termgraph is installed +# - align graphs of different sections +# - add commandline arguments to just look at specific date or specific program + +# helper functions +def filelocation(): + if (os.getenv("XDG_DATA_HOME")): + return os.getenv("XDG_DATA_HOME") + "/timetracker/data" + else: + return os.getenv("HOME") + "/.local/share/timetracker/data" + +def timestring(secs): + secs /= 60 + if (secs >= 60): + return str(floor(secs / 60)) + "h" + str(floor(secs % 60)).zfill(2) + \ + "m" + else: + return str(floor(secs % 60)) + "m" + +# command -> array of args +# inp (=stdin) -> string +# returns stdout as string +def runExternal(command, inp): + proc = subprocess.Popen(command, stdin=subprocess.PIPE, + stdout=subprocess.PIPE) + proc.stdin.write(inp.encode("utf-8")) + proc.stdin.close() + + while proc.returncode is None: + proc.poll() + + return proc.stdout.read().decode("utf-8") + +# yellow and bold +def printHeading(text): + print("\033[33m\033[1m" + text + "\033[0m") + + + +# does not handle errors +datafile = open(filelocation(), "r") + +# parse input file +days = {} +programs = [] +for line in datafile: + parts = line.split(","); + if datetime.fromtimestamp(int(parts[0])).strftime("%Y-%m-%d") not in days: + days[datetime.fromtimestamp(int(parts[0])).strftime("%Y-%m-%d")] = {} + dayRef = days[datetime.fromtimestamp(int(parts[0])).strftime("%Y-%m-%d")] + + for part2 in parts[1:]: + # print(part2) + program = part2.split(":")[0] + ptime = int(part2.split(":")[1]) + if program not in programs: + programs.append(program) + if program in dayRef: + dayRef[program] += ptime + else: + dayRef[program] = ptime + +# graphs +printHeading("# past days") +tgIn = "" # termgraph input +for day in days: + daySum = 0 + for program in days[day]: + if program != "slock" and program != "standby": + daySum += days[day][program] + tgIn += day + " " + timestring(daySum).rjust(5, " ") + "," + \ + str(daySum) + "\n" +print(runExternal(["termgraph", "--label-before", "--no-values"], tgIn)[1:-2]) +print() + +today = datetime.fromtimestamp(int(parts[0])).strftime("%Y-%m-%d") +if today in days: + printHeading("# today") + maxLen = 0 # maximum length of program names + for program in days[today]: + if len(program) > maxLen: + maxLen = len(program) + tgIn = "" # termgraph input + for program in sorted(days[today], key=lambda x: days[today][x], + reverse=True): + if days[today][program] >= 60: + tgIn += program.ljust(maxLen, " ") + " " + \ + timestring(days[today][program]).rjust(5, " ") + "," + \ + str(days[today][program]) + "\n" + print(runExternal(["termgraph", "--label-before", "--no-values"], + tgIn)[1:-2])