Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Work Day Tracker

A lightweight desktop popup that shows up twice a day and asks what you worked on. Entries go into a local CSV you can open in Excel or Google Sheets.

How it works

Two scheduled triggers fire on weekdays: one at 10am and one at 3:30pm (cron on Linux/WSL, Task Scheduler on Windows). Each one opens a small tkinter window with a prompt and a row-based input table (project, description, hours). The afternoon window also shows what you logged earlier that day, and those earlier rows are editable in place (blank a row out entirely to delete it).

Clicking "Log it" validates the hours fields (a typo like 2h flags the field red instead of landing in the CSV) and appends your entries to worklog.csv. Clicking "Skip" closes the window and writes nothing. "Snooze 30m" hides the popup and brings it back half an hour later, for the triggers that land mid-meeting. Closing the window with the title-bar X asks before discarding anything you typed. Keyboard-wise: Enter logs, Escape closes (with the same discard check), and Tab out of the last hours field starts a fresh row.

A lock file prevents duplicate windows if a scheduled trigger fires while one is already open, and every scheduled run writes a line to tracker.log next to tracker.py (popup shown, skipped because one was already open, or crashed with the traceback), so a popup that never appeared is diagnosable instead of a mystery.

Setup

Windows (no admin rights needed)

We run the app as a plain script under Python, not as a bundled .exe. An unsigned, self-scheduling binary trips Windows Defender's high-severity "persistence" detection, so a signed, sanctioned interpreter running our own script is the safer setup on a managed machine. See docs/windows-guide.md for the full walkthrough.

  1. Install Python (the Microsoft Store or a company software portal both work, no admin needed).

  2. Put tracker.py and scheduler.py in a folder you own, for example C:\Users\you\WorkDayTracker. The log, prefs, and assets all live next to tracker.py.

  3. Optional: create an assets subfolder and drop tsheet_categories.csv in it to enable the project autocomplete.

  4. Open a terminal in that folder and run:

    python tracker.py --install
    

    This creates two per-user scheduled tasks (no admin prompt). They launch pythonw.exe against tracker.py, so no console window flashes when a popup fires. The tasks are registered with missed-run catch-up (StartWhenAvailable) and are allowed to start on battery, so a 10:00 that passes while the laptop is asleep, locked before login, or undocked fires as soon as it can instead of being silently dropped. Those two settings are the fix for popups that "randomly" fail to appear; the schtasks defaults skip both cases without logging anything.

To remove the schedule later, run python tracker.py --uninstall and delete the folder.

Linux / WSL

python3 tracker.py --install

This writes two cron entries for weekdays at the times in prefs.json, with the session's DISPLAY/WAYLAND_DISPLAY baked into each line (cron strips the GUI environment, so without this the popup has nowhere to draw and dies silently). Installing from inside a virtualenv is safe: the cron line uses the system python3, not the venv interpreter.

Note: on WSL the cron popups only fire while WSL itself is running, since WSL2 shuts down when its last shell closes. Keep a terminal open across the check-in times, or use the native Windows setup above, which survives sleep and reboots. WSL remains fine for development (python3 tracker.py --now works in a desktop session).

Test it

python3 tracker.py --now

The --now flag skips the lock file check and opens the window immediately.

Customization

Project list

Put a CSV in assets/tsheet_categories.csv. The app reads project names from the first column named category (case-insensitive), or falls back to the first column if no such header exists. The names show up in an autocomplete dropdown on the project field, and the dropdown filters live as you type.

Preferences (prefs.json, or the Settings button in the popup)

Key Default What it does
morning_time "10:00" Morning check-in trigger (24h HH:MM)
afternoon_time "15:30" Afternoon check-in trigger, also the cutover for the greeting
chime true Play assets/fairy_dust.wav when the popup opens (toggle in Settings)
daily_target_hours 8 Target shown next to the running total, e.g. 6.5h of 8h

Output

Entries are written to worklog.csv in the same directory. It is created automatically on first submit if it does not exist yet.

Column Format Notes
date YYYY-MM-DD Always today's date at submit time
project string From the project dropdown or typed in
description string Free text
hours decimal Can be blank
logged_at YYYY-MM-DD HH:MM:SS Exact timestamp when "Log it" was clicked

Rows with all three fields blank are skipped. Partial rows (at least one field filled) are written with empty cells for the missing fields.

Files

work_day_tracker/
  tracker.py            # app logic and UI
  scheduler.py          # cron (Linux) / Task Scheduler (Windows) integration
  worklog.csv           # your log (auto-created, not committed)
  prefs.json            # popup times and options (auto-created, not committed)
  tracker.log           # what each scheduled run did (auto-created, not committed)
  assets/
    tsheet_categories.csv   # project name list (optional)
    fairy_dust.wav          # popup chime (optional, toggle in Settings)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages