pomodoroprompt/pomodoroprompt.py

150 lines
5.4 KiB
Python

import sys
import csv
import time
from datetime import datetime, timedelta
from pathlib import Path
from pytz import timezone
from playsound import playsound
import pytz
import zenipy
WORK_MIN = 25 # Minutes for a work session
SHORT_MIN = 5 # Minutes for a short break
LONG_MIN = 15 # Minutes for a long break (NOT YET IMPLEMENTED)
INTERRUPTED_MIN = 1 # Minimum minutes to ask to record an interrupted Pomodoro
QUIET = True
def pomodoro_prompt_plan(whatdid = ''):
""" Ask about what task will be worked on (showing last thing worked on)
"""
text = "What're you gonna do?"
title = ''
# Instead of repeating this, i'd prefer a clean interface with the ability to get back
# the placeholder text with 'esc' or up arrow or something. But i'm not up for building
# my own interface, so here's what we get. NOTE: If we can do system notifications that
# when clicked will focus the terminal running pomodoro prompt, that would be even better
# than these pop-up GUI notifications/text entry.
if whatdid:
text = "\n\n(Last thing you did: " + whatdid + ')\n'
whatnext = zenipy.zenipy.entry(text=text, placeholder=whatdid, title=title)
# Pressing cancel returns None, but we want to just treat it as an empty string.
if whatnext is None:
whatnext = ''
return whatnext
def pomodoro_prompt_report(whatnext):
""" Ask what task was completed, showing the last task claimed to be being worked on
"""
text = "What'd you do?"
title = ''
if whatnext:
text = "\n\n(What you said you'd do: " + whatnext + ')\n'
whatdid = zenipy.zenipy.entry(text=text, placeholder=whatnext, title=title)
# Pressing cancel returns None, but we want to just treat it as an empty string.
if whatdid is None:
whatdid = ''
return whatdid
def quit_prompt():
""" Confirm exit or start a new pomodoro
"""
print('\nPress p to start a new pomodoro, q to quit')
choice = input('p/q: ').strip().lower()
if choice in ('p', 'pomodoro'):
return
elif choice in ('q', 'quit', 'exit'):
sys.exit(0)
else:
quit_prompt()
def log_step(text, utc_start, end_section=False):
""" Write detailed log of all events
"""
eastern = timezone('US/Eastern')
start = utc_start.astimezone(eastern)
timelog_path = 'log/' + str(start.year) + '-' \
+ format(start.month, '02') + '-' \
+ format(start.day, '02') + '.log'
timelog_file = Path(timelog_path)
timelog_file.touch(exist_ok=True)
with timelog_file.open('a') as timelog:
timelog.write(text + '\n')
if end_section:
timelog.write('\n\n')
def record_task(whatnext, whatdid, start, end=None):
""" Record completed pomodoro to CSV
"""
if end is None:
end = datetime.now(pytz.utc)
with open('log/timelog.csv', 'a', newline='') as csvfile:
# TODO make first line started, recorded, description, intention
timewriter = csv.writer(csvfile)
timewriter.writerow([start, end, whatdid, whatnext])
def str_minutes(time_diff):
""" Return at least whole seconds from a time difference
"""
return str(time_diff).split('.')[0]
def countdown_to(until):
""" Display a timer counting down to until
"""
while datetime.now(pytz.utc) <= until:
to_go = until-datetime.now(pytz.utc)
print('\r', str_minutes(to_go), sep='', end='')
time.sleep(1)
def main():
whatdid = ''
while True:
whatnext = pomodoro_prompt_plan(whatdid)
start = datetime.now(pytz.utc)
end = start + timedelta(minutes=WORK_MIN)
log_step('Start with plan: ' + whatnext, start)
try:
print('Working on: ', whatnext)
countdown_to(end)
if not QUIET:
playsound('res/timesup.aac')
whatdid = pomodoro_prompt_report(whatnext)
record_task(whatnext, whatdid, start)
log_step('Completed pomodoro: ' + whatdid, start, True)
print('Worked on: ' + whatdid)
print('Break time!')
# We're taking a break. Clear out task start/end times.
start = None
end = datetime.now(pytz.utc) + timedelta(minutes=SHORT_MIN)
countdown_to(end)
if not QUIET:
playsound('res/timesup.aac')
continue
except KeyboardInterrupt:
if start is None:
quit_prompt()
continue
time_spent = datetime.now(pytz.utc) - start
if time_spent < timedelta(minutes=INTERRUPTED_MIN):
quit_prompt()
continue
time_spent_str = str_minutes(time_spent)
print('\n{} time spent, save?'.format(time_spent_str))
choice = input('[y]/n: ').strip()
if choice.lower() in ('y', 'yes', ''):
whatdid = pomodoro_prompt_report(whatnext)
record_task(whatnext, whatdid, start)
log_step('Incomplete (' + time_spent_str + ') pomodoro: ' + whatdid, start, True)
quit_prompt()
else:
print('What did you break?')
# If we somehow end up here, try a last-ditch effort to save.
record_task(whatnext, 'Incomplete, interrupted task:' + whatnext, start)
log_step('Incomplete, interrupted task:' + whatnext, start, True)
if __name__ == '__main__':
main()