pomodoroprompt/pomodoroprompt.py

150 lines
5.2 KiB
Python
Raw Normal View History

import sys
import csv
2020-07-05 16:55:18 +00:00
import time
from datetime import datetime, timedelta
from pathlib import Path
from pytz import timezone
2020-10-10 03:44:46 +00:00
from playsound import playsound
2020-07-05 16:55:18 +00:00
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
2020-10-10 04:20:18 +00:00
QUIET = False
2020-07-05 16:55:18 +00:00
def pomodoro_prompt_plan(whatdid = ''):
""" Ask about what task will be worked on (showing last thing worked on)
"""
2020-07-06 12:43:56 +00:00
title = "What're you gonna do?"
text = ''
# 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 = ''
2020-07-05 20:00:19 +00:00
return whatnext
def pomodoro_prompt_report(whatnext):
""" Ask what task was completed, showing the last task claimed to be being worked on
"""
2020-07-06 12:43:56 +00:00
title = "What'd you do?"
text = ''
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 = ''
2020-07-05 20:00:19 +00:00
return whatdid
2020-07-05 16:55:18 +00:00
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)
2020-10-10 04:13:40 +00:00
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:
2020-07-06 12:48:24 +00:00
timelog.write(text + '\n')
2020-07-06 12:43:56 +00:00
if end_section:
2020-07-06 12:48:24 +00:00
timelog.write('\n\n')
def record_task(whatdid, start, end=None):
""" Record completed pomodoro to CSV
"""
if end is None:
end = datetime.now(pytz.utc)
with open('timelog.csv', 'a', newline='') as csvfile:
timewriter = csv.writer(csvfile)
timewriter.writerow([start, end, whatdid])
2020-07-05 16:55:18 +00:00
2020-07-06 12:43:56 +00:00
def str_minutes(time_diff):
""" Return at least whole seconds from a time difference
"""
2020-07-06 12:43:56 +00:00
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)
2020-07-05 16:55:18 +00:00
def main():
whatdid = ''
while True:
whatnext = pomodoro_prompt_plan(whatdid)
start = datetime.now(pytz.utc)
2020-07-06 13:27:00 +00:00
end = start + timedelta(minutes=WORK_MIN)
2020-07-06 12:43:56 +00:00
log_step('Start with plan: ' + whatnext, start)
try:
2020-07-06 13:27:34 +00:00
print('Working on: ', whatnext)
countdown_to(end)
2020-10-10 04:20:18 +00:00
if not QUIET:
playsound('res/timesup.aac')
whatdid = pomodoro_prompt_report(whatnext)
record_task(whatdid, start)
2020-07-06 12:43:56 +00:00
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)
2020-10-10 04:20:18 +00:00
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(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('Incomplete, interrupted task:' + whatnext, start)
2020-07-06 12:43:56 +00:00
log_step('Incomplete, interrupted task:' + whatnext, start, True)
2020-07-05 16:55:18 +00:00
if __name__ == '__main__':
main()