diff --git a/ansible/roles/sway/files/waybar_config.json b/ansible/roles/sway/files/waybar_config.json index 4d13bc9..1b3d667 100644 --- a/ansible/roles/sway/files/waybar_config.json +++ b/ansible/roles/sway/files/waybar_config.json @@ -20,7 +20,7 @@ "spacing": 10 }, "custom/clock": { - "exec": "waybar_custom_clock", + "exec": "waybar_custom_clock 'America/New_York'", "return-type": "json", "restart-interval": 30 } diff --git a/ansible/roles/sway/files/waybar_custom_clock.py b/ansible/roles/sway/files/waybar_custom_clock.py index 9cef0b2..6a2fe35 100644 --- a/ansible/roles/sway/files/waybar_custom_clock.py +++ b/ansible/roles/sway/files/waybar_custom_clock.py @@ -1,13 +1,17 @@ #!/usr/bin/env python # # Custom waybar module for clocks. Implemented because the official clock module was downloading timezone definitions on every boot. +import datetime import json import sys import time from dataclasses import dataclass +from functools import lru_cache from typing import Final, List, Optional +from zoneinfo import ZoneInfo INTERVAL: Final[int] = 10 +LOCAL_TIMEZONE = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo @dataclass @@ -35,17 +39,56 @@ class Update: ) +@lru_cache(maxsize=1) +def make_calendar(today: datetime.date, tz: datetime.tzinfo): + width: Final[int] = 20 + start_of_month = today.replace(day=1) + month_header = today.strftime("%B %Y") + padding = width - len(month_header) + right_padding = " " * (padding // 2) + left_padding = right_padding + (" " if padding % 2 == 1 else "") + header = f"{left_padding}{month_header}{right_padding}" + days_of_week = "Su Mo Tu We Th Fr Sa" + + # Make the grid + first_day_padding = " " * ( + 0 if start_of_month.weekday() == 6 else (3 * (1 + start_of_month.weekday())) - 1 + ) + output = f"{header}\n{days_of_week}\n{first_day_padding}" + + print_day = start_of_month + while print_day.month == today.month: + if print_day.weekday() == 6: + output += "\n" + else: + output += " " + output += f"{print_day.day: >2}" + print_day += datetime.timedelta(days=1) + return output + + def main(): + tz: Optional[datetime.tzinfo] = ( + ZoneInfo(sys.argv[1]) if len(sys.argv) >= 2 else LOCAL_TIMEZONE + ) + if tz is None: + raise Exception("Failed to detect timezone.") + next_update = time.time() while True: time_before_next_update = next_update - time.time() if time_before_next_update > 0: time.sleep(time_before_next_update) next_update = time.time() + INTERVAL - argv = json.dumps(sys.argv) + + now = datetime.datetime.now(tz=tz) + text = now.strftime("%Y-%m-%d %H:%M") + tooltip = make_calendar(now.date(), tz) + out = Update( - text="foo", alt=argv, tooltip=argv, css_class=["foo"], percentage="100" + text=text, alt="foo", tooltip=tooltip, css_class=["foo"], percentage="100" ) + print(out.dump(), flush=True)