timetracker

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

timetracker-report (3569B)


      1 #!/usr/bin/env python3
      2 import os
      3 from datetime import datetime, timedelta
      4 from math import floor
      5 import subprocess
      6 
      7 #   HELPER FUNCTIONS   #######################################################
      8 def filelocation():
      9     if (os.getenv("XDG_DATA_HOME")):
     10         return os.getenv("XDG_DATA_HOME") + "/timetracker/data"
     11     else:
     12         return os.getenv("HOME") + "/.local/share/timetracker/data"
     13 
     14 def timestring(secs):
     15     secs /= 60
     16     if (secs >= 60):
     17         return str(floor(secs / 60)) + "h" + str(floor(secs % 60)).zfill(2) + \
     18                 "m"
     19     else:
     20         return str(floor(secs % 60)) + "m"
     21 
     22 # yellow and bold
     23 def printHeading(text):
     24     print("\033[33m\033[1m" + text + "\033[0m")
     25 
     26 # example: data = [["firefox", 75], ["vim", 250], ...]
     27 def printGraph(data):
     28     # replace name with name and time in correct alignment
     29     # 15 is enough space https://stackoverflow.com/questions/23534263/what-is-the-maximum-allowed-limit-on-the-length-of-a-process-name
     30     for line in data:
     31         line[0] = line[0].ljust(16, " ") + timestring(line[1]).rjust(5, " ")
     32 
     33     width = 50;
     34     # scale numbers on width
     35     maximum = 0;
     36     for line in data:
     37         if (line[1] > maximum): maximum = line[1]
     38     for line in data:
     39         line[1] = round(line[1] / maximum * 50) if maximum != 0 else 0
     40 
     41     # print the graph
     42     for line in data:
     43         bar = ""
     44         if (line[1] == 0): bar = "▏"
     45         else: bar = "▇" * line[1]
     46 
     47         print(line[0] + " " + bar)
     48 
     49 
     50 #   READ AND PARSE FILE   ####################################################
     51 try:
     52     datafile = open(filelocation(), "r")
     53 except FileNotFoundError:
     54     print("data is file not there (yet)")
     55     exit(1)
     56 
     57 # parse input file
     58 days = {}
     59 programs = []
     60 for line in datafile:
     61     parts = line.split(",");
     62     datestring = datetime.fromtimestamp(int(parts[0])).strftime("%Y-%m-%d")
     63     if datestring not in days:
     64         days[datestring] = {}
     65     dayRef = days[datestring]
     66 
     67     for part2 in parts[1:]:
     68         # print(part2)
     69         program = part2.split(":")[0]
     70         ptime = int(part2.split(":")[1])
     71         if program not in programs:
     72             programs.append(program)
     73         if program in dayRef:
     74             dayRef[program] += ptime
     75         else:
     76             dayRef[program] = ptime
     77 
     78 
     79 #   PRINT GRAPHS   ###########################################################
     80 # past week
     81 printHeading("# past week")
     82 tgIn = [] # graph input
     83 for i in range(7):
     84     day = (datetime.today() + timedelta(days=i-6)).strftime("%Y-%m-%d")
     85     daySum = 0
     86     if day in days:
     87         for program in days[day]:
     88             if program != "slock" and program != "standby":
     89                 daySum += days[day][program]
     90     tgIn.append([day, daySum])
     91 printGraph(tgIn)
     92 
     93 # today
     94 today = datetime.today().strftime("%Y-%m-%d")
     95 if today in days:
     96     print()
     97     printHeading("# today")
     98     tgIn = [] # graph input
     99     for program in sorted(days[today], key=lambda x: days[today][x],
    100             reverse=True):
    101         if days[today][program] >= 60:
    102             tgIn.append([program, days[today][program]])
    103     printGraph(tgIn)
    104 
    105 # average
    106 print()
    107 printHeading("# average")
    108 # get total number of days
    109 dayNum = (datetime.today() - \
    110         datetime.strptime(list(days.keys())[0], "%Y-%m-%d")).days + 1
    111 tgIn = [] # graph input
    112 for program in programs:
    113     ptime = 0
    114     for day in days:
    115         for p in days[day]:
    116             if p == program:
    117                 ptime += days[day][program] / dayNum
    118     if ptime >= 60:
    119         tgIn.append([program, ptime]);
    120 tgIn = sorted(tgIn, key=lambda x: x[1], reverse=True)
    121 printGraph(tgIn)