|
import pandas as pd |
|
from tqdm import trange |
|
import os |
|
import sys |
|
import time |
|
import math |
|
import signal |
|
from datetime import datetime as dt, timedelta |
|
|
|
# magic numbers |
|
GOAL_WEEK = 25 |
|
GOAL_DAYS = 5 |
|
GOAL_HOURS = GOAL_WEEK / GOAL_DAYS |
|
WAGE = 22.4 |
|
TIMESHEET_CSV = '~/timesheet.csv' |
|
|
|
# helpers |
|
def hours_to_seconds(hours): |
|
return math.ceil(hours * 60 * 60) |
|
|
|
def seconds_to_hours(seconds): |
|
return round((seconds / 60 / 60) + 0.0005, 3) |
|
|
|
def today_exists(): |
|
return timesheet.date[timesheet.shape[0]-1] == str(dt.date(dt.now())) |
|
|
|
def pay_period_hours(): |
|
# resets on even weeks (submit on odd weeks) |
|
if WEEK_NUM % 2 == 0: |
|
return round(timesheet[timesheet.week == WEEK_NUM].hours.sum() + 0.0005, 3) |
|
return round(timesheet[timesheet.week >= WEEK_NUM - 1].hours.sum() + 0.0005, 3) |
|
|
|
def pay_week_hours(): |
|
return round(timesheet[timesheet.week == WEEK_NUM].hours.sum() + 0.0005, 3) |
|
|
|
def calc_pay(hrs): |
|
return round(hrs * WAGE, 2) |
|
|
|
def print_days_completed(): |
|
print(f'\t{round(timesheet[timesheet.week == WEEK_NUM].hours.sum()/GOAL_HOURS, 1)} / {GOAL_DAYS} days') |
|
|
|
# save on ctrl-c |
|
def signal_handler(sig, frame): |
|
today_hours = round(seconds_to_hours(math.ceil(time.time() - start_time)) + |
|
today_prev_hours + 0.0005, 3) |
|
timesheet.at[timesheet.shape[0]-1, 'hours'] = today_hours |
|
timesheet.to_csv(TIMESHEET_CSV, index=False) |
|
if (today_hours != pd.read_csv(TIMESHEET_CSV).hours[timesheet.shape[0]-1]): |
|
print('file write error') |
|
print(f'\n\t{today_hours} hours, ${calc_pay(today_hours)}') |
|
print(f"\t{round(pay_period_hours(),1)} / {GOAL_HOURS * GOAL_DAYS} hrs, ${calc_pay(pay_week_hours())} / ${calc_pay(GOAL_HOURS * GOAL_DAYS)}") |
|
print_days_completed() |
|
sys.exit(0) |
|
|
|
# load data |
|
timesheet = pd.read_csv(TIMESHEET_CSV) |
|
WEEK_NUM = dt.date(dt.now()).isocalendar()[1] |
|
|
|
# hour submission output |
|
if (len(sys.argv) > 1 and sys.argv[1] == 'submit'): |
|
if WEEK_NUM % 2 == 0: |
|
print(timesheet[timesheet.week == WEEK_NUM]) |
|
else: |
|
print(timesheet[timesheet.week >= WEEK_NUM-1]) |
|
print(f"{pay_period_hours()} hrs, ${calc_pay(pay_period_hours())}") |
|
sys.exit(0) |
|
|
|
# time tracking initialization |
|
start_time = time.time() |
|
if not today_exists(): |
|
timesheet = pd.concat([timesheet, pd.DataFrame( |
|
{'date': [dt.date(dt.now())], 'hours': [0], 'week': [WEEK_NUM]})], ignore_index=True) |
|
today_prev_hours = timesheet.hours[timesheet.shape[0]-1] |
|
signal.signal(signal.SIGINT, signal_handler) |
|
|
|
# time tracking output |
|
print_days_completed() |
|
if today_prev_hours < GOAL_HOURS: |
|
print(f'\t{dt.now().strftime("%I:%M %p")} --> {(dt.now() + timedelta(hours=GOAL_HOURS - today_prev_hours)).strftime("%I:%M %p")}') |
|
for seconds in trange(0, hours_to_seconds(GOAL_HOURS), initial=hours_to_seconds(today_prev_hours)): |
|
time.sleep(1) |
|
if (seconds >= hours_to_seconds(GOAL_HOURS)): |
|
break |
|
os.system(f"osascript -e 'display alert \"{GOAL_HOURS} Hours Worked!\" message \"Congrats\"'") |
|
while True: |
|
for seconds in trange(0, hours_to_seconds(1)): |
|
time.sleep(1) |