Files
medicus/MedicusWithClaude/s03soubory.py
2026-03-20 18:03:44 +01:00

324 lines
13 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.
import os, shutil, fdb, time
import re, datetime, funkce, funkce_ext
# Connect to the Firebird database
conn = fdb.connect(
dsn=r'localhost:c:\medicus 3\data\medicus.fdb',
user='SYSDBA',
password="masterkey",
charset="win1250")
cesta = r"u:\NextcloudOrdinace\Dokumentace_ke_zpracování"
cestazpracovana = r"u:\NextcloudOrdinace\Dokumentace_zpracovaná"
# Konstanty 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'
# ─── Helper funkce ────────────────────────────────────────────────────────────
def restore_files_for_import(retezec):
drop = r"u:\Dropbox\!!!Days\Downloads Z230\Dokumentace"
next = r"u:\NextcloudOrdinace\Dokumentace_ke_zpracování"
if not os.path.exists(drop):
print(f"The directory '{drop}' does not exist.")
return
for item in os.listdir(drop):
item_path = os.path.join(drop, item)
if os.path.isfile(item_path) or os.path.islink(item_path):
os.unlink(item_path)
print(f"Deleted file: {item_path}")
elif os.path.isdir(item_path):
shutil.rmtree(item_path)
print(f"Deleted directory: {item_path}")
for item in os.listdir(next):
item_path = os.path.join(next, item)
if os.path.isfile(item_path) and item_path.endswith(".pdf") and retezec in item_path:
shutil.copy(item_path, os.path.join(drop, item))
print(f"Copied file: {item_path}")
def kontrola_rc(rc, connection):
cur = connection.cursor()
cur.execute("select count(*),idpac from kar where rodcis=? group by idpac", (rc,))
row = cur.fetchone()
if row:
return row[1]
else:
return False
def kontrola_struktury(souborname, connection):
if souborname.endswith('.pdf'):
pattern = re.compile(r'(^\d{9,10}) (\d{4}-\d{2}-\d{2}) (\w+, \w.+?) \[(.+?)\] \[(.*?)\]')
match = pattern.search(souborname)
vpohode = True
if match and len(match.groups()) == 5:
datum = match.group(2)
try:
datetime.datetime.strptime(datum, "%Y-%m-%d").date()
except:
vpohode = False
return vpohode
cur = connection.cursor()
cur.execute("select count(*) from kar where rodcis=?", (match.group(1),))
row = cur.fetchone()[0]
if row != 1:
vpohode = False
return vpohode
else:
vpohode = False
return vpohode
else:
vpohode = False
return vpohode
return vpohode
def vrat_info_o_souboru(souborname, connection):
pattern = re.compile(r'(^\d{9,10}) (\d{4}-\d{2}-\d{2}) (\w+, \w.+?) \[(.+?)\] \[(.*?)\]')
match = pattern.search(souborname)
rc = match.group(1)
datum = datetime.datetime.strptime(match.group(2), "%Y-%m-%d").date()
jmeno = match.group(3)
prvnizavorka = match.group(4)
druhazavorka = match.group(5)
cur = connection.cursor()
cur.execute("select idpac from kar where rodcis=?", (rc,))
idpac = cur.fetchone()[0]
datumsouboru = datetime.datetime.fromtimestamp(os.path.getctime(os.path.join(cesta, souborname)))
return (rc, idpac, datum, jmeno, prvnizavorka, druhazavorka, souborname, datumsouboru)
def prejmenuj_chybny_soubor(souborname, cesta):
if souborname[0] != "":
soubornovy = "" + souborname
os.rename(os.path.join(cesta, souborname), os.path.join(cesta, soubornovy))
def najdi_posledni_dekurs_dnes(conn, idpac, datum_vlozeni):
"""Vrátí (id, rtf) posledního dekurzu pacienta pokud je z dnešního dne, jinak None."""
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, bookmark_list, filenameforbookmark_list):
"""Přidá více souborů do EXISTUJÍCÍ sekce 'Vložené přílohy'.
Postup:
1. Spočítá počet Files: odkazů = N → nové indexy začínají od N
2. Vloží nové \\pard řádky před uzavírací prázdný řádek sekce
3. Přidá nové bookmarky na konec {\\info{\\bookmarks ...}}
"""
# 1. Počet existujících Files: odkazů
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:
n_files = 0
print(f" Počet existujících Files odkazů: {n_files}, přidávám {len(bookmark_list)} nových")
# 2. Vložit nové \pard řádky před PRILOHY_CLOSING
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_pards = ''
for i, fname in enumerate(filenameforbookmark_list):
idx = n_files + i
new_pards += (r'\pard\s10{\*\bkmkstart ' + str(idx) + r'}'
r'\plain\cs32\f0\ul\fs20\cf1 ' + fname
+ r'{\*\bkmkend ' + str(idx) + r'}\par' + '\n')
rtf = rtf[:closing_pos] + new_pards + rtf[closing_pos:]
# 3. Přidat nové bookmarky na konec {\info{\bookmarks ...}}
def append_bookmarks(m):
entries = [e for e in m.group(1).split(';') if e.strip()]
entries.extend(bookmark_list)
return '{\\info{\\bookmarks ' + ';'.join(entries) + '}}'
rtf = re.sub(r'\{\\info\{\\bookmarks ([^}]*)\}\}', append_bookmarks, rtf)
return rtf
def merge_rtf_prepend(existing_rtf, new_bkm_list, new_body_pards, n_new):
"""Vloží novou sekci příloh na ZAČÁTEK stávajícího dekurzu (sekce tam ještě není)."""
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
# Šablona RTF pro nový dekurs
RTF_TEMPLATE = 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
}"""
# ─── Hlavní tělo skriptu ──────────────────────────────────────────────────────
info = []
for soubor in os.listdir(cesta):
if os.path.isfile(os.path.join(cesta, soubor)):
print(soubor)
if kontrola_struktury(soubor, conn):
info.append(vrat_info_o_souboru(soubor, conn))
else:
prejmenuj_chybny_soubor(soubor, cesta)
info = sorted(info, key=lambda x: (x[0], x[1]))
print(info)
skupiny = {}
for row in info:
skupiny[row[0]] = []
for row in info:
skupiny[row[0]].append(row)
for key in skupiny.keys():
print(f"\n{'='*60}")
print(f"RC: {key}, souborů: {len(skupiny[key])}")
cislo = 9
poradi = 0
bookmark_list = []
filenameforbookmark_list = []
bookmarks_body = ''
idpac = skupiny[key][0][1]
# ── Krok 1: vložit každý soubor do ext DB + přesunout do zpracovaných ────
for row in skupiny[key]:
fileid = funkce_ext.zapis_file_ext(
vstupconnection=conn, idpac=row[1],
cesta=cesta, souborname=row[6], prvnizavorka=row[4],
soubordate=row[2], souborfiledate=row[7], poznamka=row[5])
print(f" → FILES.ID = {fileid} ({row[6]})")
# Přesun souboru do zpracovaných
for attempt in range(3):
try:
dest = os.path.join(cestazpracovana, row[6])
if not os.path.exists(dest):
shutil.move(os.path.join(cesta, row[6]), dest)
else:
ts = datetime.datetime.now().strftime("%Y-%m-%d %H-%M-%S")
shutil.move(os.path.join(cesta, row[6]),
os.path.join(cestazpracovana, row[6][:-4] + " " + ts + ".pdf"))
print(" Přesun OK!")
break
except Exception as e:
print(f" Attempt {attempt + 1} failed: {e}")
if attempt < 2:
print(" Retrying in 5 seconds...")
time.sleep(5)
else:
print(" Max retries reached. Command failed.")
filenameforbookmark = row[2].strftime('%Y-%m-%d') + ' ' + row[4] + ': ' + row[5]
bookmark_list.append('"' + filenameforbookmark + '","Files:' + str(fileid) + '",' + str(cislo))
filenameforbookmark_list.append(filenameforbookmark)
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
# ── Krok 2: sestavit tělo nové sekce příloh ───────────────────────────────
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 3: rozhodovací logika (3 případy) ────────────────────────────────
datumzapisu = datetime.datetime.now().date()
caszapisu = datetime.datetime.now().time()
cur = conn.cursor()
print(f"\n>>> Hledám poslední dekurs pro IDPAC={idpac}...")
existujici = najdi_posledni_dekurs_dnes(conn, idpac, datumzapisu)
if existujici:
dekurs_id, existing_rtf = existujici
if ma_sekci_prilohy(existing_rtf):
# Případ 1: dnešní dekurs má sekci příloh → přidáme soubory dovnitř
print(f"\n>>> Sekce 'Vložené přílohy' nalezena v DEKURS ID={dekurs_id}")
print(">>> Přidávám soubory DO existující sekce...")
merged_rtf = pridat_do_sekce_prilohy(existing_rtf, bookmark_list, filenameforbookmark_list)
else:
# Případ 2: dnešní dekurs existuje, ale sekci příloh nemá → prepend
print(f"\n>>> DEKURS ID={dekurs_id} nemá sekci příloh → vkládám sekci na začátek...")
merged_rtf = merge_rtf_prepend(existing_rtf, bookmark_list, new_body, len(skupiny[key]))
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 → vytvoříme nový
print(f"\n>>> Žádný dekurs pro dnešek → vytvářím nový...")
bookmark_str = ';'.join(bookmark_list)
rtf = RTF_TEMPLATE.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, datumzapisu, caszapisu, rtf)
)
conn.commit()
print(f"\n>>> Nový DEKURS ID={dekursid}")
print("\n=== HOTOVO ===")
conn.close()