Skip to content

Instantly share code, notes, and snippets.

@ShyftXero
Last active February 16, 2024 16:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ShyftXero/9d1cccdecd61a965db27016f300f18a7 to your computer and use it in GitHub Desktop.
Save ShyftXero/9d1cccdecd61a965db27016f300f18a7 to your computer and use it in GitHub Desktop.
# 20240215
# shyft
# script to prove my wife wrong about how much time I'm spending at my computer in the eventing.
# use with caution... may not be worth it to you...
# relies on https://github.com/ActivityWatch/activitywatch/ "Records what you do so that you can know how you've spent your time."
# grown from https://github.com/ActivityWatch/aw-client/blob/master/examples/time_spent_today.py
import sys
from datetime import date, datetime, time, timedelta, timezone
from rich import print
import socket
from typer import Typer
import aw_client
app = Typer()
@app.command()
def win(NUM_DAYS:int=7, EVENING_START:int=17, ACTIVITY_THRESHOLD:int=30, verbose:bool=False):
"""
NUM_DAYS = 7 # look back at the last week
EVENING_START = 17 # 5pm
ACTIVITY_THRESHOLD = 30 # min number of seconds of non-afk activity to consider in the calculation of being "at your computer"
"""
# Set this to your AFK bucket
bucket_id = f"aw-watcher-afk_{socket.gethostname()}"
td = timedelta(days=NUM_DAYS)
daystart = datetime.combine(datetime.now().date() - td, time())
dayend = daystart + td + timedelta(days=1) # to account for today as well
min_usage_thresh_td = timedelta(seconds=ACTIVITY_THRESHOLD)
awc = aw_client.ActivityWatchClient("afterwork_tracking")
raw_events = awc.get_events(bucket_id, start=daystart, end=dayend)
raw_events = sorted(raw_events, key=lambda x: x.timestamp.astimezone())
# breakpoint()
daily_sums = dict()
after5_events = list()
for e in raw_events:
if e.duration < min_usage_thresh_td:
continue # skip this event if its duration is less than the threshold.
ts = e.timestamp.astimezone() # convert to central time for conginitve ease
# after 5pm and active form more than 60 seconds by default
if e.data["status"] == "not-afk" and ts.hour >= EVENING_START:
after5_events.append(e)
# breakpoint()
if ts.date() not in daily_sums.keys():
daily_sums[ts.date()] = e.duration
if verbose:
print('adding new ', e.duration, 'to', ts.date(), 'initiated at', ts,'event id=', e.id)
else:
if verbose:
print('adding additional ', e.duration, 'to', ts.date(), 'initiated at', ts,'event id=', e.id)
# print(e.timestamp,'duration', e.duration)
daily_sums[ts.date()] += e.duration
# print(e.timestamp,'duration', e.duration)
after5_events_durations = [e.duration for e in after5_events]
total_duration = sum(after5_events_durations, timedelta())
print(f"[yellow]{'='*25}[/yellow]")
print('[yellow]Daily Summaries[/yellow]')
print(f"[yellow]{'='*25}[/yellow]")
for k,verbose in daily_sums.items():
print(f'{k} - time spent in evening {verbose}')
print(f"[green]{'='*25}[/green]")
print('[green]Stats[/green]')
print(f"[green]{'='*25}[/green]")
print(f"Total time spent on computer after {timedelta(hours=EVENING_START)} in last {NUM_DAYS} days: {total_duration} (HH:MM:SS) where each instance of usage is at least {min_usage_thresh_td} long")
print(f'Average amount of time per non-afk instance {total_duration/len(after5_events_durations)}')
if __name__ == "__main__":
app()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment