• Stars
    star
    113
  • Rank 310,115 (Top 7 %)
  • Language
    Rust
  • License
    Other
  • Created almost 5 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An automated time tracker (WIP)

How did you spend your day?

teaser

plot screenshot

Track which projects you are working on and how much

timeline example

Add your own custom classification rules...

custom rules

...to get more detail

detailed plot screenshot

timetrackrs - an automatic rule-based time tracker

timetrackrs tracks what you spend your time on and stores it in a database. Inspired by arbtt, which I used previously.

Provides a Web UI to analyze it and create custom rules to improve the classification.

The user activity is tracked as "events", where each events has a timestamp, a duration, and a set of tags with values. You can think of tags as basically an extension of categories, allowing multiple category trees.

For example, an event can may have the following tags:

  • category:Productivity/Software Development/IDE
  • project:2021/timetrackrs
  • device:Home-PC

Which means in the UI you can figure out the time spent on software development, or on a specific project (not necessarily software development), or on a specific device.

Setup / Building

Note that this tool is not yet finished. There are no prebuilt binaries available yet.

git clone https://github.com/phiresky/timetrackrs.git
cd timetrackrs
# build frontend first
cd frontend
yarn install
yarn build
cd ..
# build and install `timetrackrs` binary to ~/.cargo/bin
./update-schemas.sh
cargo install --path .

You should start timetrackrs on user login. It will start the UI at http://localhost:52714/dashboard and start the default window tracking data source.

If you use systemd, you can use the included [timetrackrs.service] service file to auto-start timetrackrs.

Note for building in Windows: If you're experiencing an error related to openssl-sys either install the OpenSSL Library properly via vcpkg or add the --features openssl-vendored argument to the installation command, such as:

#build and install `timetrackrs` binary to ~/.cargo/bin
cargo install --features openssl-vendored --path .

Development

First, generate the dev-db needed for sqlx compilation:

./update-schemas.sh

To start a timetrackrs server (backend + frontend) without any capturing, you can run

RUST_LOG=debug,sqlx=warn,hyper=warn cargo run --bin timetrackrs -- --config data/debug_config.json

To continuously rebuild the frontend, do

cd frontend
yarn dev

Data Sources

Working Data Sources

  • Linux X11 tracking. Tracks the following properties:

    • Which program is open (binary name)
    • The window title
    • Which file does the program have open (via cmd args)
    • Connected WiFi (to be able to figure out rough location)
    • Some stats about the system

    Adds the following intrinsic tags:

    • software-window-title:...
    • software-executable-path:...
    • software-window-class:<X11 window class>
    • software-opened-file:<file path>
    • device-hostname:...

    and more.

  • App Usage import

    Allows tracking which apps / app categories are used on your Android devices.

    • device-hostname:...
    • device-type:<tablet or phone>
    • android-packageid:<play store package id>
    • software-name:<App Name>
    • device-os-type:Android
  • Browser Usage

    Tracks which websites / domains are used.

    Adds the following tags:

    • browse-url:https://...
    • browse-full-domain:news.ycombinator.com
    • browse-domain:ycombinator.com
  • VS Code tracking

    Tracks which software development projects you spend your time on, as well as which files.

    To enable, open your user settings and set window.title to ${dirty}${activeEditorShort}${separator}${rootName}${separator}${appName}} 🛤sd🠚proj=${rootPath}🙰file=${activeEditorMedium}🠘

    Adds the following tags:

    • software-development-project:<project-path>
  • Sleep As Android import

    Imports data of when and how you slept from the Sleep app.

    Creates events with the following tags:

    • physical-activity:sleeping
  • Timetrackrs import

    Imports data from a different timetrackrs database (e.g. from another device).

  • ZSH shell usage

    Adds the following tags:

    • title-match-shell-cwd:<current working directory>
    • title-match-shell-usr:<current username>
    • title-match-shell-cmd:<currently running program>

    To enable, install zsh-histdb, then add the following to your .zshrc:

    # set window title for timetrackrs
    # adopted from https://github.com/ohmyzsh/ohmyzsh/blob/master/lib/termsupport.zsh
    autoload -Uz add-zsh-hook
    
    function title_precmd {
        title_preexec '' ''
    }
    function title_preexec {
        # http://zsh.sourceforge.net/Doc/Release/Expansion.html
        # http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html#Prompt-Expansion
        local cwd="$(print -P '%~')"
        local user="$(print -P '%n@%m')"
        local LINE="$2"
        local cmd="$(print -P '%100>...>$LINE%<<')"
    
        title '' '{"t":"shell","cwd":${(qqq)cwd},"histdb":$HISTDB_SESSION,"usr":${(qqq)user},"cmd":${(qqq)cmd}}'
    }
    add-zsh-hook precmd title_precmd
    add-zsh-hook preexec title_preexec
    

Todo Data Sources

  • Fix Windows data source
  • More detailed browser usage (which containers are used, how did you get to website X?). Needs own webextension
  • mpv usage via (which TV shows and movies watched), via own mpv tracking lua script .config/mpv/scripts/logall.lua
  • Google Fitness import via API
  • Manual entry UI to add start/stop times and categories by hand.

External Info Fetchers

Timetrackrs supports fetching additional information from external sources.

Currently, the following are implemented:

  • Youtube Meta Fetcher

    Fetches some metadata when watching videos like the youtube category (Music / Educational / Entertainment / etc) and the channel. Adds the following tags:

    • youtube-channel:<uploader channel id>
    • youtube-channel-name:<uploader username>
    • youtube-tag:<tag-value> for each tag
    • youtube-category:<category> for each video category
  • Wikidata fetcher

    For each domain visited, tries to get some info about that domain from Wikidata. Adds the following tags.

    Adds the following tags when visiting e.g. reddit.com:

    • wikidata-label:Reddit
    • wikidata-id:Q1136
    • wikidata-category:social networking service
    • wikidata-category:social-news website
    • wikidata-category:mobile app

General Todo

Ideas for getting program metadata

Metadata we could potentially get:

  • Get open files from /proc/pid/fd
  • This program name can be mapped to a software package using the system package manager, example: pacman -Qo /usr/bin/vlc. Then that package name can be used to get metadata, for example the software homepage, tags etc.

Technical details

Philosophy

Store as much information in an as raw as possible format in the capture step. Interpret / make it usable later in the analyse step. This prevents accidentally missing interesting information when saving and can allow reinterpretions in unexpected ways later. Redundancies in the data which cause large storage requirements will be solved with compression later.

This is similar to arbtt, and specifically different to many other time tracking alternatives such as ActivityWatch, which stores processed data only.

Rule application

Each event has a set of "intrinsic tags" given by the data source. For example, an intrinsic tag of the window tracking data source would be window-title:Hey there! - Youtube - https://youtube.com/watch?v=xyz

Then there is a set of rules that add more tags based on existing tags. These are either simple derivations like "if software-executable-basename:vlc then add category:Entertainment" or based on external fetchers that retrieve data from external sources.

The rules are applied iteratively until settled. Here is an example rule derivation chain (you can view this for any tag in the UI):

Yesterday at 4:51 pm, you spent 30s in category: Entertainment/Video.

Derivation:

  1. The data source x11_v2 has the intrinsic tag software-window-title:Bloons TD 6 - YouTube - https://www.youtube.com/watch?v=bs-AUJF9nhs — Firefox
  2. The tag software-window-title matched the regex ^.*(?P<url>https?://[-a-zA-Z0-9@:%._\+~#=]{1,256}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)).*$, so the rule browse-url:$url in Default Rules added the tag browse-url:https://www.youtube.com/watch?v=bs-AUJF9nhs
  3. The InternalFetcher url-domain-matcher matched on the tag browse-url and added the tag browse-main-domain:youtube.com
  4. The ExternalFetcher youtube-meta-json matched on the tag browse-main-domain:youtube.com and queried YouTube to get the tags and categories, adding the tag youtube-category:Gaming.
  5. The tag youtube-category matched the regex ^(Gaming|Entertainment)$ so a rule in Default Rules added the tag category:Entertainment/Video.

Compression notes

Finish and make use of https://github.com/phiresky/sqlite-zstd. Then redundancy in the stored raw events should become basically irrelevant.

Compression benchmark:

for id in $(sqlite3 activity.sqlite3 "select id from events where data_type='x11'"); do sqlite3 activity.sqlite3 "select data from events where id='$id'" > "x11/$id.json"; done

Zstd test: 7400 x11 events rows:

  • 202M uncompressed (27kB avg)
  • 21M compressed without dictionary (2.8kbyte avg)
  • 20M compressed with xz -9
  • 5.0M compressed with generated dictionary (675byte avg), 110KB dictionary-file (which is default --maxdict)
  • 12M compressed with random sample json file as dictionary (1.6kbyte avg)
  • 11M compressed with dict generated 100 random json files (20kb dict file)
  • 2.7M compressed with large dict, 1MB dict file size (--maxdict=1000000)
  • 1.9MB as single file: zstd -19 all
  • 1.6MB as single file: zstd --ultra -22 --long=31 all
  • 1.3MB as single file (ordered by date) -19
  • 1.3MB as single file (ordered by date) --ultra -22 --long=31

Conclusion: zstd is awesome

Comparison to other tools

ActivityWatch

ActivityWatch is fairly similar, but it has a very different philosophy regarding the collected data (see above). It also has no option to fetch metadata from external sources, and the plugins are limited to the same computer (no import from a phone or some API like fitness or sleep tracking or similar).

I actually opened an issue in the ActivityWatch repo with some of the things I learned while writing timetrackrs, since so far it's not clear if I'll get timetrackrs to a production ready state.

Arbtt

  • Only tracks open programs
  • The performance does not scale well with db size, the analyze step always has to go through the whole database. Timetrackrs caches the extracted data in a separate database.
  • I've had a lot of database corruption issues in the past with it. Timetrackrs uses sqlite which is pretty safe.
  • No Web-UI, creating rules is hard
  • No external data fetchers, no importing from other apps

More Repositories

1

ripgrep-all

rga: ripgrep, but also search in PDFs, E-Books, Office documents, zip, tar.gz, etc.
Rust
8,147
star
2

sql.js-httpvfs

Hosting read-only SQLite databases on static file hosters like Github Pages
TypeScript
3,469
star
3

sqlite-zstd

Transparent dictionary-based row-level compression for SQLite
Rust
1,447
star
4

blog

Source code of my personal blog
TypeScript
339
star
5

world-development-indicators-sqlite

Python
152
star
6

procedural-cities

Information about procedural city generation
TeX
128
star
7

nmap-log-parse

Logs which devices are in your local network and draws graphs
TypeScript
127
star
8

pandoc-url2cite

Effortlessly and transparently add correctly styled citations to your markdown paper given only a URL
TypeScript
122
star
9

youtube-sponsorship-stats

TypeScript
121
star
10

tv-show-ratings

Compare the episode ratings of TV shows
TypeScript
75
star
11

neural-network-demo

Demonstration and visualization of feed-forward neural networks running in the browser
TypeScript
60
star
12

tuxguitar

unofficial mirror from sourceforge svn
Java
57
star
13

backchannel-prediction

Yeah, Right, Uh-Huh: A Deep Learning Backchannel Predictor
Python
54
star
14

tantivy-wasm

TypeScript
42
star
15

fbstats

generate facebook messaging statistics
TypeScript
38
star
16

levenshtein-demo

TypeScript
35
star
17

typed-socket.io

A library for fully typed client-server communication with socket.io and TypeScript.
TypeScript
30
star
18

encrypted-gist

Storing files in github gists, with client side transparent encryption and authentication
TypeScript
28
star
19

webrtc-remote-touch-pen-input

JavaScript
24
star
20

ts-histdbimport

Imports a `.zsh_history` file into a https://github.com/larkery/zsh-histdb sqlite database.
JavaScript
24
star
21

convolution-demo

Visualization of convolution on pairs of simple functions
TypeScript
18
star
22

thought-forge-ai

Generate 30-60 second "deep thought" TikTok-style video including a monologue, moving video scenes, music, and subtitles.
TypeScript
16
star
23

ebv-theta-to-mqtt

Perl
15
star
24

emojidome

Interactive viewer of the results of the Emojidome XKCD
TypeScript
14
star
25

dupegone

small fast duplicate file finder in c++
C++
11
star
26

redis-remotify

A tiny TypeScript library for fully typed remote calls via Redis.
TypeScript
9
star
27

mima

Mima Compiler and Interpreter for the browser
JavaScript
9
star
28

Gelddruckmaschine

Telegram bot that finds arbitrage opportunities between multiple crypto trading sites to print money mostly risk-free
JavaScript
8
star
29

warc-sqlite

POC of converting a set of WARC web archive files to a SQLite database and querying it
Python
7
star
30

phiresky.github.io

Lazy Github homepage generator
TypeScript
7
star
31

deep-intellisense

IntelliSense based on deep learning using char-rnn
TypeScript
6
star
32

endoh1-ts

Deobfuscating the ASCII fluid simulater and converting it to TypeScript
JavaScript
6
star
33

lemmy-federation-state

Quick visualization of the lemmy federation state
TypeScript
6
star
34

youtube-watch-history-parse

TypeScript
5
star
35

rpi-autousbupload

Automatically uploads photos from usb devices to an ftp server. Optimized for robustness on an Raspberry Pi.
Python
5
star
36

dfa2regex

Converts Deterministic finite automata to regular expressions.
JavaScript
5
star
37

minecraft-stats

Parses Vanilla Minecraft Server Statistics and displays graphs
JavaScript
4
star
38

fix-messy-movie-folder

Try to identify movie files in messy folders and sort them into a predefined structure
Java
4
star
39

rust-brotli-wasm

Two experiments of the brotli encoder / decoder compiled from Rust to WebAssembly.
Rust
4
star
40

RobinHood-TheLegendOfSherwood-Resolution-Patcher

Patch the resolution of Robin Hood: The Legend of Sherwood to support any resolution (e.g. 1920x1080)
C++
4
star
41

socket.io-distributor

Simple load leveling for socket.io
TypeScript
3
star
42

portfolio-bot

Telegram Bot that allows you to get information on your investments (stocks, ETFs, etc)
TypeScript
3
star
43

coronavirus-reproduction-analysis

Jupyter Notebook
3
star
44

qalc-react

Unit Calculator
TypeScript
3
star
45

gaussian-mixtures-demo

TypeScript
2
star
46

pythoven

Python
2
star
47

joint-multilingual-speech-recognition-and-language-id

TeX
2
star
48

tree-magic-cli

Rust
2
star
49

how-long-am-i-working

use google location history to graph how much time you've spent at a location (e.g. at work)
TypeScript
2
star
50

pingplot

plot a ping log
R
2
star
51

csv-cooccurrence-graph

Rust
2
star
52

RaspberrySmartScaleReceiver

Program to receive the body weight and body composition analysis data from a Soehnle 63760 BB smart scale using a 433 Mhz receiver on the Raspberry Pi.
C++
2
star
53

phiresky

1
star
54

rga-windows-test

Rust
1
star
55

bachelor-thesis

TeX
1
star
56

bayesian-aggregation-for-swarm-reinforcement-learning

Python
1
star
57

score-voting-tool

Rust
1
star
58

masters-thesis

HTML
1
star
59

algo2-summary

compact summary of stuff from the algorithms 2 lecture. Zusammenfassung der Algorithmen II Vorlesung am KIT
TeX
1
star
60

ocr-pdf-via-document-ai

OCR a set of images via the Google Cloud API
JavaScript
1
star
61

plangraph-impl

Implementation of some algorithms for planar graphs
JavaScript
1
star
62

guitar-tabs

Static hosted version of the guitar tabs portion of my old (<2010) website
CSS
1
star
63

plangraph

Mitschrieb zur Vorlesung planare Graphen KIT SS2015
Python
1
star
64

kogsys-demos

overview page for all the lecture demonstrations
HTML
1
star
65

ts-boilerplates

just some simple boilerplates for me to use
TypeScript
1
star
66

nushell-history-skim

Rust
1
star
67

prosem-proto

Simple procedural town generation (for Proseminar)
TypeScript
1
star
68

fourier-series-demo

TypeScript
1
star