diff --git a/main.py b/main.py index c92b578..d0957d5 100755 --- a/main.py +++ b/main.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python3 +#! /home/gum/p/break/.venv/bin/python # vim:fenc=utf-8 # # Copyright © 2023 gum @@ -12,34 +12,23 @@ Play my playlist every few minutes. import sys import threading from argparse import ArgumentParser +from datetime import datetime from select import select from subprocess import DEVNULL, Popen, run from termios import TCIOFLUSH, tcflush from time import sleep, time - -class StoppableThread(threading.Thread): - """Thread class with a stop() method. The thread itself has to check - regularly for the stopped() condition.""" - - def __init__(self, *args, **kwargs): - super(StoppableThread, self).__init__(*args, **kwargs) - self._stop_event = threading.Event() - - def stop(self): - self._stop_event.set() - - def stopped(self): - return self._stop_event.is_set() +WINDOW_TITLE = "" -def generate_interval(interval: int): +def generate_interval(work_time: int, break_time: int): """ Generate the interval between plays in seconds. """ - if interval: + if work_time and break_time: while True: - yield int(interval) + yield work_time + yield break_time else: # pomodoro scheme while True: @@ -60,24 +49,103 @@ def play_playlist(playlist): def wait_or_enter(duration, i3_focus=False): + """ + A timer that will stop if the user presses enter. + The i3_focus flag will focus the i3 window with the title "break" to prevent the user from doing other things while the timer lasts. + """ stop = "" start = time() + if i3_focus: + run( + ["i3-msg", f'[title="{WINDOW_TITLE}"] focus, fullscreen'], + stdout=DEVNULL, + stderr=DEVNULL, + ) while not stop and (time() - start < duration): # Run until flag is True if i3_focus: - run(["i3-msg", '[title=\"break\"] focus']) + run( + ["i3-msg", f'[title="{WINDOW_TITLE}"] focus'], + stdout=DEVNULL, + stderr=DEVNULL, + ) stop, _, _ = select([sys.stdin], [], [], 1) - tcflush(sys.stdin, TCIOFLUSH) + + if i3_focus: + run( + ["i3-msg", f'[title="{WINDOW_TITLE}"] move to scratchpad'], + stdout=DEVNULL, + stderr=DEVNULL, + ) + + if stop: + return sys.stdin.readline().strip() + else: + tcflush(sys.stdin, TCIOFLUSH) + return -def main(playlist, interval): - for i in generate_interval(interval): - play = play_playlist(playlist) - print(f"playlist playing, press enter to start {i // 60} minute interval") - wait_or_enter(float("inf"), i3_focus=True) - play.terminate() - print("...") +def write_break_message(msg): + today = datetime.now().strftime("%Y-%m-%d") + minute = datetime.now().strftime("%H:%M") + msg = f"{minute} BREAK {msg}" + with open(f"/home/gum/z/{today}.md", "a") as f: + print(msg) + f.write(msg + "\n") + + +def main(playlist, work_time, break_time): + interval = generate_interval(work_time, break_time) + + print( + "testing playlist, press enter to start if you hear the playlist", + end="", + flush=True, + ) + play = play_playlist(playlist) + wait_or_enter(float("inf"), i3_focus=True) + play.terminate() + + while True: + # work + i = next(interval) + print("work for", i // 60, "minutes", end="", flush=True) wait_or_enter(i) - print("next") + + # break + i = next(interval) + print("break for", i // 60, "minutes", end=" ", flush=True) + msg = wait_or_enter(i, i3_focus=bool(WINDOW_TITLE)) + + # start music to signal the end of a break. + if not msg: + print("> ", end="", flush=True) + play = play_playlist(playlist) + msg = wait_or_enter(float("inf"), i3_focus=bool(WINDOW_TITLE)) + play.terminate() + + write_break_message(msg) + + +def timer(playlist, duration): + print( + "testing playlist, press enter to start if you hear the playlist", + end="", + flush=True, + ) + play = play_playlist(playlist) + wait_or_enter(float("inf"), i3_focus=bool(WINDOW_TITLE)) + play.terminate() + + # work + print("wait for", duration, "seconds") + msg = wait_or_enter(duration, i3_focus=bool(WINDOW_TITLE)) + + # start music to signal the end of a break. + if msg is None: + print("timer is over, press enter to quit", end="", flush=True) + play = play_playlist(playlist) + wait_or_enter(float("inf"), i3_focus=bool(WINDOW_TITLE)) + play.terminate() if __name__ == "__main__": @@ -88,11 +156,33 @@ if __name__ == "__main__": help="path to the folder with the playlist to play", ) parser.add_argument( - "--interval", + "--work-time", default=None, - type=str, + type=int, help="Interval between plays in minutes, if empty I use the pomodoro scheme.", ) + parser.add_argument( + "--break-time", + default=None, + type=int, + help="Interval between plays in minutes, if empty I use the pomodoro scheme.", + ) + parser.add_argument( + "--window-title", + default=None, + type=str, + help="window title of this program, to prevent the user from doing other things during a break.", + ) + parser.add_argument( + "--once", + default=None, + type=int, + help="set true for this to be a single timer", + ) args = parser.parse_args() + WINDOW_TITLE = args.window_title - main(args.playlist, args.interval) + if args.once: + timer(args.playlist, args.once) + else: + main(args.playlist, args.work_time, args.break_time)