Files
medicus/MedicusWithClaude/test_import_single.py
2026-03-18 07:13:47 +01:00

239 lines
9.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""test_import_single.py vloží 1 soubor do dekurzu s rozšířenou logikou:
1. Poslední dekurs pacienta je z dnešního dne A má sekci 'Vložené přílohy'
→ soubor se přidá DO té sekce (ne nová sekce)
2. Poslední dekurs je z dnešního dne, ale sekci 'Vložené přílohy' nemá
→ prepend nové sekce na začátek
3. Poslední dekurs je z jiného dne / neexistuje
→ nový dekurs pro dnešek
Spustit na Windows.
"""
import datetime, os, re, fdb
import funkce, funkce_ext
CESTA = r'u:\\'
IDPAC = 9742
DATUM = datetime.date(2026, 3, 18)
SOUBORY = [
{'souborname': '7309208104 2026-03-18 Buzalka, Vladimír [vyšetření] [ahoj Claude - zařazení].pdf',
'prvnizavorka': 'vyšetření',
'druhazavorka': 'ahoj Claude - zařazení',
'datum': DATUM},
]
# Vzor pro detekci sekce Vložené přílohy (RTF kódování win1250)
PRILOHY_HEADER = r"Vlo\'9een\'e9 p\'f8\'edlohy:"
PRILOHY_CLOSING = r'\pard\s10\plain\cs15\f0\fs20 \par'
# ─────────────────────────────────────────────────────────────────────────────
def najdi_posledni_dekurs_dnes(conn, idpac, datum_vlozeni):
"""Vrátí (id, rtf) posledního dekurzu pacienta pokud je z dnešního dne."""
cur = conn.cursor()
cur.execute("""
SELECT FIRST 1 ID, DATUM, DEKURS FROM DEKURS
WHERE IDPAC = ?
ORDER BY ID DESC
""", (idpac,))
row = cur.fetchone()
if row is None:
return None
dekurs_id, dekurs_datum, dekurs_rtf = row
print(f" Poslední dekurs: ID={dekurs_id}, datum={dekurs_datum}")
if dekurs_datum == datum_vlozeni:
print(f" → dnešní den ({datum_vlozeni}) ✓")
return (dekurs_id, dekurs_rtf)
else:
print(f" → jiný den ({dekurs_datum}{datum_vlozeni}), vytvoříme nový")
return None
def ma_sekci_prilohy(rtf):
return PRILOHY_HEADER in rtf
def pridat_do_sekce_prilohy(rtf, new_bkm_entry, filenameforbookmark):
"""Přidá soubor do EXISTUJÍCÍ sekce 'Vložené přílohy'.
Postup:
1. Spočítá počet Files: odkazů = N → nový index = N
2. Posune bkmkstart/bkmkend >= N o +1 (uvolní místo pro nový)
3. Vloží nový \pard před uzavírací prázdný řádek sekce
4. Vloží bookmark na pozici N do {\info{\bookmarks ...}}
"""
# 1. Počet existujících Files: odkazů v bookmarks listu
bkm_match = re.search(r'\{\\info\{\\bookmarks ([^}]*)\}\}', rtf)
if bkm_match:
bkm_entries = [e for e in bkm_match.group(1).split(';') if e.strip()]
n_files = sum(1 for e in bkm_entries if '"Files:' in e)
else:
bkm_entries = []
n_files = 0
new_idx = n_files
print(f" Počet existujících Files odkazů: {n_files} → nový bkmkstart={new_idx}")
# 2. Posunout bkmkstart/bkmkend >= n_files o +1
rtf = re.sub(r'\\bkmkstart (\d+)',
lambda m: '\\bkmkstart ' + (
str(int(m.group(1)) + 1) if int(m.group(1)) >= n_files
else m.group(1)),
rtf)
rtf = re.sub(r'\\bkmkend (\d+)',
lambda m: '\\bkmkend ' + (
str(int(m.group(1)) + 1) if int(m.group(1)) >= n_files
else m.group(1)),
rtf)
# 3. Najít uzavírající prázdný řádek sekce (první výskyt po hlavičce)
prilohy_pos = rtf.find(PRILOHY_HEADER)
closing_pos = rtf.find(PRILOHY_CLOSING, prilohy_pos)
if closing_pos == -1:
raise RuntimeError("Nenalezen uzavírací řádek sekce Vložené přílohy!")
new_pard = (r'\pard\s10{\*\bkmkstart ' + str(new_idx) + r'}'
r'\plain\cs32\f0\ul\fs20\cf1 ' + filenameforbookmark
+ r'{\*\bkmkend ' + str(new_idx) + r'}\par')
rtf = rtf[:closing_pos] + new_pard + '\n' + rtf[closing_pos:]
# 4. Vložit bookmark na pozici n_files do {\info{\bookmarks}}
def insert_bookmark(m):
entries = [e for e in m.group(1).split(';') if e.strip()]
entries.insert(n_files, new_bkm_entry)
return '{\\info{\\bookmarks ' + ';'.join(entries) + '}}'
rtf = re.sub(r'\{\\info\{\\bookmarks ([^}]*)\}\}', insert_bookmark, rtf)
return rtf
def merge_rtf_prepend(existing_rtf, new_bkm_list, new_body_pards, n_new):
"""Vloží nový obsah na ZAČÁTEK stávajícího dekurzu (žádná existující sekce)."""
rtf = existing_rtf
rtf = re.sub(r'\\bkmkstart (\d+)',
lambda m: '\\bkmkstart ' + str(int(m.group(1)) + n_new), rtf)
rtf = re.sub(r'\\bkmkend (\d+)',
lambda m: '\\bkmkend ' + str(int(m.group(1)) + n_new), rtf)
new_bkm_str = ';'.join(new_bkm_list)
def merge_bkm(m):
existing = m.group(1).strip()
combined = new_bkm_str + (';' + existing if existing else '')
return '{\\info{\\bookmarks ' + combined + '}}'
if re.search(r'\{\\info\{\\bookmarks', rtf):
rtf = re.sub(r'\{\\info\{\\bookmarks ([^}]*)\}\}', merge_bkm, rtf)
else:
rtf = re.sub(r'(\\deflang\d+)',
r'\1{\\info{\\bookmarks ' + new_bkm_str + '}}', rtf, count=1)
match = re.search(r'\\uc1\\pard', rtf)
if match:
pos = match.start()
rtf = rtf[:pos] + new_body_pards + '\n' + rtf[pos:]
return rtf
# ─────────────────────────────────────────────────────────────────────────────
conn = fdb.connect(dsn=r'localhost:c:\medicus 3\data\medicus.fdb',
user='SYSDBA', password='masterkey', charset='WIN1250')
# ── Krok 1: vložit soubory do ext DB ─────────────────────────────────────────
bookmark_list = []
bookmarks_body = ''
cislo = 9
poradi = 0
for s in SOUBORY:
cesta_souboru = os.path.join(CESTA, s['souborname'])
datumsouboru = datetime.datetime.fromtimestamp(os.path.getmtime(cesta_souboru))
print(f"\n>>> Zpracovávám: {s['souborname']}")
fileid = funkce_ext.zapis_file_ext(
vstupconnection=conn, idpac=IDPAC,
cesta=CESTA, souborname=s['souborname'],
prvnizavorka=s['prvnizavorka'],
soubordate=s['datum'], souborfiledate=datumsouboru,
poznamka=s['druhazavorka'],
)
print(f" → FILES.ID = {fileid}")
filenameforbookmark = (s['datum'].strftime('%Y-%m-%d') + ' '
+ s['prvnizavorka'] + ': ' + s['druhazavorka'])
bookmark_list.append('"' + filenameforbookmark + '","Files:' + str(fileid) + '",' + str(cislo))
cislo += 7
bookmarks_body += (r'\pard\s10{\*\bkmkstart ' + str(poradi) + r'}'
r'\plain\cs32\f0\ul\fs20\cf1 ' + filenameforbookmark
+ r'{\*\bkmkend ' + str(poradi) + r'}\par')
poradi += 1
new_body = (r'\uc1\pard\s10\plain\cs20\f0\i\fs20 Vlo\'9een\'e9 p\'f8\'edlohy:\par' + '\n'
+ bookmarks_body + '\n'
+ r'\pard\s10\plain\cs15\f0\fs20 \par')
# ── Krok 2: rozhodovací logika ────────────────────────────────────────────────
print(f"\n>>> Hledám poslední dekurs pro IDPAC={IDPAC}...")
existujici = najdi_posledni_dekurs_dnes(conn, IDPAC, DATUM)
cur = conn.cursor()
now = datetime.datetime.now()
if existujici:
dekurs_id, existing_rtf = existujici
if ma_sekci_prilohy(existing_rtf):
# ── Případ 1: dnešní dekurs s existující sekcí → přidáme do ní ──────
print(f"\n>>> Sekce 'Vložené přílohy' nalezena v DEKURS ID={dekurs_id}")
print(">>> Přidávám soubor DO existující sekce...")
filenameforbookmark = (SOUBORY[0]['datum'].strftime('%Y-%m-%d') + ' '
+ SOUBORY[0]['prvnizavorka'] + ': ' + SOUBORY[0]['druhazavorka'])
merged_rtf = pridat_do_sekce_prilohy(
existing_rtf,
bookmark_list[0],
filenameforbookmark
)
else:
# ── Případ 2: dnešní dekurs bez sekce → prepend ───────────────────────
print(f"\n>>> DEKURS ID={dekurs_id} nemá sekci příloh → prepend nové sekce")
merged_rtf = merge_rtf_prepend(existing_rtf, bookmark_list, new_body, len(SOUBORY))
print("\n=== Výsledný RTF ===")
print(merged_rtf)
cur.execute("UPDATE DEKURS SET DEKURS = ? WHERE ID = ?", (merged_rtf, dekurs_id))
conn.commit()
print(f"\n>>> UPDATE DEKURS ID={dekurs_id} hotovo!")
else:
# ── Případ 3: žádný dnešní dekurs → nový ─────────────────────────────────
print(f"\n>>> Žádný dekurs pro {DATUM} → vytvářím nový...")
bookmark_str = ';'.join(bookmark_list)
rtf = r"""{\rtf1\ansi\ansicpg1250\uc1\deff0\deflang1029{\info{\bookmarks BOOKMARKNAMES}}{\fonttbl{\f0\fnil\fcharset238 Arial;}{\f5\fnil\fcharset238 Symbol;}}
{\colortbl ;\red0\green0\blue255;\red0\green128\blue0;\red0\green0\blue0;}
{\stylesheet{\s10\fi0\li0\ql\ri0\sb0\sa0 Vlevo;}{\*\cs15\f0\fs20 Norm\'e1ln\'ed;}{\*\cs20\f0\i\fs20 Z\'e1hlav\'ed;}{\*\cs32\f0\ul\fs20\cf1 Odkaz;}}
BOOKMARKSTEXT
\pard\s10\plain\cs15\f0\fs20 \par
}"""
rtf = rtf.replace('BOOKMARKNAMES', bookmark_str)
rtf = rtf.replace('BOOKMARKSTEXT', new_body)
print("\n=== Výsledný RTF ===")
print(rtf)
dekursid = funkce.get_dekurs_id(conn)
cur.execute(
"INSERT INTO DEKURS (id, iduzi, idprac, idodd, idpac, datum, cas, dekurs)"
" VALUES (?,?,?,?,?,?,?,?)",
(dekursid, 6, 2, 2, IDPAC, now.date(), now.time(), rtf)
)
conn.commit()
print(f"\n>>> Nový DEKURS ID={dekursid}")
conn.close()
print("\n=== HOTOVO ===")
print("Otevři Medicus → karta Buzalka → zkontroluj dekurs!")