diff --git a/.idea/Medevio.iml b/.idea/Medevio.iml
index 3cd7809..b51fc52 100644
--- a/.idea/Medevio.iml
+++ b/.idea/Medevio.iml
@@ -4,7 +4,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 7a3c570..35161d5 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,5 +3,5 @@
-
+
\ No newline at end of file
diff --git a/10ReadPozadavky/PRAVIDELNE_0_READ_ALL_ACTIVE_POZADAVKY.py b/10ReadPozadavky/PRAVIDELNE_0_READ_ALL_ACTIVE_POZADAVKY.py
index cbabdcf..755cb6c 100644
--- a/10ReadPozadavky/PRAVIDELNE_0_READ_ALL_ACTIVE_POZADAVKY.py
+++ b/10ReadPozadavky/PRAVIDELNE_0_READ_ALL_ACTIVE_POZADAVKY.py
@@ -8,6 +8,18 @@ from datetime import datetime, timezone
import time
from dateutil import parser
+# Force UTF-8 output even under Windows Task Scheduler
+import sys
+try:
+ sys.stdout.reconfigure(encoding='utf-8')
+ sys.stderr.reconfigure(encoding='utf-8')
+except AttributeError:
+ # Python < 3.7 fallback (not needed for you, but safe)
+ import io
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
+ sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
+
+
# ================================
# 🔧 CONFIGURATION
# ================================
diff --git a/10ReadPozadavky/PRAVIDELNE_1_ReadLast300DonePozadavku.py b/10ReadPozadavky/PRAVIDELNE_1_ReadLast300DonePozadavku.py
index f7d4590..aefb18b 100644
--- a/10ReadPozadavky/PRAVIDELNE_1_ReadLast300DonePozadavku.py
+++ b/10ReadPozadavky/PRAVIDELNE_1_ReadLast300DonePozadavku.py
@@ -6,13 +6,41 @@ import requests
from pathlib import Path
from datetime import datetime
from dateutil import parser
+import sys
+
+# Force UTF-8 output even under Windows Task Scheduler
+import sys
+try:
+ sys.stdout.reconfigure(encoding='utf-8')
+ sys.stderr.reconfigure(encoding='utf-8')
+except AttributeError:
+ # Python < 3.7 fallback (not needed for you, but safe)
+ import io
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
+ sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
+
+# ================================
+# 🛡 SAFE PRINT FOR CP1250 / Emoji
+# ================================
+def safe_print(text: str):
+ enc = sys.stdout.encoding or ""
+ if not enc.lower().startswith("utf"):
+ # strip emoji + characters outside BMP
+ text = ''.join(ch for ch in text if ord(ch) < 65536)
+ try:
+ print(text)
+ except UnicodeEncodeError:
+ # final fallback to ASCII only
+ text = ''.join(ch for ch in text if ord(ch) < 128)
+ print(text)
+
# ================================
# 🔧 CONFIGURATION
# ================================
TOKEN_PATH = Path("token.txt")
CLINIC_SLUG = "mudr-buzalkova"
-LIMIT = 300 # stáhneme posledních 300 ukončených požadavků
+LIMIT = 300
DB_CONFIG = {
"host": "192.168.1.76",
@@ -24,7 +52,7 @@ DB_CONFIG = {
"cursorclass": pymysql.cursors.DictCursor,
}
-# ⭐ Ověřený dotaz s lastMessage
+# ⭐ GraphQL query
GRAPHQL_QUERY = r"""
query ClinicRequestList2(
$clinicSlug: String!,
@@ -71,33 +99,31 @@ def read_token(path: Path) -> str:
return tok.split(" ", 1)[1]
return tok
+
# ================================
-# DATETIME PARSER (UTC → MySQL)
+# DATETIME PARSER
# ================================
def to_mysql_dt(iso_str):
if not iso_str:
return None
try:
- dt = parser.isoparse(iso_str) # ISO8601 → aware datetime (UTC)
- dt = dt.astimezone() # převede na lokální čas (CET/CEST)
+ dt = parser.isoparse(iso_str)
+ dt = dt.astimezone()
return dt.strftime("%Y-%m-%d %H:%M:%S")
except:
return None
+
# ================================
-# UPSERT WITH MERGED UPDATED TIME
+# UPSERT
# ================================
def upsert(conn, r):
p = r.get("extendedPatient") or {}
- # API pole
api_updated = to_mysql_dt(r.get("updatedAt"))
-
- # poslední zpráva
last_msg = r.get("lastMessage") or {}
msg_at = to_mysql_dt(last_msg.get("createdAt"))
- # vybereme novější čas
def max_dt(a, b):
if a and b:
return max(a, b)
@@ -137,6 +163,7 @@ def upsert(conn, r):
conn.commit()
+
# ================================
# FETCH LAST 300 DONE REQUESTS
# ================================
@@ -162,6 +189,7 @@ def fetch_done(headers):
data = r.json()["data"]["requestsResponse"]
return data.get("patientRequests", [])
+
# ================================
# MAIN
# ================================
@@ -175,17 +203,18 @@ def main():
conn = pymysql.connect(**DB_CONFIG)
- print(f"\n=== Downloading last {LIMIT} DONE requests @ {datetime.now():%Y-%m-%d %H:%M:%S} ===")
+ safe_print(f"\n=== Downloading last {LIMIT} DONE requests @ {datetime.now():%Y-%m-%d %H:%M:%S} ===")
requests_list = fetch_done(headers)
- print(f"📌 Requests returned: {len(requests_list)}")
+ safe_print(f"📌 Requests returned: {len(requests_list)}")
for r in requests_list:
upsert(conn, r)
conn.close()
- print("\n✅ DONE - latest closed requests synced.\n")
+ safe_print("\n\u2705 DONE - latest closed requests synced.\n")
+# ================================
if __name__ == "__main__":
main()
diff --git a/10ReadPozadavky/PRAVIDELNE_2_ReadPoznamky.py b/10ReadPozadavky/PRAVIDELNE_2_ReadPoznamky.py
index b742f2f..db18fe9 100644
--- a/10ReadPozadavky/PRAVIDELNE_2_ReadPoznamky.py
+++ b/10ReadPozadavky/PRAVIDELNE_2_ReadPoznamky.py
@@ -12,6 +12,35 @@ import pymysql
from datetime import datetime
from pathlib import Path
import time
+import sys
+
+# Force UTF-8 output even under Windows Task Scheduler
+import sys
+try:
+ sys.stdout.reconfigure(encoding='utf-8')
+ sys.stderr.reconfigure(encoding='utf-8')
+except AttributeError:
+ # Python < 3.7 fallback (not needed for you, but safe)
+ import io
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
+ sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
+
+
+# ==============================
+# 🛡 SAFE PRINT FOR CP1250 / EMOJI
+# ==============================
+def safe_print(text: str):
+ enc = sys.stdout.encoding or ""
+ if not enc.lower().startswith("utf"):
+ # strip emoji + anything above BMP
+ text = ''.join(ch for ch in text if ord(ch) < 65536)
+ try:
+ print(text)
+ except UnicodeEncodeError:
+ # final ASCII fallback
+ text = ''.join(ch for ch in text if ord(ch) < 128)
+ print(text)
+
# ==============================
# 🔧 CONFIGURATION
@@ -31,29 +60,30 @@ DB_CONFIG = {
}
-from datetime import datetime
-
+# ==============================
+# 🕒 DATETIME FIXER
+# ==============================
def fix_datetime(dt_str):
"""Convert ISO 8601 string with 'Z' or ms into MySQL DATETIME format."""
if not dt_str:
return None
try:
- # Remove trailing Z and parse flexible ISO format
return datetime.fromisoformat(dt_str.replace("Z", "").replace("+00:00", ""))
except Exception:
return None
-# ✅ Optional: limit which requests to process
-CREATED_AFTER = "2025-01-01" # set "" to disable
+
+# Optional filter
+CREATED_AFTER = "2025-01-01"
+
# ==============================
# 🧮 HELPERS
# ==============================
def read_token(p: Path) -> str:
- """Read Bearer token from file."""
tok = p.read_text(encoding="utf-8").strip()
if tok.startswith("Bearer "):
- tok = tok.split(" ", 1)[1]
+ return tok.split(" ", 1)[1]
return tok
@@ -101,7 +131,7 @@ def fetch_questionnaire(headers, request_id, clinic_slug):
}
r = requests.post(GRAPHQL_URL, json=payload, headers=headers, timeout=40)
if r.status_code != 200:
- print(f"❌ HTTP {r.status_code} for {request_id}: {r.text}")
+ safe_print(f"❌ HTTP {r.status_code} for {request_id}: {r.text}")
return None
return r.json().get("data", {}).get("request")
@@ -118,23 +148,24 @@ def insert_questionnaire(cur, req):
updated_at = fix_datetime(req.get("updatedAt"))
cur.execute("""
-INSERT INTO medevio_questionnaires (
- request_id, created_at, updated_at, user_note, ecrf_json
-)
-VALUES (%s,%s,%s,%s,%s)
+ INSERT INTO medevio_questionnaires (
+ request_id, created_at, updated_at, user_note, ecrf_json
+ )
+ VALUES (%s,%s,%s,%s,%s)
ON DUPLICATE KEY UPDATE
updated_at = VALUES(updated_at),
user_note = VALUES(user_note),
ecrf_json = VALUES(ecrf_json),
updated_local = NOW()
""", (
- req.get("id"),
- created_at,
- updated_at,
- req.get("userNote"),
- json.dumps(ecrf_data, ensure_ascii=False),
-))
- print(f" 💾 Stored questionnaire for {patient.get('surname','')} {patient.get('name','')}")
+ req.get("id"),
+ created_at,
+ updated_at,
+ req.get("userNote"),
+ json.dumps(ecrf_data, ensure_ascii=False),
+ ))
+
+ safe_print(f" 💾 Stored questionnaire for {patient.get('surname','')} {patient.get('name','')}")
# ==============================
@@ -149,6 +180,8 @@ def main():
}
conn = pymysql.connect(**DB_CONFIG)
+
+ # load list of requests
with conn.cursor() as cur:
sql = """
SELECT id, pacient_jmeno, pacient_prijmeni, createdAt, updatedAt, questionnaireprocessed
@@ -163,26 +196,30 @@ def main():
rows = cur.fetchall()
- print(f"📋 Found {len(rows)} requests needing questionnaire check.")
+ safe_print(f"📋 Found {len(rows)} requests needing questionnaire check.")
+ # process each one
for i, row in enumerate(rows, 1):
req_id = row["id"]
- print(f"\n[{i}/{len(rows)}] 🔍 Fetching questionnaire for {req_id} ...")
+ safe_print(f"\n[{i}/{len(rows)}] 🔍 Fetching questionnaire for {req_id} ...")
req = fetch_questionnaire(headers, req_id, CLINIC_SLUG)
if not req:
- print(" ⚠️ No questionnaire data found.")
+ safe_print(" ⚠️ No questionnaire data found.")
continue
with conn.cursor() as cur:
insert_questionnaire(cur, req)
- cur.execute("UPDATE pozadavky SET questionnaireprocessed = NOW() WHERE id = %s", (req_id,))
+ cur.execute(
+ "UPDATE pozadavky SET questionnaireprocessed = NOW() WHERE id = %s",
+ (req_id,)
+ )
conn.commit()
- time.sleep(0.6) # polite pacing
+ time.sleep(0.6)
conn.close()
- print("\n✅ Done! All questionnaires stored in MySQL table `medevio_questionnaires`.")
+ safe_print("\n✅ Done! All questionnaires stored in MySQL table `medevio_questionnaires`.")
# ==============================
diff --git a/10ReadPozadavky/PRAVIDELNE_3_StahniKomunikaci.py b/10ReadPozadavky/PRAVIDELNE_3_StahniKomunikaci.py
index 2b05def..daceb2a 100644
--- a/10ReadPozadavky/PRAVIDELNE_3_StahniKomunikaci.py
+++ b/10ReadPozadavky/PRAVIDELNE_3_StahniKomunikaci.py
@@ -15,6 +15,34 @@ import pymysql
from pathlib import Path
from datetime import datetime
import time
+import sys
+
+# Force UTF-8 output even under Windows Task Scheduler
+import sys
+try:
+ sys.stdout.reconfigure(encoding='utf-8')
+ sys.stderr.reconfigure(encoding='utf-8')
+except AttributeError:
+ # Python < 3.7 fallback (not needed for you, but safe)
+ import io
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
+ sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
+
+# ==============================
+# 🛡 SAFE PRINT FOR CP1250 / EMOJI
+# ==============================
+def safe_print(text: str):
+ enc = sys.stdout.encoding or ""
+ if not enc or not enc.lower().startswith("utf"):
+ # strip emoji + characters outside BMP for Task Scheduler (CP1250)
+ text = ''.join(ch for ch in text if ord(ch) < 65536)
+ try:
+ print(text)
+ except UnicodeEncodeError:
+ # fallback pure ASCII
+ text = ''.join(ch for ch in text if ord(ch) < 128)
+ print(text)
+
# ==============================
# 🔧 CONFIGURATION
@@ -94,7 +122,7 @@ def fetch_messages(headers, request_id):
r = requests.post("https://api.medevio.cz/graphql", json=payload, headers=headers, timeout=30)
if r.status_code != 200:
- print("❌ HTTP", r.status_code, "for request", request_id)
+ safe_print(f"❌ HTTP {r.status_code} for request {request_id}")
return []
return r.json().get("data", {}).get("messages", []) or []
@@ -158,7 +186,7 @@ def insert_download(cur, req_id, msg, existing_ids):
return
if attachment_id in existing_ids:
- return # skip duplicates
+ return
url = mr.get("downloadUrl") or mr.get("url")
if not url:
@@ -169,7 +197,7 @@ def insert_download(cur, req_id, msg, existing_ids):
r.raise_for_status()
data = r.content
except Exception as e:
- print("⚠️ Failed to download:", e)
+ safe_print(f"⚠️ Failed to download: {e}")
return
filename = url.split("/")[-1].split("?")[0]
@@ -216,7 +244,7 @@ def main():
cur.execute("SELECT attachment_id FROM medevio_downloads")
existing_ids = {row["attachment_id"] for row in cur.fetchall()}
- print(f"📦 Already downloaded attachments: {len(existing_ids)}\n")
+ safe_print(f"📦 Already downloaded attachments: {len(existing_ids)}\n")
# ---- Select pozadavky needing message sync
sql = """
@@ -229,12 +257,12 @@ def main():
cur.execute(sql)
requests_to_process = cur.fetchall()
- print(f"📋 Found {len(requests_to_process)} pozadavků requiring message sync.\n")
+ safe_print(f"📋 Found {len(requests_to_process)} pozadavků requiring message sync.\n")
- # ---- Process each pozadavek
+ # ---- Process each record
for idx, row in enumerate(requests_to_process, 1):
req_id = row["id"]
- print(f"[{idx}/{len(requests_to_process)}] Processing {req_id} …")
+ safe_print(f"[{idx}/{len(requests_to_process)}] Processing {req_id} …")
messages = fetch_messages(headers, req_id)
@@ -248,11 +276,11 @@ def main():
cur.execute("UPDATE pozadavky SET messagesProcessed = NOW() WHERE id = %s", (req_id,))
conn.commit()
- print(f" ✅ {len(messages)} messages saved\n")
+ safe_print(f" ✅ {len(messages)} messages saved\n")
time.sleep(0.25)
conn.close()
- print("🎉 Done!")
+ safe_print("🎉 Done!")
if __name__ == "__main__":
diff --git a/10ReadPozadavky/PRAVIDELNE_4_StahniPrilohyUlozDoMySQL.py b/10ReadPozadavky/PRAVIDELNE_4_StahniPrilohyUlozDoMySQL.py
index 1a7d578..22f5275 100644
--- a/10ReadPozadavky/PRAVIDELNE_4_StahniPrilohyUlozDoMySQL.py
+++ b/10ReadPozadavky/PRAVIDELNE_4_StahniPrilohyUlozDoMySQL.py
@@ -14,6 +14,36 @@ import pymysql
from pathlib import Path
from datetime import datetime
import time
+import sys
+
+# Force UTF-8 output even under Windows Task Scheduler
+import sys
+try:
+ sys.stdout.reconfigure(encoding='utf-8')
+ sys.stderr.reconfigure(encoding='utf-8')
+except AttributeError:
+ # Python < 3.7 fallback (not needed for you, but safe)
+ import io
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
+ sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
+
+
+# ==============================
+# 🛡 SAFE PRINT FOR CP1250 / EMOJI
+# ==============================
+def safe_print(text: str):
+ enc = sys.stdout.encoding or ""
+ if not enc or not enc.lower().startswith("utf"):
+ # strip emoji + characters outside BMP
+ text = ''.join(ch for ch in text if ord(ch) < 65536)
+
+ try:
+ print(text)
+ except UnicodeEncodeError:
+ # ASCII fallback
+ text = ''.join(ch for ch in text if ord(ch) < 128)
+ print(text)
+
# ==============================
# 🔧 CONFIGURATION
@@ -67,6 +97,7 @@ 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
+
# ==============================
# 📡 FETCH ATTACHMENTS
# ==============================
@@ -78,42 +109,40 @@ def fetch_attachments(headers, request_id):
}
r = requests.post("https://api.medevio.cz/graphql", json=payload, headers=headers, timeout=30)
if r.status_code != 200:
- print(f"❌ HTTP {r.status_code} for request {request_id}")
+ safe_print(f"❌ HTTP {r.status_code} for request {request_id}")
return []
return r.json().get("data", {}).get("patientRequestMedicalRecords", [])
# ==============================
-# 💾 SAVE TO MYSQL (clean version)
+# 💾 SAVE TO MYSQL
# ==============================
def insert_download(cur, req_id, a, m, created_date, existing_ids):
attachment_id = a.get("id")
if attachment_id in existing_ids:
- print(f" ⏭️ Already downloaded {attachment_id}")
+ safe_print(f" ⏭️ Already downloaded {attachment_id}")
return False
url = m.get("downloadUrl")
if not url:
- print(" ⚠️ Missing download URL")
+ safe_print(" ⚠️ Missing download URL")
return False
filename = extract_filename_from_url(url)
- # Download file
try:
r = requests.get(url, timeout=30)
r.raise_for_status()
content = r.content
except Exception as e:
- print(f" ⚠️ Download failed {url}: {e}")
+ safe_print(f" ⚠️ Download failed {url}: {e}")
return False
file_size = len(content)
attachment_type = a.get("attachmentType")
content_type = m.get("contentType")
- # 🚨 CLEAN INSERT — no patient_jmeno/no patient_prijmeni
cur.execute("""
INSERT INTO medevio_downloads (
request_id, attachment_id, attachment_type,
@@ -136,7 +165,7 @@ def insert_download(cur, req_id, a, m, created_date, existing_ids):
))
existing_ids.add(attachment_id)
- print(f" 💾 Saved {filename} ({file_size/1024:.1f} kB)")
+ safe_print(f" 💾 Saved {filename} ({file_size/1024:.1f} kB)")
return True
@@ -152,11 +181,12 @@ def main():
conn = pymysql.connect(**DB_CONFIG)
- # Load existing IDs
+ # Load existing attachments
with conn.cursor() as cur:
cur.execute("SELECT attachment_id FROM medevio_downloads")
existing_ids = {row["attachment_id"] for row in cur.fetchall()}
- print(f"✅ {len(existing_ids)} attachments already saved.")
+
+ safe_print(f"✅ {len(existing_ids)} attachments already saved.")
# Build query for pozadavky
sql = """
@@ -173,7 +203,7 @@ def main():
cur.execute(sql, params)
req_rows = cur.fetchall()
- print(f"📋 Found {len(req_rows)} pozadavky to process.")
+ safe_print(f"📋 Found {len(req_rows)} pozadavky to process.")
# Process each pozadavek
for i, row in enumerate(req_rows, 1):
@@ -182,12 +212,12 @@ def main():
jmeno = row.get("pacient_jmeno") or ""
created_date = row.get("createdAt") or datetime.now()
- print(f"\n[{i}/{len(req_rows)}] 🧾 {prijmeni}, {jmeno} ({req_id})")
+ safe_print(f"\n[{i}/{len(req_rows)}] 🧾 {prijmeni}, {jmeno} ({req_id})")
attachments = fetch_attachments(headers, req_id)
if not attachments:
- print(" ⚠️ No attachments found")
+ safe_print(" ⚠️ No attachments found")
with conn.cursor() as cur:
cur.execute("UPDATE pozadavky SET attachmentsProcessed = NOW() WHERE id = %s", (req_id,))
conn.commit()
@@ -199,17 +229,16 @@ def main():
insert_download(cur, req_id, a, m, created_date, existing_ids)
conn.commit()
- # Mark processed
with conn.cursor() as cur:
cur.execute("UPDATE pozadavky SET attachmentsProcessed = NOW() WHERE id = %s", (req_id,))
conn.commit()
- print(f" ✅ Done ({len(attachments)} attachments)")
-
+ safe_print(f" ✅ Done ({len(attachments)} attachments)")
time.sleep(0.3)
conn.close()
- print("\n🎯 All attachments processed.")
+ safe_print("\n🎯 All attachments processed.")
+
# ==============================
if __name__ == "__main__":
diff --git a/10ReadPozadavky/PRAVIDELNE_5_SaveToFileSystem incremental.py b/10ReadPozadavky/PRAVIDELNE_5_SaveToFileSystem incremental.py
index 6d907c4..2492756 100644
--- a/10ReadPozadavky/PRAVIDELNE_5_SaveToFileSystem incremental.py
+++ b/10ReadPozadavky/PRAVIDELNE_5_SaveToFileSystem incremental.py
@@ -10,6 +10,17 @@ from datetime import datetime
import time
import sys
+# Force UTF-8 output even under Windows Task Scheduler
+import sys
+try:
+ sys.stdout.reconfigure(encoding='utf-8')
+ sys.stderr.reconfigure(encoding='utf-8')
+except AttributeError:
+ # Python < 3.7 fallback (not needed for you, but safe)
+ import io
+ sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
+ sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
+
# ==============================
# 🛡 SAFE PRINT FOR CP1250 / EMOJI
# ==============================
@@ -92,17 +103,16 @@ safe_print("🔍 Loading metadata from DB (FAST)…")
cur_meta.execute("""
SELECT d.id AS download_id,
- d.request_id,
- d.filename,
- d.created_at,
- p.updatedAt AS req_updated_at,
- p.pacient_jmeno AS jmeno,
- p.pacient_prijmeni AS prijmeni,
- p.displayTitle
-FROM medevio_downloads d
-JOIN pozadavky p ON d.request_id = p.id
-WHERE d.downloaded_at IS NULL
-ORDER BY p.updatedAt DESC
+ d.request_id,
+ d.filename,
+ d.created_at,
+ p.updatedAt AS req_updated_at,
+ p.pacient_jmeno AS jmeno,
+ p.pacient_prijmeni AS prijmeni,
+ p.displayTitle
+ FROM medevio_downloads d
+ JOIN pozadavky p ON d.request_id = p.id
+ ORDER BY p.updatedAt DESC
""")
rows = cur_meta.fetchall()
diff --git a/10ReadPozadavky/PRAVIDELNE_PLNYSCRIPT.py b/10ReadPozadavky/PRAVIDELNE_PLNYSCRIPT.py
index 69063e7..17721b2 100644
--- a/10ReadPozadavky/PRAVIDELNE_PLNYSCRIPT.py
+++ b/10ReadPozadavky/PRAVIDELNE_PLNYSCRIPT.py
@@ -15,7 +15,7 @@ Spustí všechny PRAVIDELNÉ skripty v daném pořadí:
import time, socket
for _ in range(30):
try:
- socket.create_connection(("127.0.0.1", 3307), timeout=3).close()
+ socket.create_connection(("192.168.1.76", 3307), timeout=3).close()
break
except OSError:
time.sleep(10)
diff --git a/10ReadPozadavky/test.py b/10ReadPozadavky/test.py
new file mode 100644
index 0000000..60efc51
--- /dev/null
+++ b/10ReadPozadavky/test.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+"""
+Orchestrator for all PRAVIDELNE scripts in exact order.
+"""
+
+import time, socket
+for _ in range(30):
+ try:
+ socket.create_connection(("192.168.1.76", 3307), timeout=3).close()
+ break
+ except OSError:
+ time.sleep(10)
+
+import sys
+import subprocess
+from pathlib import Path
+from datetime import datetime
+
+# =====================================================================
+# Import EXACT Functions.py from: C:\Reporting\Fio\Functions.py
+# This bypasses all other Functions.py files in the system.
+# =====================================================================
+
+import importlib.util
+
+FUNCTIONS_FILE = Path(r"C:\Reporting\Fio\Functions.py")
+
+spec = importlib.util.spec_from_file_location("Functions_FIO", FUNCTIONS_FILE)
+Functions_FIO = importlib.util.module_from_spec(spec)
+sys.modules["Functions_FIO"] = Functions_FIO
+spec.loader.exec_module(Functions_FIO)
+
+# correct WhatsApp function
+SendWhatsAppMessage = Functions_FIO.SendWhatsAppMessage
+
+
+# =====================================================================
+# General Orchestrator Settings
+# =====================================================================
+
+# folder where orchestrator + sub-scripts live
+BASE_DIR = Path(__file__).resolve().parent
+
+SCRIPTS_IN_ORDER = [
+ "PRAVIDELNE_0_READ_ALL_ACTIVE_POZADAVKY.py",
+ "PRAVIDELNE_1_ReadLast300DonePozadavku.py",
+ "PRAVIDELNE_2_ReadPoznamky.py",
+ "PRAVIDELNE_3_StahniKomunikaci.py",
+ "PRAVIDELNE_4_StahniPrilohyUlozDoMySQL.py",
+ "PRAVIDELNE_5_SaveToFileSystem incremental.py",
+]
+
+LOG_FILE = BASE_DIR / "PRAVIDELNE_log.txt"
+
+
+# =====================================================================
+# Logging + WhatsApp wrappers
+# =====================================================================
+
+def log(msg: str):
+ ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+ line = f"[{ts}] {msg}"
+ print(line)
+ try:
+ with LOG_FILE.open("a", encoding="utf-8") as f:
+ f.write(line + "\n")
+ except:
+ pass
+
+
+def whatsapp_notify(text: str):
+ """WhatsApp message wrapper — never allowed to crash orchestrator"""
+ try:
+ SendWhatsAppMessage(text)
+ except:
+ pass
+
+
+# =====================================================================
+# Main orchestrator
+# =====================================================================
+
+def main():
+ log("=== START pravidelného běhu ===")
+ whatsapp_notify("🏁 *PRAVIDELNÉ skripty: START*")
+
+ for script_name in SCRIPTS_IN_ORDER:
+ script_path = BASE_DIR / script_name
+
+ if not script_path.exists():
+ err = f"❌ Skript nenalezen: {script_path}"
+ log(err)
+ whatsapp_notify(err)
+ continue
+
+ log(f"▶ Spouštím: {script_path.name}")
+ whatsapp_notify(f"▶ *Spouštím:* {script_path.name}")
+
+ try:
+ result = subprocess.run(
+ [sys.executable, str(script_path)],
+ cwd=str(BASE_DIR),
+ capture_output=True,
+ text=True,
+ encoding="utf-8",
+ errors="ignore",
+ )
+ except Exception as e:
+ err = f"💥 Chyba při spouštění {script_path.name}: {e}"
+ log(err)
+ whatsapp_notify(err)
+ continue
+
+ # return code
+ rc_msg = f"↳ {script_path.name} return code: {result.returncode}"
+ log(rc_msg)
+ whatsapp_notify(rc_msg)
+
+ # stderr (warnings/errors)
+ if result.stderr:
+ err_msg = f"⚠ stderr v {script_path.name}:\n{result.stderr.strip()}"
+ log(err_msg)
+ whatsapp_notify(err_msg)
+
+ log("=== KONEC pravidelného běhu ===")
+ whatsapp_notify("✅ *PRAVIDELNÉ skripty: KONEC*\n")
+
+
+# =====================================================================
+# Entry point
+# =====================================================================
+
+if __name__ == "__main__":
+ main()