#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Jednorázový skript: znovu stáhne přílohy pro 1c935d36-c9df-46a1-9ef2-b7f327f376c7 (Šmídová). Přeskočí přílohy, které jsou již v medevio_downloads. Po úspěchu označí požadavek jako zpracovaný. """ import requests import pymysql import time from pathlib import Path TARGET_REQUEST_ID = "1c935d36-c9df-46a1-9ef2-b7f327f376c7" RETRY_ATTEMPTS = 5 RETRY_DELAY = 3 # sekund mezi pokusy TOKEN_PATH = Path(__file__).resolve().parent.parent / "token.txt" DB_CONFIG = { "host": "192.168.1.76", "port": 3306, "user": "root", "password": "Vlado9674+", "database": "medevio", "charset": "utf8mb4", "cursorclass": pymysql.cursors.DictCursor, } GRAPHQL_QUERY = r""" query ClinicRequestDetail_GetPatientRequest2($requestId: UUID!) { patientRequestMedicalRecords: listMedicalRecordsForPatientRequest( attachmentTypes: [ECRF_FILL_ATTACHMENT, MESSAGE_ATTACHMENT, PATIENT_REQUEST_ATTACHMENT] patientRequestId: $requestId pageInfo: {first: 100, offset: 0} ) { attachmentType id medicalRecord { contentType description downloadUrl id url visibleToPatient } } } """ def extract_filename_from_url(url: str) -> str: try: return url.split("/")[-1].split("?")[0] except Exception: return "unknown_filename" def read_token(p: Path) -> str: tok = p.read_text(encoding="utf-8").strip() return tok.split(" ", 1)[1] if tok.startswith("Bearer ") else tok def download_with_retry(url: str, attempts: int, delay: int) -> bytes: for attempt in range(1, attempts + 1): try: r = requests.get(url, timeout=60) if r.status_code == 200: return r.content print(f" ⚠️ HTTP {r.status_code}, pokus {attempt}/{attempts}") except Exception as e: print(f" ⚠️ Chyba stahování (pokus {attempt}/{attempts}): {e}") if attempt < attempts: time.sleep(delay) raise RuntimeError(f"Stahování selhalo po {attempts} pokusech: {url}") def main(): token = read_token(TOKEN_PATH) headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} conn = pymysql.connect(**DB_CONFIG) # Načíst již stažené attachment_id pro tento požadavek with conn.cursor() as cur: cur.execute("SELECT attachment_id FROM medevio_downloads WHERE request_id = %s", (TARGET_REQUEST_ID,)) existing_ids = {row["attachment_id"] for row in cur.fetchall()} print(f"🔍 Zpracovávám požadavek {TARGET_REQUEST_ID}") print(f" Již staženo příloh: {len(existing_ids)}") # GraphQL dotaz payload = { "operationName": "ClinicRequestDetail_GetPatientRequest2", "query": GRAPHQL_QUERY, "variables": {"requestId": TARGET_REQUEST_ID}, } r = requests.post("https://api.medevio.cz/graphql", json=payload, headers=headers, timeout=30) attachments = r.json().get("data", {}).get("patientRequestMedicalRecords", []) print(f" Nalezeno příloh celkem: {len(attachments)}") # Načíst createdAt pro INSERT with conn.cursor() as cur: cur.execute("SELECT createdAt FROM pozadavky WHERE id = %s", (TARGET_REQUEST_ID,)) row = cur.fetchone() created_date = row["createdAt"] if row else None saved = 0 skipped = 0 errors = 0 with conn.cursor() as cur: for a in attachments: m = a.get("medicalRecord") or {} att_id = a.get("id") if att_id in existing_ids: print(f" ⏭️ Přeskočeno (již existuje): {att_id}") skipped += 1 continue url = m.get("downloadUrl") if not url: print(f" ⚠️ Příloha {att_id} nemá downloadUrl, přeskakuji") skipped += 1 continue try: content = download_with_retry(url, RETRY_ATTEMPTS, RETRY_DELAY) filename = extract_filename_from_url(url) cur.execute(""" INSERT INTO medevio_downloads ( request_id, attachment_id, attachment_type, filename, content_type, file_size, created_at, file_content ) VALUES (%s,%s,%s,%s,%s,%s,%s,%s) """, (TARGET_REQUEST_ID, att_id, a.get("attachmentType"), filename, m.get("contentType"), len(content), created_date, content)) existing_ids.add(att_id) print(f" 💾 Uloženo: {filename} ({len(content) / 1024:.1f} kB)") saved += 1 time.sleep(0.5) except Exception as e: print(f" ❌ Chyba: {e}") errors += 1 conn.commit() if errors == 0: with conn.cursor() as cur: cur.execute("UPDATE pozadavky SET attachmentsProcessed = NOW() WHERE id = %s", (TARGET_REQUEST_ID,)) conn.commit() print(f"\n✅ Hotovo. Uloženo: {saved}, přeskočeno: {skipped}. Požadavek označen jako zpracovaný.") else: print(f"\n⚠️ Hotovo s chybami. Uloženo: {saved}, přeskočeno: {skipped}, chyby: {errors}.") print(" Požadavek NEBYL označen jako zpracovaný (opakujte po kontrole).") conn.close() if __name__ == "__main__": main()