#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Query Medevio for the full agenda of 17 Oct 2025, print raw API response, and export to Excel. """ import json import time from pathlib import Path import requests import pandas as pd from openpyxl import load_workbook from openpyxl.styles import Font, Alignment from openpyxl.utils import get_column_letter from datetime import datetime, timedelta from dateutil.relativedelta import relativedelta # přidá měsíce správně GRAPHQL_URL = "https://api.medevio.cz/graphql" CALENDAR_ID = "144c4e12-347c-49ca-9ec0-8ca965a4470d" CLINIC_SLUG = "mudr-buzalkova" # ==================== Load Token ==================== def load_gateway_token(storage_path="medevio_storage.json"): """Return Medevio gateway-access-token from saved Playwright storage.""" from pathlib import Path path = Path(storage_path) if not path.exists(): raise SystemExit(f"❌ Storage file not found: {path}") with path.open("r", encoding="utf-8") as f: state = json.load(f) token = next( (c["value"] for c in state["cookies"] if c["name"] == "gateway-access-token"), None ) if not token: raise SystemExit("❌ gateway-access-token not found in storage file.") return token gateway_token = load_gateway_token() headers = { "content-type": "application/json", "origin": "https://my.medevio.cz", "referer": "https://my.medevio.cz/", "authorization": f"Bearer {gateway_token}", } # === Dynamické datumy === tomorrow = datetime.utcnow().date() + timedelta(days=1) since = datetime.combine(tomorrow, datetime.min.time()).replace(microsecond=1) until = since + relativedelta(months=1) - timedelta(milliseconds=1) # ISO formát s "Z" (UTC) since_iso = since.isoformat() + "Z" until_iso = until.isoformat() + "Z" payload = { "operationName": "ClinicAgenda_ListClinicReservations", "variables": { "calendarIds": [CALENDAR_ID], "clinicSlug": CLINIC_SLUG, "since": since_iso, "until": "2025-11-30T21:59:59.999Z", "locale": "cs", "emptyCalendarIds": False, }, "query": """query ClinicAgenda_ListClinicReservations( $calendarIds: [UUID!], $clinicSlug: String!, $locale: Locale!, $since: DateTime!, $until: DateTime!, $emptyCalendarIds: Boolean! ) { reservations: listClinicReservations( clinicSlug: $clinicSlug, calendarIds: $calendarIds, since: $since, until: $until ) @skip(if: $emptyCalendarIds) { id start end note done color request { id displayTitle(locale: $locale) extendedPatient { name surname dob insuranceCompanyObject { shortName } } } } }""", } print("since:", since_iso) print("until:", until_iso) # ==================== Query API ==================== print("📡 Querying Medevio API for agenda...") r = requests.post(GRAPHQL_URL, headers=headers, data=json.dumps(payload)) print("Status:", r.status_code) try: data = r.json() except Exception as e: print("❌ Could not parse JSON:", e) print(r.text) raise SystemExit() if "data" not in data or "reservations" not in data["data"]: raise SystemExit("⚠️ No 'reservations' data found in response.") reservations = data["data"]["reservations"] from datetime import datetime from dateutil import parser, tz # ===== Process reservations into table ===== rows = [] for r in reservations: req = r.get("request") or {} patient = req.get("extendedPatient") or {} insurance = patient.get("insuranceCompanyObject") or {} # parse datetimes (convert to local time) try: start_dt = parser.isoparse(r.get("start")).astimezone(tz.gettz("Europe/Prague")) end_dt = parser.isoparse(r.get("end")).astimezone(tz.gettz("Europe/Prague")) except Exception: start_dt = end_dt = None date_str = start_dt.strftime("%Y-%m-%d") if start_dt else "" time_interval = f"{start_dt.strftime('%H:%M')}-{end_dt.strftime('%H:%M')}" if start_dt and end_dt else "" rows.append({ "Date": date_str, "Time": time_interval, "Title": req.get("displayTitle") or "", "Patient": f"{patient.get('surname','')} {patient.get('name','')}".strip(), "DOB": patient.get("dob") or "", "Insurance": insurance.get("shortName") or "", "Note": r.get("note") or "", "Color": r.get("color") or "", "Request_ID": req.get("id") or "", "Reservation_ID": r.get("id"), }) df = pd.DataFrame(rows).sort_values(["Date", "Time"]) # ===== Excel export ===== EXPORT_DIR = Path(r"C:\Users\vlado\PycharmProjects\Medevio\exports") EXPORT_DIR.mkdir(exist_ok=True) timestamp = time.strftime("%Y-%m-%d %H-%M-%S") xlsx_path = EXPORT_DIR / f"Medevio_agenda_{timestamp}.xlsx" # remove old files for old in EXPORT_DIR.glob("Medevio_agenda_*.xlsx"): try: old.unlink() except Exception: pass df.to_excel(xlsx_path, index=False) wb = load_workbook(xlsx_path) ws = wb.active # style header for col in range(1, len(df.columns) + 1): c = ws.cell(row=1, column=col) c.font = Font(bold=True) c.alignment = Alignment(horizontal="center") ws.column_dimensions[get_column_letter(col)].width = 20 ws.freeze_panes = "A2" wb.save(xlsx_path) print(f"📘 Exported clean agenda view to:\n{xlsx_path}")