commit 25c62420b64e6a67c14aa1c583fc5d5ca59893b2 Author: alexnigl Date: Sat Apr 5 03:29:44 2025 +0200 inital commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..20d7a5b --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Timer + +Pure Python Timer GUI. + +## Install +```sh +pipx install https://git.qu3.org/an/timer +``` + +## Usage + +5sec timer: `timer +5s` +5min timer: `timer +5m` +timer for 08:00 (present day) `timer 08:00` +timer for May 1st 2025 `timer 2025-05-01 00:00` diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..c8d59a3 --- /dev/null +++ b/setup.py @@ -0,0 +1,14 @@ +from setuptools import setup, find_packages + +setup( + name="timer", + version="0.1", + author="Alexander Nigl", + py_modules=["timer"], + install_requires=[ + "click", + ], + entry_points = { + 'console_scripts': ['timer=timer:main'], + } +) diff --git a/timer.py b/timer.py new file mode 100755 index 0000000..50717a8 --- /dev/null +++ b/timer.py @@ -0,0 +1,74 @@ +#!/bin/env python3 +import datetime +from tkinter import Tk, CENTER, Label +import click +import typing as t + + +class DateTime(click.DateTime): + def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]: + try: + if format == SECONDS and value[-1] == "s": + return datetime.datetime.now() + datetime.timedelta(seconds=int(value[1:-1])) + if format == MINUTES and value[-1] == "m": + return datetime.datetime.now() + datetime.timedelta(minutes=int(value[1:-1])) + if format == HOURS: + return datetime.datetime.combine( + datetime.datetime.now().date(), + datetime.datetime.strptime(value, format).time() + ) + return datetime.datetime.strptime(value, format) + except ValueError: + return None + + +SECONDS = '+%Ms' +MINUTES = '+%Mm' +HOURS = '%H:%M' +DATETIME_FORMAT = ['%Y-%m-%d', '%Y-%m-%dT%H:%M:%S', '%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', HOURS, MINUTES, SECONDS] + + +@click.command() +@click.argument("enddate", type=DateTime(formats=DATETIME_FORMAT)) +def main(enddate): + root = Tk() + root.geometry("300x100+200+200") + root.configure(background="#000") + tlbl = Label(root, text="", font=("Arial", -100), fg="#fff", bg="#000") + tlbl.pack() + tlbl.place(relx=.5, rely=.5, anchor=CENTER) + + def deltaStr(t): + days, remainder = divmod(t.total_seconds(), 60 * 60 * 24) + hours, remainder = divmod(remainder, 3600) + minutes, seconds = divmod(remainder, 60) + if days == 0: + if hours == 0: + if minutes == 0: + return f"{int(seconds):02d}" + return f"{int(minutes):02d}:{int(seconds):02d}" + return f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}" + return f"{int(days):02d}:{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}" + + def resize(_): + ratio = root.winfo_width() / 1920 + tlbl.configure(font=('Chicago', int(ratio * -200))) + + def update(): + delta = enddate - datetime.datetime.now() + if delta.total_seconds() < 0: + tlbl.configure(text="Now") + tlbl.config(fg="red") + else: + tlbl.configure(text=deltaStr(delta)) + root.after(1000, update) + + root.bind("", resize) + root.bind("", lambda x: root.destroy()) + root.after(1, update) + root.wm_attributes('-type', 'splash') + root.mainloop() + + +if __name__ == "__main__": + main()