Files
ordinaceprojekt/Medevio/zapis_poznamky.py
T
Vladimir Buzalka a9ef60212d notebookvb
2026-05-31 07:51:29 +02:00

203 lines
6.1 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Zapise poznamku lekare do Medevio kalendare (color=CHARCOAL).
Hlavni funkce: `zapis_poznamku()` - bere parametry:
calendar_id UUID kalendare (Vlado / manzelka / ...)
den date nebo str 'YYYY-MM-DD'
cas str 'HH:MM' nebo time
trvani_min int - delka v minutach
poznamka str - text
perioda None | str - "DAILY", "WEEKDAYS", atd. (zatim NotImplemented)
color ECRFIconColor enum, default CHARCOAL
clinic_slug default mudr-buzalkova
Vrati id vytvorene rezervace (str).
CLI:
python zapis_poznamky.py --den 2026-06-03 --cas 09:00 --trvani 5 --poznamka "Text"
python zapis_poznamky.py --den 2026-06-03 --cas 09:00 --trvani 5 --poznamka "Text" --kalendar manzelka
"""
import sys
import json
import argparse
from pathlib import Path
from datetime import datetime, date, time as dtime, timedelta
import requests
from dateutil import tz
try:
sys.stdout.reconfigure(encoding="utf-8")
except AttributeError:
pass
GRAPHQL_URL = "https://api.medevio.cz/graphql"
CLINIC_SLUG = "mudr-buzalkova"
PRAGUE_TZ = tz.gettz("Europe/Prague")
# Pojmenovane kalendare - viz pamet project-medevio-kalendar
CALENDARS = {
"vlado": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
"manzelka": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
}
DEFAULT_CALENDAR = "vlado"
BASE_DIR = Path(__file__).resolve().parent
TOKEN_PATH = BASE_DIR / "token.txt"
DEBUG_DIR = BASE_DIR / "debug"
MUTATION = """mutation CreateReservation_MakeReservationByDoctor(
$clinicSlug: String!,
$color: ECRFIconColor,
$note: String!,
$timeSlotInput: TimeSlotInput!
) {
reservation: makeReservationByDoctor(
clinicSlug: $clinicSlug
color: $color
note: $note
timeSlotInput: $timeSlotInput
) {
id
__typename
}
}"""
def _load_token() -> str:
token = TOKEN_PATH.read_text(encoding="utf-8").strip()
if token.startswith("Bearer "):
token = token.split(" ", 1)[1]
return token
def _headers() -> dict:
return {
"content-type": "application/json",
"authorization": f"Bearer {_load_token()}",
"origin": "https://my.medevio.cz",
"referer": "https://my.medevio.cz/",
}
def _to_utc_iso(dt: datetime) -> str:
if dt.tzinfo is None:
dt = dt.replace(tzinfo=PRAGUE_TZ)
return dt.astimezone(tz.UTC).strftime("%Y-%m-%dT%H:%M:%S.000Z")
def _resolve_calendar(calendar) -> str:
"""Prijme UUID nebo nazev ('vlado', 'manzelka'). Vrati UUID."""
if calendar in CALENDARS:
return CALENDARS[calendar]
if isinstance(calendar, str) and len(calendar) == 36 and calendar.count("-") == 4:
return calendar
raise ValueError(f"Neznamy kalendar: {calendar!r}. Pouzij UUID nebo jeden z {list(CALENDARS)}.")
def _resolve_day(den) -> date:
if isinstance(den, date) and not isinstance(den, datetime):
return den
if isinstance(den, datetime):
return den.date()
return datetime.strptime(str(den), "%Y-%m-%d").date()
def _resolve_time(cas) -> dtime:
if isinstance(cas, dtime):
return cas
return datetime.strptime(str(cas), "%H:%M").time()
def zapis_poznamku(
calendar: str = DEFAULT_CALENDAR,
den=None,
cas=None,
trvani_min: int = 5,
poznamka: str = "",
perioda: str | None = None,
color: str = "CHARCOAL",
clinic_slug: str = CLINIC_SLUG,
save_debug: bool = True,
) -> str:
"""Vytvori poznamku lekare v Medevio kalendari. Vraci id rezervace."""
if perioda is not None:
raise NotImplementedError(
"Periodicita zatim neni implementovana - neznam format payloadu. "
"Zachyt jednu opakujici se rezervaci pres Claude in Chrome a doplnime."
)
if den is None or cas is None:
raise ValueError("Musis zadat 'den' a 'cas'.")
calendar_id = _resolve_calendar(calendar)
d = _resolve_day(den)
t = _resolve_time(cas)
start_dt = datetime.combine(d, t).replace(tzinfo=PRAGUE_TZ)
end_dt = start_dt + timedelta(minutes=int(trvani_min))
payload = {
"operationName": "CreateReservation_MakeReservationByDoctor",
"variables": {
"clinicSlug": clinic_slug,
"color": color,
"note": poznamka,
"timeSlotInput": {
"calendarId": calendar_id,
"start": _to_utc_iso(start_dt),
"end": _to_utc_iso(end_dt),
},
},
"query": MUTATION,
}
r = requests.post(GRAPHQL_URL, headers=_headers(), data=json.dumps(payload), timeout=30)
r.raise_for_status()
data = r.json()
if save_debug:
DEBUG_DIR.mkdir(exist_ok=True)
debug_path = DEBUG_DIR / f"poznamka_{datetime.now():%Y%m%d_%H%M%S}.json"
debug_path.write_text(
json.dumps({"request": payload["variables"], "response": data}, ensure_ascii=False, indent=2),
encoding="utf-8",
)
print(f"[debug] {debug_path}")
if "errors" in data:
raise RuntimeError(f"GraphQL error: {data['errors']}")
res_id = data["data"]["reservation"]["id"]
print(f"OK: {d} {t:%H:%M} +{trvani_min}min '{poznamka}' -> {res_id}")
return res_id
def main():
ap = argparse.ArgumentParser(description="Zapis poznamku lekare do Medevio kalendare.")
ap.add_argument("--kalendar", default=DEFAULT_CALENDAR,
help=f"Jmeno ({'/'.join(CALENDARS)}) nebo UUID. Default '{DEFAULT_CALENDAR}'.")
ap.add_argument("--den", required=True, help="YYYY-MM-DD")
ap.add_argument("--cas", required=True, help="HH:MM (lokalni cas Europe/Prague)")
ap.add_argument("--trvani", type=int, default=5, help="delka v minutach (default 5)")
ap.add_argument("--poznamka", required=True, help="text poznamky")
ap.add_argument("--perioda", default=None,
help="opakovani (zatim NotImplemented)")
ap.add_argument("--color", default="CHARCOAL")
args = ap.parse_args()
zapis_poznamku(
calendar=args.kalendar,
den=args.den,
cas=args.cas,
trvani_min=args.trvani,
poznamka=args.poznamka,
perioda=args.perioda,
color=args.color,
)
if __name__ == "__main__":
main()