~proycon/todotxt-more

40b63caac0558b59ec4e531dc2439ac0308a430a — Maarten van Gompel 6 months ago 2e39237
rewrote timetrack log in python instead of posix shell for better performance
2 files changed, 88 insertions(+), 56 deletions(-)

A todo.actions.d/helpers/timetrack_log.py
M todo.actions.d/timetrack
A todo.actions.d/helpers/timetrack_log.py => todo.actions.d/helpers/timetrack_log.py +82 -0
@@ 0,0 1,82 @@
#!/usr/bin/env python3

import sys
from datetime import datetime, timedelta

def fmtdelta(delta):
    secs = delta.total_seconds()
    if secs < 60:
        return f"{secs}s"
    else:
        mins = secs / 60
        if mins < 60:
            return f"{mins}s"
        else:
            hours = mins / 60
            mins = mins % 60
            return f"{hours}h{mins}s"

def parsetime(s):
    if len(s) == 19:
        return datetime.strptime(s, "%Y-%m-%d %H:%M:%S")
    elif len(s) == 16:
        return datetime.strptime(s, "%Y-%m-%d %H:%M")
    elif len(s) == 10:
        return datetime.strptime(s, "%Y-%m-%d")
    raise ValueError(f"Unable to parse time {s}")

def read(filename, totimestamp):
    with open(filename,'r',encoding='utf-8') as f:
        for line in f:
            yield line
    if totimestamp > datetime.now():
        yield datetime.now().strftime("+%Y-%m-%d %a %H:%M") + " now"

output_delta = 0
fromtimestamp = datetime.now().replace(hour=0,minute=9, second=0)
totimestamp = datetime.now().replace(hour=0,minute=9, second=0) + timedelta(days=1)
prevtime=fromtimestamp
prevtask=""
pos = 0
filename = sys.argv[1]
for arg in sys.argv[2:]:
    if arg == '-d':
        output_delta = 1
    elif arg == '-s':
        output_delta = 2
    else:
        if pos == 0:
            fromtimestamp = parsetime(arg)
            pos += 1
        elif pos == 1:
            totimestamp = parsetime(arg)
        else:
            raise Exception(f"Unknown argument: {arg}")



for line in read(filename, totimestamp):
    line = line.strip()
    fields = line.split(' ')
    if len(fields) >= 3:
        timestamp = parsetime(fields[0] + " " + fields[2])
        if timestamp > fromtimestamp and timestamp < totimestamp and output_delta == 0:
            print(line)
            continue
        task = " ".join(fields[3:])
        if prevtask and output_delta != 0:
            delta = timestamp - prevtime
            if output_delta == 1:
                reltime = fmtdelta(delta)
            else:
                reltime = str(int(delta.total_seconds()))
            if prevtask != "idle":
                print(reltime, prevtask)
        if timestamp > fromtimestamp and timestamp < totimestamp:
            prevtask = task
            prevtime = timestamp
            if timestamp > totimestamp:
                break
        else:
            prevtask = ""


M todo.actions.d/timetrack => todo.actions.d/timetrack +6 -56
@@ 145,63 145,13 @@ case $action in
        fi
        ;;
    "log")
        if [ "$1" = "-d" ]; then
            output_delta=1
            shift
        elif [ "$1" = "-s" ]; then
            output_delta=2 #raw
            shift
        else
            output_delta=0
        fi
        if [ -z "$1" ]; then
            fromtimestamp=$(date --date="today 00:00:00" +%s)
        else
            fromtimestamp=$(date -d "$1" +%s)
            shift
        fi
        if [ -z "$1" ];  then
            totimestamp=$(date --date="tomorrow 00:00:00" +%s)
        else
            totimestamp=$(date -d "$1" +%s)
            shift
        fi
        prevdate="$fromtimestamp"
        prevtask=""
        #add an idle entry so we catch the current item as well if needed
        if [ "$totimestamp" -ge "$(date +%s)" ]; then
            echo "$NOW now" > /tmp/timetrack.idle
        else
            echo >/tmp/timetrack.idle
        fi
        cat "$TIMETRACK_FILE" /tmp/timetrack.idle | while read line ; do
            [ -z "$line" ] && continue
            date=$(echo "$line" | cut -d" " -f 1)
            time=$(echo "$line" | cut -d" " -f 3)
            timestamp=$(date -d "$date $time" +%s)
            if [ "$timestamp" -gt "$fromtimestamp" ] && [ "$timestamp" -lt "$totimestamp" ]; then
                if [ $output_delta -eq 0 ]; then
                    echo "$line"
                fi
            fi
            task=$(echo "$line" | cut -d" " -f 4-)
            if [ -n "$prevtask" ] && [ $output_delta -ne 0 ] ; then
                if [ $output_delta -eq 1 ]; then
                    reltime=$(fmtreltime "$prevdate" "$prevtime" "$date $time")
                elif [ $output_delta -eq 2 ]; then
                    reltime=$(reltime "$prevdate" "$prevtime" "$date $time")
                fi
                [ "$prevtask" != "idle" ] && echo "$reltime $prevtask"
            fi
            if [ "$timestamp" -gt "$fromtimestamp" ] && [ "$timestamp" -lt "$totimestamp" ]; then
                prevtask=$task
                prevdate="$date"
                prevtime="$time"
                [ "$timestamp" -gt "$totimestamp" ] && break
            else
                prevtask=""
            fi
        done
       #if [ "$totimestamp" -ge "$(date +%s)" ]; then
       #    echo "$NOW now" > /tmp/timetrack.idle
       #else
       #    echo >/tmp/timetrack.idle
       #fi
        "$SCRIPTDIR/helpers/timetrack_log.py" "$TIMETRACK_FILE" $@
        ;;
    summary)
        if [ "$1" = "--all" ] || [ "$1" = "-a" ]; then