#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Sync open requests: checks each request marked as open in MySQL (doneAt IS NULL AND removedAt IS NULL) against the Medevio API. If the API shows the request is closed (doneAt) or removed (removedAt), updates MySQL accordingly. """ import json import sys import time import requests import pymysql from pathlib import Path from datetime import datetime # ============================== # UTF-8 output (Windows friendly) # ============================== try: sys.stdout.reconfigure(encoding="utf-8") sys.stderr.reconfigure(encoding="utf-8") except AttributeError: import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8") sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8") # ============================== # DRY RUN - set to True to only print what would be updated, False to actually update # ============================== DRY_RUN = False # ============================== # CONFIG # ============================== GRAPHQL_URL = "https://api.medevio.cz/graphql" CLINIC_SLUG = "mudr-buzalkova" TOKEN_PATH = Path(__file__).resolve().parent.parent / "token.txt" gateway_token = TOKEN_PATH.read_text(encoding="utf-8").strip() headers = { "content-type": "application/json", "authorization": f"Bearer {gateway_token}", "origin": "https://my.medevio.cz", "referer": "https://my.medevio.cz/", } DB_CONFIG = { "host": "192.168.1.76", "port": 3306, "user": "root", "password": "Vlado9674+", "database": "medevio", "charset": "utf8mb4", "cursorclass": pymysql.cursors.DictCursor, } GRAPHQL_QUERY = """ query GetPatientRequest2($requestId: UUID!, $clinicSlug: String!) { request: getPatientRequest2(patientRequestId: $requestId, clinicSlug: $clinicSlug) { id doneAt removedAt updatedAt } } """ def fix_datetime(dt_str): if not dt_str: return None try: return datetime.fromisoformat(dt_str.replace("Z", "+00:00")) except Exception: return None def fetch_request(request_id): payload = { "operationName": "GetPatientRequest2", "query": GRAPHQL_QUERY, "variables": { "requestId": request_id, "clinicSlug": CLINIC_SLUG, }, } for attempt in range(3): try: r = requests.post(GRAPHQL_URL, json=payload, headers=headers, timeout=30) break except (requests.ConnectionError, requests.Timeout, requests.exceptions.RequestException) as e: print(f" ⚠️ Attempt {attempt+1}/3 failed: {e}") time.sleep(2) else: print(f" ❌ Connection failed after 3 attempts for {request_id}") return None if r.status_code != 200: print(f" ❌ HTTP {r.status_code} for {request_id}") return None data = r.json() if "errors" in data: print(f" ❌ API error for {request_id}: {data['errors']}") return None return data.get("data", {}).get("request") # ============================== # MAIN # ============================== conn = pymysql.connect(**DB_CONFIG) # 1) Read all open requests from MySQL with conn.cursor() as cur: cur.execute( "SELECT id, displayTitle, pacient_prijmeni, pacient_jmeno " "FROM pozadavky WHERE doneAt IS NULL AND removedAt IS NULL" ) open_requests = cur.fetchall() mode = "DRY RUN" if DRY_RUN else "LIVE" print(f"🔧 Mode: {mode}") print(f"📋 Found {len(open_requests)} open requests in MySQL.\n") updated = 0 errors = 0 for i, req in enumerate(open_requests, 1): rid = req["id"] name = f"{req.get('pacient_prijmeni', '')} {req.get('pacient_jmeno', '')}".strip() title = req.get("displayTitle", "") print(f"[{i}/{len(open_requests)}] {name} – {title} ({rid})") api_data = fetch_request(rid) if api_data is None: errors += 1 continue api_done = api_data.get("doneAt") api_removed = api_data.get("removedAt") api_updated = api_data.get("updatedAt") if api_done or api_removed: done_dt = fix_datetime(api_done) removed_dt = fix_datetime(api_removed) updated_dt = fix_datetime(api_updated) status = "DONE" if api_done else "REMOVED" if DRY_RUN: print(f" 🔍 Would update → {status} (doneAt={api_done}, removedAt={api_removed})") else: with conn.cursor() as cur: cur.execute( "UPDATE pozadavky SET doneAt = %s, removedAt = %s, updatedAt = %s WHERE id = %s", (done_dt, removed_dt, updated_dt, rid), ) conn.commit() print(f" ✅ Updated → {status}") updated += 1 else: print(f" ⏳ Still open") # Be gentle with the API time.sleep(1) conn.close() print(f"\n{'='*50}") print(f"📊 Total open in MySQL: {len(open_requests)}") print(f"✅ Updated (closed/removed): {updated}") print(f"⏳ Still open: {len(open_requests) - updated - errors}") print(f"❌ Errors: {errors}")