99 lines
3.1 KiB
Python
Executable File
99 lines
3.1 KiB
Python
Executable File
#!/bin/env python3
|
|
import datetime
|
|
from tkinter import Tk, CENTER, Label
|
|
import click
|
|
import typing as t
|
|
import os
|
|
|
|
DELTASECONDS = "+%Ss"
|
|
DELTAMINUTES = "+%Mm"
|
|
DELTAHOURS = "+%Hh"
|
|
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,
|
|
DELTAHOURS,
|
|
DELTAMINUTES,
|
|
DELTASECONDS,
|
|
]
|
|
|
|
|
|
class DateTime(click.DateTime):
|
|
def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]:
|
|
try:
|
|
if value[0] == "+":
|
|
if format == DELTASECONDS and value[-1] == "s":
|
|
return datetime.datetime.now() + datetime.timedelta(
|
|
seconds=int(value[1:-1])
|
|
)
|
|
if format == DELTAMINUTES and value[-1] == "m":
|
|
return datetime.datetime.now() + datetime.timedelta(
|
|
minutes=int(value[1:-1])
|
|
)
|
|
if format == DELTAHOURS and value[-1] == "h":
|
|
return datetime.datetime.now() + datetime.timedelta(
|
|
hours=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
|
|
|
|
|
|
def start_app(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=0.5, rely=0.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 - datetime.datetime.now().microsecond // 1000, update)
|
|
|
|
root.bind("<Configure>", resize)
|
|
root.bind("<Escape>", lambda x: root.destroy())
|
|
root.after(1, update)
|
|
if os.environ.get("XDG_CURRENT_DESKTOP", "") == "i3":
|
|
root.wm_attributes("-type", "splash")
|
|
root.mainloop()
|
|
|
|
|
|
@click.command()
|
|
@click.argument("enddate", type=DateTime(formats=DATETIME_FORMAT))
|
|
def main(enddate):
|
|
start_app(enddate)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|