notebookvb
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
"""export_prilohy.py – export příloh z Medicus FILES tabulky do souborů
|
||||
|
||||
Extrahuje všechny záznamy z FILES, uloží BODY blob jako soubor.
|
||||
Detekuje dva formáty BODY:
|
||||
- inline PDF (začíná %PDF)
|
||||
- reference (začíná magic \xee\xbb\xaa\x0b) → čte z externí MEDICUS_FILES_YYYYMM.fdb
|
||||
"""
|
||||
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, r'U:\OrdinaceProjekt')
|
||||
from Knihovny.najdi_dropbox import get_dropbox_root
|
||||
from Knihovny.medicus_db import get_medicus_connection
|
||||
|
||||
# ─── Konfigurace ─────────────────────────────────────────────────────────────
|
||||
|
||||
OUTPUT_DIR = os.path.join(get_dropbox_root(), r'!!!Days\Downloads Z230\Files')
|
||||
RECORDS_COUNT = 0 # 0 = všechny záznamy
|
||||
|
||||
# Magic bytes identifikující referenci na externí FDB (na reporterovi nenastane)
|
||||
MAGIC = b'\xee\xbb\xaa\x0b'
|
||||
|
||||
# ─── Pomocné funkce ───────────────────────────────────────────────────────────
|
||||
|
||||
def parse_body_ref(body_bytes):
|
||||
"""Vrátí (uid, dbname) pokud BODY je reference na ext FDB, jinak None."""
|
||||
if not body_bytes or len(body_bytes) < 8:
|
||||
return None
|
||||
if body_bytes[:4] != MAGIC:
|
||||
return None
|
||||
uid = body_bytes[4:36].decode('ascii')
|
||||
dblen = struct.unpack_from('<I', body_bytes, 36)[0]
|
||||
dbname = body_bytes[40:40 + dblen].decode('ascii')
|
||||
return uid, dbname
|
||||
|
||||
|
||||
def safe_filename(name):
|
||||
"""Odstraní znaky nevhodné pro název souboru."""
|
||||
for ch in r'\/:*?"<>|':
|
||||
name = name.replace(ch, '_')
|
||||
return name.strip()
|
||||
|
||||
|
||||
# ─── Hlavní logika ────────────────────────────────────────────────────────────
|
||||
|
||||
def main():
|
||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||
|
||||
conn = get_medicus_connection()
|
||||
cur = conn.cursor()
|
||||
limit = f"FIRST {RECORDS_COUNT} " if RECORDS_COUNT > 0 else ""
|
||||
cur.execute(f"""
|
||||
SELECT {limit}f.ID, f.IDPAC, f.DATUM, f.FILENAME, f.BODY, f.POZNAMKA
|
||||
FROM FILES f
|
||||
ORDER BY f.ID
|
||||
""")
|
||||
|
||||
ok = 0
|
||||
chyb = 0
|
||||
|
||||
for row in cur:
|
||||
file_id, idpac, datum, filename, body_blob, poznamka = row
|
||||
|
||||
# Přečti blob
|
||||
try:
|
||||
if hasattr(body_blob, 'read'):
|
||||
body_bytes = body_blob.read()
|
||||
body_blob.close()
|
||||
else:
|
||||
body_bytes = body_blob or b''
|
||||
except Exception as e:
|
||||
print(f" [CHYBA] ID={file_id}: čtení BODY selhalo: {e}")
|
||||
chyb += 1
|
||||
continue
|
||||
|
||||
# Zjisti formát
|
||||
ref = parse_body_ref(body_bytes)
|
||||
if ref:
|
||||
_, dbname = ref
|
||||
print(f" [SKIP] ID={file_id}: reference na ext DB {dbname} — nepodporováno")
|
||||
chyb += 1
|
||||
continue
|
||||
pdf_data = body_bytes
|
||||
|
||||
# Sestavení cílového názvu: ID_IDPAC_DATUM_filename
|
||||
datum_str = datum.strftime('%Y-%m-%d') if datum else 'bez-data'
|
||||
raw_fn = filename or f'soubor_{file_id}.bin'
|
||||
out_name = f"{file_id:06d}_{idpac:06d}_{datum_str}_{safe_filename(raw_fn)}"
|
||||
out_path = os.path.join(OUTPUT_DIR, out_name)
|
||||
|
||||
# Ulož
|
||||
with open(out_path, 'wb') as f:
|
||||
f.write(pdf_data)
|
||||
|
||||
print(f" ID={file_id} idpac={idpac} {datum_str} {raw_fn} → {len(pdf_data):,} B")
|
||||
ok += 1
|
||||
|
||||
conn.close()
|
||||
print(f"\nHotovo: {ok} uloženo, {chyb} chyb")
|
||||
print(f"Výstup: {OUTPUT_DIR}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user