[HOME] | [ABOUT ME] | [BLOG] | [CONTACT]


Time Tracking

Originally I started time tracking with Clockify as part of learning Japanese to ensure immersion related goals were being met/exceeded. I migrated my data to Toggl (for no reason tbh), which I ultimately abandoned due to time tracking beginning to feel like a chore.

I looked into some alternatives and started tracking time again. Since January I’ve used timewarrior to track the time I allocate to productive activity. This includes most everything excluding necessities (food, hygeine, sleep, etc.) and leisure activity (english media consumption and gaming).

Scripting

Being that timewarrior is a command line program, the flexibility provided via Bash or Python scripting alone makes Timewarrior’s competition irrelevant.

I’ve written several scripts to streamline automatic tagging, starting, and stopping of new intervals. These scripts have resolved my complaints as they make interval management less of a chore by putting the controls just a key away.

A statusline block

The first script I wrote a few months ago is a simple status bar block. While a timewarrior interval is open (exit code 0), it shows the time since the interval started. When there is no open interval (exit code 1), it just shows the sum of all intervals for the day. At a glace, gives me a good idea of how the day is going productivity-wise.

#!/bin/python
from subprocess import run
timew = run(["timew"], capture_output=True,text=True)
if timew.returncode == 0:
    result = timew.stdout.split("\n  ")
    out = result.pop(0)[9:] + ": " + result.pop().split(maxsplit=1).pop().strip("\n")
    print(out)
else:
    summary = run(["timew", "summary", ":no-ids", ":no-tags"],capture_output=True,text=True).stdout
    # get day's total time
    summary = summary.split("\n")
    out = summary[-3].strip()
    print("Σ" + out)

I use this script in tandem with dwmblocks where it refreshes every 60 seconds. Alternatively the block can be force refreshed when dwmblocks receives an RTMIN+4 signal (this signal value is configured within dwmblocks config.h file). This signalling is incredibly useful for the following scripts.

Generic Keybind

I originally wrote this one in bash, but rewrote it in Python. This script has some non-python dependencies: dmenu and timewarrior. The entry object might be a little overkill for this usecase but for future timewarrior related projects/extensions, it should prove very useful.

I don’t consider this one done, I intend on revisiting it in the future to make adding new template intervals not require messing with the source file.

Script here (GitHub)

Immersion Keybind

For Japanese immersion I have a directory of symlinks to the content I’m currently immersing in. This one simply prompts the contents of a directory with dmenu, begins playback with mpv, tags the interval, and annotates it with the selected directory’s name. The script remains alive until the mpv session is closed by the user, where the interval is closed and the associated status bar block is refreshed to reflect this change.

#!/bin/sh
DIR="$HOME/anime/"
SELECTION=$(ls -1 $DIR | dmenu -l 20)
if [ -z "$SELECTION" ]; then
    exit
else
    mpv --save-position-on-quit --ignore-path-in-watch-later-config --playlist="$DIR$SELECTION" & 
    timew start anime immersion jp
    timew annotate "$SELECTION"
    pkill -RTMIN+4 dwmblocks
    wait $(pidof mpv)
    timew stop
    pkill -RTMIN+4 dwmblocks
fi