Files
botPillbox/utils.py
T
2026-01-06 13:28:43 +07:00

94 lines
3.0 KiB
Python

#!/usr/bin/env python3
# utils.py
from datetime import datetime, date
from typing import List, Optional
from zoneinfo import ZoneInfo
from telegram import ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton
from config import BTN_ADD, BTN_LIST, BTN_EDIT, BTN_DELETE, BTN_HISTORY, BTN_TZ, BTN_CANCEL, TZ_SUGGESTIONS
# ----------------- UI HELPERS -----------------
def main_menu_kb():
kb = [
[BTN_ADD, BTN_LIST],
[BTN_EDIT, BTN_DELETE],
[BTN_HISTORY, BTN_TZ]
]
return ReplyKeyboardMarkup(kb, resize_keyboard=True, one_time_keyboard=False)
def tz_keyboard():
kb = [[tz] for tz in TZ_SUGGESTIONS]
kb.append(["Ввести вручную"])
kb.append([BTN_CANCEL])
return ReplyKeyboardMarkup(kb, one_time_keyboard=True, resize_keyboard=True)
def build_wd_keyboard(wd_sel: set):
labels = ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"]
kb = []
row = []
for i, lab in enumerate(labels):
prefix = "✅" if i in wd_sel else "◻️"
row.append(InlineKeyboardButton(f"{prefix} {lab}", callback_data=f"wd_toggle:{i}"))
if (i + 1) % 3 == 0:
kb.append(row)
row = []
if row:
kb.append(row)
kb.append([
InlineKeyboardButton("Готово", callback_data="wd_done"),
InlineKeyboardButton("Отмена", callback_data="wd_cancel")
])
return InlineKeyboardMarkup(kb)
# ----------------- DATA HELPERS -----------------
def parse_hhmm(s: str) -> Optional[str]:
s = s.strip()
try:
dt = datetime.strptime(s, "%H:%M")
return dt.strftime("%H:%M")
except ValueError:
return None
def weekdays_list_to_csv(lst: List[int]) -> str:
return ",".join(str(i) for i in sorted(set(lst))) if lst else ""
def weekdays_csv_to_list(csv: Optional[str]) -> List[int]:
if not csv:
return []
return [int(x) for x in csv.split(",") if x.isdigit()]
def now_utc() -> datetime:
return datetime.utcnow()
def utc_str_min(dt: datetime) -> str:
return dt.strftime("%Y-%m-%d %H:%M")
def utc_str_full(dt: datetime) -> str:
return dt.strftime("%Y-%m-%d %H:%M:%S")
def localized_now_for_tz(tzname: str) -> datetime:
try:
tz = ZoneInfo(tzname)
except Exception:
tz = ZoneInfo("UTC")
return datetime.now(tz)
def local_time_hhmm_for_user(tzname: str, when_utc: datetime) -> str:
try:
tz = ZoneInfo(tzname)
except Exception:
tz = ZoneInfo("UTC")
local = when_utc.astimezone(tz)
return local.strftime("%H:%M")
def user_local_hhmm_to_utc_dt(tzname: str, local_date: date, hhmm: str) -> datetime:
hour, minute = map(int, hhmm.split(":"))
local_dt = datetime(local_date.year, local_date.month, local_date.day, hour, minute)
try:
tz = ZoneInfo(tzname)
local_dt = local_dt.replace(tzinfo=tz)
except Exception:
tz = ZoneInfo("UTC")
local_dt = local_dt.replace(tzinfo=tz)
return local_dt.astimezone(ZoneInfo("UTC")).replace(tzinfo=None)