Package: annextimelog
⚠️  This tool still in development. The most basic time tracking features recording, deletion, editing, search as well as syncing are implemented though.annextimelog- ⏱️Git Annex-backed Time TrackingThis is a brainstorm for aGit Annex-backed time tracker.
The idea originated across some of my Mastodon threads:https://fosstodon.org/@nobodyinperson/109596495108921683https://fosstodon.org/@nobodyinperson/109159397807119512https://fosstodon.org/@nobodyinperson/111591979214726456The gist is that I was (and still am) unhappy with the existing time tracking solutions. I worked withhledger's timeclockandtimewarrioreach for quite some time and built my own workflow and scripts around them.✅ RequirementsOver the years, the below features turned out to bemypersonal requirements for a time-tracking system (TL;DR: easy and intuitive recording, hassle-free syncing, data export for further analysis).
Here is a table comparing annextimelog withtimewarriorandhledger timeclock:✅ = feature available, 🟡 = partly available, ❌ = not availablefeaturetimewarriorhledgertimeclockannextimelogprecisestart and end times✅✅✅ as git-annex metadatatracking of overlapping/simultaneous periods❌🟡 (separate files)✅ backend can do itnice, colourful,graphical summary✅🟡✅ with Pythonrich, more plannedplain textdata storage✅✅🟡 buried ingit-annexbranchgit-friendly,merge conflict free data format🟡¹🟡¹✅ git-annex’ own merge strategyarbitrarytagsattachable to tracked periods✅🟡 hledger tags²✅ just git-annex metadataarbitrarynotesattachable to tracked periods🟡³🟡 hledger tags²✅ just git-annex metadatatags can havevalues❌✅ hledger tags²✅ just git-annex metadatafilesattach-/linkable to tracked periods❌🟡 path asfile:tag🟡 annexed files, linking is plannedclito start, stop, edit, etc. tracked periods✅⁴❌ own scripts needed🟡 recording and editingplugin system🟡⁵🟡⁶ (hledger’s own)❌ git-style plugin system planneddata exportto common format✅ (JSON)✅ (CSV, JSON)✅ as timeclock, JSON, cli commandssyncingfunctionality built-in❌❌✅ git-annex’s purpose is syncingmulti-usersupport❌❌✅ nothing in the way, just use tags¹last line is always modified, merge conflicts can arise when working from different machines²hledger tagshave limitations, e.g. no spaces, colons, commas, etc.³timewarrior annotations can't contain newlines for example. I wrote an extension to edit your annotation in your$EDITORand optionally GPG-encrypt it, which lets you add newlines. Quite an inconvenience.⁴timewarrior’s cli has some nasty inconveniences (e.g. no shortcut for ‘yesterday’, must painfully type out the full date, no intelligence to operate only on yesterday, gets confused and errors out in certain combinations of start/end times, etc…)⁵timewarrior extensions (here mine) are just fed the data via STDIN, not other command-line arguments. Not as useful as the git-style plugin system.⁶for the analysis part,hledgerplugins can be used. But as there is no actual cli to manage the data, there’s no plugin system for that.🛠️ ImplementationTo learn more about howannextimelogworks under the hood with git-annex as backend, have a look atdoc/implementation.📦 InstallationYou can run this tool if you havenixinstalled:# drop into a temporary shell with the command availablenixshellgitlab:nobodyinperson/annextimelog# install itnixprofileinstallgitlab:nobodyinperson/annextimelogOn Arch Linux you can install from theAURwith your favorite helper, or directly with pacman fromthis user repository.# use an AUR helper to installparu-SannextimelogOtherwise, you can install it like any other Python package, e.g. withpipor betterpipx:pipxinstallannextimelog# latest development versionpipxinstallgit+https://gitlab.com/nobodyinperson/annextimelogNote that in this case you will need to installgit-annexmanually.Any of the above makes theannextimelog(oratl) command available.❓ Usageusage:annextimelog[-h][--no-config][-ckey=value][--repoREPO][-n][--force][-v][-q][-O{json,console,timeclock,cli,rich}][--version|--version-only]{test,git,config,sync,sy,track,tr,delete,del,rm,remove,summary,su,ls,list,find,search}...

⏱️TimetrackerbasedonGitAnnex

options:-h,--helpshowthishelpmessageandexit--no-configIgnoreconfigfromgit-ckey=valueSetatemporaryconfigkey=value.Ifnotpresent,'annextimelog.'willbeprependedtothekey.--forceJustdoit.Ignorepotentialdataloss.--versionshowversioninformationandexit--version-onlyshowonlyversionandexitData:--repoREPOBackendrepositorytouse.Defaultsto$ANNEXTIMELOGREPO,$ANNEXTIMELOG_REPOor$XDG_DATA_HOME/annextimelog(currently:/tmp/annextimelog)-n,--dry-rundon't actually store, modify or delete events in the repo. Useful for testing what exactly commands would do.Note that the automatic repo creation is still performed.Output:Options changing output behaviour-v, --verbose         verbose output. More -v ⮕ more output-q, --quiet           less output. More -q ⮕ less output-O {json,console,timeclock,cli,rich}, --output-format {json,console,timeclock,cli,rich}Select output format. Defaults to 'console'.Subcommands:{test,git,config,sync,sy,track,tr,delete,del,rm,remove,summary,su,ls,list,find,search}test                run test suitegit                 Access the underlying git repositoryconfig              Convenience wrapper around 'atlgitconfig[annextimelog.]key[value],e.g.'atl config emojis false'willsettheannextimelog.emojisconfigtofalse.sync(sy)syncdatatrack(tr)recordatimeperioddelete(del,rm,remove)deleteaneventsummary(su,ls,list,find,search)showasummaryoftrackedperiods

🛠️Usage

Loggingevents:

>atltrworkfor4h@homewithclient=smallcorponproject=topsecret
>atltr10-11@doctor
>atltry22:00-30minagosleep@homequality=meh
>atl-vvvtr...# debug problemsNote:Commonprepositionslike'with','about',etc.areignored.Seethefulllistwith>python-c'from annextimelog.token import Noop;print(Noop.FILLERWORDS)'Listingevents:

>atl
>atllsweek
>atl-Ojsonls-a# dump all data as JSON>atl-Otimeclockls-a|hledger-ftimeclock:-bal--daily# analyse with hledgerRemovingeventsbyID:

>atlrmO3YzvZ4m

Syncing:# add a git remote of your choice>atlgitremoteaddgit@gitlab.com:you/yourrepo# sync up>atlsync

Configuration

>atl-ckey=value...# temporarily set config>atlconfigkeyvalue# permanently set config>atlconfigcommit...# whether events should be committed upon modification. Setting this to false can improve performance but will reduce granularity to undo changes.>atlconfigdryrun...# equivalent of -n / --dry-run>atlconfigemojis...# whether emojis should be shown in pretty-formated event output>atlconfigfast...# setting this to false will cause annextimelog be be more sloppy (and possible faster) by leaving out some non-critical cleanup steps.>atlconfiglonglist...# equivalent of specifying --long (e.g. atl ls -l)>atlconfigoutputformat...# equivalent of -O / --output-format>atlconfigweekstartssunday...# whether the week should start on Sunday instead of Monday (the default)🛠️ DevelopmentThis project usespoetry, so you can run the following in this repository to get into a development environment:poetryinstall
poetryshell# now you're in a shell with everything set upOther:# Auto-run mypy when file changes:justwatch-mypy# Auto-run tests when file changes:justwatch-test# Test how a sequence of command-line args is interpreted as event metadatajusttest-tokenswork@homenote=blamyfield+=one,two,three2hagountilnow# Run tests against a different Python versionjusttest-with-python-version3.10