import csv import time from datetime import datetime, timedelta from pathlib import Path import pytz import zenipy WORK_MIN = 1 # Minutes for a work session SHORT_MIN = 1 # 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 def pomodoro_prompt_plan(whatdid = ''): 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 = '' return whatnext def pomodoro_prompt_report(whatnext): 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 = '' return whatdid def quit_prompt(): print('\nPress p to start a new pomodoro, q to quit') choice = input('p/q: ').strip() if choice.lower() in ('p', 'pomodoro'): return elif choice.lower() in ('q', 'quit', 'exit'): quit() else: quit_prompt() def log_step(text, start, end_section=False): 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(whatdid, start, end=None): 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]) def str_minutes(time_diff): return str(time_diff).split('.')[0] 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) while datetime.now(pytz.utc) <= end: to_go = end-datetime.now(pytz.utc) print('\r', str_minutes(to_go), sep='', end='') time.sleep(1) whatdid = pomodoro_prompt_report(whatnext) record_task(whatdid, start) log_step('Completed pomodoro: ' + whatdid, start, True) end = datetime.now(pytz.utc) + timedelta(minutes=SHORT_MIN) while datetime.now(pytz.utc) <= end: to_go = end-datetime.now(pytz.utc) print('\r', str_minutes(to_go), sep='', end='') time.sleep(1) continue except KeyboardInterrupt: time_spent = datetime.now(pytz.utc) - start if time_spent > timedelta(minutes=INTERRUPTED_MIN): 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) log_step('Incomplete, interrupted task:' + whatnext, start, True) if __name__ == '__main__': main()