machine_setup/ansible/roles/sway/files/waybar_custom_clock.py

109 lines
3.1 KiB
Python
Raw Normal View History

2022-10-19 00:04:46 +00:00
#!/usr/bin/env python
#
# Custom waybar module for clocks. Implemented because the official clock module was downloading timezone definitions on every boot.
2022-10-19 02:15:04 +00:00
import datetime
2022-10-19 00:04:46 +00:00
import json
import sys
import time
from dataclasses import dataclass
2022-10-19 02:15:04 +00:00
from functools import lru_cache
2022-10-19 00:04:46 +00:00
from typing import Final, List, Optional
2022-10-19 02:15:04 +00:00
from zoneinfo import ZoneInfo
2022-10-19 00:04:46 +00:00
INTERVAL: Final[int] = 10
2022-10-19 02:15:04 +00:00
LOCAL_TIMEZONE = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo
2022-10-19 00:04:46 +00:00
@dataclass
class Update:
text: Optional[str]
alt: Optional[str]
tooltip: Optional[str]
css_class: Optional[List[str]]
percentage: Optional[str]
def dump(self) -> str:
# Dump a dict because we can't name our member variable "class"
return json.dumps(
{
k: v
for k, v in {
"text": self.text,
"alt": self.alt,
"tooltip": self.tooltip,
"class": self.css_class,
"percentage": self.percentage,
}.items()
if v is not None
}
)
2022-10-19 02:15:04 +00:00
@lru_cache(maxsize=1)
2022-10-20 02:35:48 +00:00
def make_calendar(today: datetime.date, tz: datetime.tzinfo):
2022-10-19 02:15:04 +00:00
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"
2022-10-20 02:35:48 +00:00
timezone_str = str(tz)
2022-10-19 02:15:04 +00:00
# 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 += " "
2022-10-19 02:29:23 +00:00
if print_day == today:
2022-10-20 02:35:48 +00:00
output += '<span foreground="#323232" background="#CCCCCC">'
2022-10-19 02:15:04 +00:00
output += f"{print_day.day: >2}"
2022-10-19 02:29:23 +00:00
if print_day == today:
output += "</span>"
2022-10-19 02:15:04 +00:00
print_day += datetime.timedelta(days=1)
2022-10-20 02:35:48 +00:00
output += f'\n<span size="small">{timezone_str}</span>'
2022-10-19 02:15:04 +00:00
return output
2022-10-19 00:04:46 +00:00
def main():
2022-10-19 02:15:04 +00:00
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.")
2022-10-19 00:04:46 +00:00
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
2022-10-19 02:15:04 +00:00
now = datetime.datetime.now(tz=tz)
text = now.strftime("%Y-%m-%d %H:%M")
2022-10-20 02:35:48 +00:00
tooltip = make_calendar(now.date(), tz)
2022-10-19 02:15:04 +00:00
2022-10-19 00:04:46 +00:00
out = Update(
2022-10-19 02:29:23 +00:00
text=text,
alt="foo",
tooltip=f"<tt>{tooltip}</tt>",
css_class=["foo"],
percentage="100",
2022-10-19 00:04:46 +00:00
)
2022-10-19 02:15:04 +00:00
2022-10-19 00:04:46 +00:00
print(out.dump(), flush=True)
if __name__ == "__main__":
main()