Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/tillkuhn/billy-idle

💤 Billy Idle - Lightweight MacOS (In)activity Tracker written in Go
https://github.com/tillkuhn/billy-idle

go grpc hours macos sqlite time-tracking timer tool work

Last synced: 8 days ago
JSON representation

💤 Billy Idle - Lightweight MacOS (In)activity Tracker written in Go

Awesome Lists containing this project

README

        

image:https://github.com/tillkuhn/billy-idle/actions/workflows/go.yml/badge.svg[ci-build]

== 💤 Billy Idle - Lightweight macOS (In)activity Tracker

Simple busy / idle time tracker inspired by the ancient article https://www.dssw.co.uk/blog/2015-01-21-inactivity-and-idle-time/[Inactivity and Idle Time on OS X].

== Background

According to the article, OS X has a timer called *HIDIdleTime* that tracks the last time you interacted with the computer, e.g. moved the mouse, typed a key, or interacted with the computer.

*billy-idle* simply queries this value periodically using the `ioreg` utility that ships with macOS, and matches it against a pre-defined threshold.
If exceeded, it will create a record for the busy time period in database.
This data can later be used as input for time tracking tools or statistics.

== Example Time Tracking Report

----
Friday January 10, 2025 (2025-01-10) Daily Report
----------------------------------------------------------------------------------------------------
🕰 | TIME RANGE | 🐝 BUSY RECORD
-----+---------------------+--------------------------------------------------------------------------------
☕ | 08:42:52 → 11:55:07 | Spent 3h12m Driving a Pickup truck Mark Lt to Minneapolis #874
🌞 | 12:24:19 → 12:35:00 | Spent 10m Drinking a Belgian And French Ale Orval Trappist Ale with 2.6% #875
🌞 | 13:24:14 → 15:08:20 | Spent 1h44m Building App Tealgrammar 5.8.4 in Orc #876
🌞 | 15:09:27 → 15:24:27 | Spent 15m Driving a Van A4 Cabriolet to Orlando #877
🌞 | 15:24:27 → now | Still busy with Eating a Frozen kahlua creme topped with Clementine #878
-----+---------------------+--------------------------------------------------------------------------------
🧮 | 5H23M +BREAK: 5H23M | BUSY+IDLE: 15H15M SKIP(<5M): 4 >REG(7H48M): -2H25M >MAX(10H): -4H37M
-----+---------------------+--------------------------------------------------------------------------------
Suggestestion: 09:00 → 14:23 (inc. 0m break), you're expected to be busy for another 2h25m
----

== Example Punch Clock Report

----
CW | 📅 DATE | WEEKDAY | 🐝 BUSY | ⏲️ PLAN | 🕰 OVERTIME
-----+-------------+-----------+---------+----------+-------------
1 | 2025-01-01 | Wednesday | 0m | 0m | 0m
| 2025-01-02 | Thursday | 7h50m | 7h48m | 2m
| 2025-01-03 | Friday | 8h10m | | 22m
| | | | |
2 | 2025-01-06 | Monday | 9h | 7h48m | 1h12m
| 2025-01-07 | Tuesday | 8h50m | | 1h2m
| 2025-01-08 | Wednesday | 8h40m | | 52m
-----+-------------+-----------+---------+----------+-------------
TOTAL | 42H30M | 3H30M
| 6 DAYS | >39H
----

== Run from source

[source,shell]
----
$ go run main.go

2024/10/01 17:13:29 🎬 billy started version=v0.0.2 built=2024-10-01T15:13:28Z pid=37477 go=go1.23.1 arch=arm64
2024/10/01 17:13:29 🥫 Open database file=~/.billy-idle/default/db.sqlite3 sqlite=3.46.0
2024/10/01 17:13:29 👀 Tracker started in idle mode with auto-idle>=2m0s interval=10s
2024/10/01 17:13:29 🐝 Enter busy mode after 0s idle time rec=#13
2024/10/01 17:15:33 💤 Checkpoint idleTime=11s state=idle lastSwitch=0s ago lastCheck=5s ago
2024/10/01 17:15:38 🛑 Received signal interrupt, initiate shutdown
2024/10/01 17:15:38 🛑 Tracker stopped after 0s busy time rec=#10
2024/10/01 17:15:38 🥫 Close database in ~/.billy-idle/dev
----

NOTE: Binary packages for macOS amd64 and arm64 are coming soon, the same goes for docker images on ghcr.io

== Install as launchd managed service (experimental)

Plist files in ~/Library/LaunchAgents/ are run at login with the id of the logged in user.
See https://stackoverflow.com/a/13372744/4292075[SO: launchctl and .plist file],
https://ieftimov.com/posts/create-manage-macos-launchd-agents-golang/[Create and manage MacOS LaunchAgents using Go]
and https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html#//apple_ref/doc/uid/10000172i-SW7-BCIEDDBJ[Launching Custom Daemons Using launchd]

[source,shell]
----
$ cp com.github.tillkuhn.billy-idle.plist ~/Library/LaunchAgents
$ launchctl load ~/Library/LaunchAgents/com.github.tillkuhn.billy-idle.plist
$ launchctl start com.github.tillkuhn.billy-idle

# in case of Load failed: 5: Input/output error, try this first
$ launchctl unload ~/Library/LaunchAgents/com.github.tillkuhn.billy-idle.plist
----

== CLI Arguments

.CLI Usage for track subcommand
[source,shell]
----
Starts the tracker in daemon mode to record busy and idle times.

Usage:
billy-idle track [flags]

Flags:
-a, --app-root string App root Directory e.g. for SQLite DB (defaults to $HOME/.billy-idle (default "/Users/tillkuhn/.billy-idle")
-c, --cmd string Command to retrieve HIDIdleTime (default "ioreg")
--drop-create Drop and re-create db schema on startup
-e, --env string Environment (default "dev")
-h, --help help for track
-m, --idle duration Max tolerated idle time before client enters idle state (default 10s)
-i, --interval duration Interval to check for idle time (default 2s)

Global Flags:
-d, --debug Debug checkpoints
----

.CLI Usage for report subcommand
[source,shell]
----
Generates a report based on the recorded idle and busy times.

Usage:
billy-idle report [flags]

Flags:
-a, --app-root string App Directory e.g. for SQLite DB (defaults to $HOME/.billy-idle/ (default "/Users/tillkuhn/.billy-idle")
-e, --env string Environment (default "default")
-h, --help help for report
--max-busy duration Max allowed time busy period per day (w/o breaks), report only (default 10h0m0s)
--min-busy duration Minimum time for a busy record to count for the report (default 5m0s)
--no-color Disable color output
--reg-busy duration Regular busy period per day (w/o breaks), report only (default 7h48m0s)

Global Flags:
-d, --debug Debug checkpoints
----

.CLI Usage for punch subcommand
[source,shell]
----
Punch busy time

Usage:
billy-idle punch [flags]

Flags:
-h, --help help for punch

Global Flags:
-d, --debug Debug checkpoints
----

== Database Support

*Billy Idle* currently only support a local https://gitlab.com/cznic/sqlite[sqlite] database, more precisely `modernc.org/sqlite` which is a cgo-free port of SQLite.
But it shouldn't be a big deal to add support for a remote https://www.postgresql.org[PostgreSQL] Database.

image:docs/sqlite.png[]

== Development

[source,shell]
----
$ make
Usage: make ...

Available targets are:

build build all targets
build-mac build for mac current arch using default goreleaser target path
clean Clean output directory
help Shows the help
install Install as launchd managed service
lint Lint go code
logs Show agent logs
minor Create Minor Release
release run goreleaser in snapshot mode
report Show report for default db
report-dev Show report for dev db
run Run app in tracker mode, add -drop-create to recreate db
run-help Run app in help mode
run-mac run mac build
test Run tests with coverage, implies lint
tidy Add missing and remove unused modules
update Update all go dependencies
----

== 🎸 Credits

image:https://upload.wikimedia.org/wikipedia/commons/thumb/7/74/Billy_idol_ill_artlibre_jnl.png/640px-Billy_idol_ill_artlibre_jnl.png[]

Source: https://commons.wikimedia.org/wiki/File:Billy_idol_ill_artlibre_jnl.png[Wikimedia Commons], terms of the https://en.wikipedia.org/wiki/en:Free_Art_License[Free Art License] apply.

== Contribution

If you want to contribute to *rubin* please have a look at the xref:CONTRIBUTING.md[]