Skip to content

Instantly share code, notes, and snippets.

@ewen-lbh
Last active March 30, 2022 13:23
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 ewen-lbh/488afb3f7f4c1393f563228a8ebbf758 to your computer and use it in GitHub Desktop.
Save ewen-lbh/488afb3f7f4c1393f563228a8ebbf758 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# TODO overall completion % instead of single-countdown.
"""
Usage:
pomodoro [SESSIONS] [CYCLES] [WORK] [BREAK] [PAUSE]
pomodoro --total-cycles=TOTAL_CYCLES --sessions-of=CYCLES
Arguments:
SESSIONS Number of sessions (cycles then pause) [default: 9999]
CYCLES Number of cycles (work then break) per session: [default: 4]
WORK Duration of a work period (in minutes) [default: 25]
BREAK Duration of a break period (in minutes) [default: 5]
PAUSE Duration of a pause period (in minutes) [default: 20]
Options:
--total-cycles=TOTAL_CYCLES Specifies a total number of cycles to do.
Will be split into (n//m) sessions of m cycles and one session of (n%m) cycles,
where n = --total-cycles and m = --sessions-of
--sessions-of=CYCLES See --total-cycles.
"""
from docopt import docopt
from time import sleep
from subprocess import run
from pathlib import Path
class StateFile:
def __init__(self, filepath: Path):
filepath.parent.mkdir(parents=True, exist_ok=True)
filepath.write_text("")
self.filepath = filepath
self.cycle = ""
self.cycle_number = 0
self.total_cycles = 0
self._total_time = 0
self.done = 0
@property
def total_time(self):
return self._total_time
@total_time.setter
def total_time(self, val):
self._total_time = val
self.done = 0
@property
def remaining(self):
return max([self.total_time - self.done, 0])
@property
def percentbar(self):
return f"[{int(self.done/self.total_time*100): 3}%]"
def __str__(self):
mins = lambda t: t//60
secs = lambda t: t%60
duration = lambda t: f"{int(mins(t)):02}'{int(secs(t)):02}\""
return f"{self.cycle_icon:<2} {self.cycle:>4} {duration(self.remaining) if self.remaining else 'done'}"
def tick(self):
self.done += 1
print(f"\033[K{self}", end="\r")
self.filepath.write_text(str(self))
@property
def cycle_icon(self):
''' return {
1: " ",
2: "¼",
3: "½",
4: "¾",
}.get(self.cycle_number, f"#{self.cycle_number}")'''
return f"{self.cycle_number}/{self.total_cycles}"
state = StateFile(Path("/home/ewen/.cache/pomodoro-state.txt"))
def countdown(time): # in seconds
state.total_time = time
while state.remaining:
state.tick()
sleep(1)
state.tick()
alert()
def alert():
run("mpv /home/ewen/rocketbook/Argon.ogg --start=00:00:10", shell=True, capture_output=True)
def work(duration=25):
print(f"--- start {duration} mins work period ---")
state.cycle = "study"
countdown(duration * 60)
def pause(duration=5):
print(f"--- starting {duration} mins pause period ---")
state.cycle = "break"
countdown(duration * 60)
def cycle(work_duration=25, pause_duration=5):
state.cycle_number += 1
work(work_duration)
pause(pause_duration)
def session(cycles: int = 4, work_for=25, pause_for=5, long_pause_for=20):
state.cycle_number = 0
for i in range(cycles-1):
print(f"=== starting cycle #{i+1} ===")
cycle(work_for, pause_for)
print(f"=== starting last cycle! ===")
cycle(work_for, long_pause_for)
if __name__ == "__main__":
try:
opts = docopt(__doc__)
def opt(key, default=0):
return int(opts.get(key) or default)
if opt("--total-cycles"):
complete_sessions, remainder_cycles = divmod(opt("--total-cycles"), opt("--sessions-of"))
state.total_cycles = opt("--total-cycles")
for _ in range(complete_sessions):
session(cycles=opt("--sessions-of"))
session(cycles=remainder_cycles)
else:
state.total_cycles = opt('CYCLES', 4)
for i in range(opt('SESSIONS', 9999)):
print(f"~~~ Starting session #{i+1} ~~~")
session(
cycles=opt('CYCLES', 4),
work_for=opt('WORK', 25),
pause_for=opt('BREAK', 5),
long_pause_for=opt('PAUSE', 20),
)
except KeyboardInterrupt:
print()
print("bye")
state.filepath.unlink()
# TODO: use SIGUSR1 to toggle time remaining display
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment