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()