notebook vb
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
- Zahájeno: 2026-03-13
|
||||
- Cíl: průzkum Firebird DB Medicus → analýzy a reporty
|
||||
- Zatím: úspěšně čteme i zapisujeme do DB, rozumíme RTF formátu
|
||||
- **2026-03-17**: Obnovena session – Claude si přečetl poznámky, připraven pokračovat
|
||||
- **2026-03-18**: Obnovena session – Claude si přečetl poznámky, připraven pokračovat. Průběžně zapisuje do tohoto souboru.
|
||||
|
||||
## Bezpečnost
|
||||
- Pracujeme na **místní kopii** – poškození DB nevadí, obnova = 5 minut
|
||||
@@ -21,6 +23,9 @@ conn = fdb.connect(
|
||||
)
|
||||
```
|
||||
- fdb verze 2.0.4, Python na PATH (prostý `python` příkaz)
|
||||
- Firebird instalace: `C:\Program Files\Firebird\Firebird_2_5_CGM\bin\`
|
||||
- Jedná se o **HQbird** (IBSurgeon enhanced Firebird) – port **3070** (ne standardní 3050)
|
||||
- fbtracemgr trace nefungoval spolehlivě – doporučeno použít **FBScanner** (stejný výrobce)
|
||||
|
||||
## O Medicusu
|
||||
- Lékařský software pro praktického lékaře
|
||||
@@ -157,6 +162,186 @@ conn.commit()
|
||||
- `insert_test.py` – testovací INSERT do DEKURS
|
||||
- `CLAUDE_NOTES.md` – tento soubor
|
||||
|
||||
## Export FILES do externích DB (zjištěno 2026-03-17 přes FBScanner)
|
||||
|
||||
### Mechanismus přesunu
|
||||
Medicus vytváří **měsíční** externí Firebird databáze ve formátu `MEDICUS_FILES_YYYYMM.fdb`.
|
||||
|
||||
**Postup exportu:**
|
||||
1. SELECT dat z FILES po 10 záznamech: `select first 10 ID, BODY, DATUM from FILES where ID > X ORDER BY ID ASC`
|
||||
2. Binární data (skeny) se zapíší do externího `.fdb` souboru
|
||||
3. V hlavní DB se BODY přepíše referenčním číslem (ID v externím souboru): `update FILES set BODY = 379 where ID = 10009`
|
||||
4. Do EXTERNI_DB se zapíše lokace: `insert into EXTERNI_DB (DBNAME, SERVER, PATH, HESLO) values ('DB202501', 'localhost/3053', 'u:\MEDICUS_FILES_202501.fdb', '<encrypted>')`
|
||||
|
||||
### Výsledek
|
||||
- Hlavní DB: FILES.BODY obsahuje jen malé číslo (referenci) místo MB blobu
|
||||
- Skenované soubory jsou fyzicky v `u:\MEDICUS_FILES_YYYYMM.fdb`
|
||||
- Medicus načítá soubory přes EXTERNI_DB tabulku (SERVER + PATH + HESLO)
|
||||
- Hesla v EXTERNI_DB jsou šifrovaná (base64 AES)
|
||||
|
||||
### FBScanner
|
||||
- Nainstalován, funguje jako proxy: Medicus → [3050] FBScanner → [3053] Firebird
|
||||
- Community Edition 2.5 – stačí pro monitoring
|
||||
- Export proveden na záloze (ne produkční DB)
|
||||
|
||||
## Přímý zápis do externí DB – dokončeno (2026-03-17)
|
||||
|
||||
### Nový soubor: `funkce_ext.py`
|
||||
Náhrada za `funkce.zapis_file()`. Ukládá PDF přímo do měsíční externí FDB
|
||||
místo do hlavní medicus.fdb.
|
||||
|
||||
**Funkce:** `zapis_file_ext(vstupconnection, idpac, cesta, souborname, prvnizavorka, soubordate, souborfiledate, poznamka, ext_base_path=r'u:\\')`
|
||||
- Parametry shodné s `funkce.zapis_file()` → jen prohodit import
|
||||
- Vrací `fileid` stejně jako původní funkce
|
||||
|
||||
**Co dělá:**
|
||||
1. Z `soubordate` odvodí `YYYYMM` → `DBNAME = 'DB202603'`
|
||||
2. Načte PDF jako bytes
|
||||
3. Vyhledá EXTERNI_DB pro daný měsíc:
|
||||
- Nalezeno → připojí se k existující FDB (masterkey)
|
||||
- Nenalezeno → vytvoří novou `MEDICUS_FILES_YYYYMM.fdb`, zaregistruje do EXTERNI_DB
|
||||
4. Vygeneruje `UID = uuid.uuid4().hex` (32 znaků)
|
||||
5. Zapíše do DATA tabulky: `UID, DATA (blob), DATASIZE, CHUNK=0`
|
||||
6. Sestaví 48bajtovou BODY referenci
|
||||
7. Získá `fileid` z Gen_Files
|
||||
8. Vloží do FILES s BODY = reference (ne blob)
|
||||
|
||||
### Úprava `s03soubory.py`
|
||||
- Přidán import `funkce_ext`
|
||||
- Volání `funkce.zapis_file(...)` nahrazeno `funkce_ext.zapis_file_ext(...)`
|
||||
|
||||
### BODY reference – binární formát (48 B)
|
||||
```
|
||||
magic 4 B = b'\xee\xbb\xaa\x0b'
|
||||
uid 32 B = UUID4 hex (ASCII, 32 znaků)
|
||||
dblen 4 B = len(DBNAME) jako little-endian uint32
|
||||
dbname N B = DBNAME ASCII (typicky 'DB202603', 8 B)
|
||||
```
|
||||
Celkem typicky: 4 + 32 + 4 + 8 = **48 bajtů**
|
||||
|
||||
### Struktura DATA tabulky (externe DB)
|
||||
```
|
||||
UID VARCHAR(32) NOT NULL
|
||||
DATA BLOB SUB_TYPE 0
|
||||
DATASIZE INTEGER
|
||||
CHUNK INTEGER
|
||||
```
|
||||
Generator: `GEN_UID` (Medicus ho asi nepoužívá přímo, UID je UUID string)
|
||||
|
||||
### EXTERNI_DB tabulka (hlavní DB)
|
||||
```
|
||||
DBNAME např. 'DB202603'
|
||||
SERVER např. 'localhost/3053' (FBScanner proxy)
|
||||
PATH např. 'u:\MEDICUS_FILES_202603.fdb'
|
||||
HESLO šifrované heslo (Medicus AES) – zkopírujeme z existující položky
|
||||
```
|
||||
Při vytváření nové DB: HESLO zkopírujeme z libovolné existující EXTERNI_DB položky
|
||||
(všechny používají masterkey, jen jinak zašifrované – ale stejný klíč).
|
||||
|
||||
### Poznámka k HESLO šifrování
|
||||
Hesla v EXTERNI_DB jsou šifrovaná Medicusem. Při vytváření nové DB proto
|
||||
zkopírujeme HESLO z existující položky (stejné heslo = stejný šifrovaný text).
|
||||
Medicus pak dokáže novou DB otevřít standardně. Pokud by to nefungovalo,
|
||||
lze heslo zadat manuálně přes správce Medicusu.
|
||||
|
||||
## Stav 2026-03-18 – nastudováno po obnově session
|
||||
|
||||
### Co bylo dokončeno (včera večer)
|
||||
- `funkce_ext.zapis_file_ext()` je **otestována a funkční**
|
||||
- `s03soubory.py` volá `zapis_file_ext` místo původní `funkce.zapis_file`
|
||||
- Celý import pipeline funguje end-to-end
|
||||
|
||||
### Celý import pipeline (s03soubory.py)
|
||||
1. Scanuje složku `u:\NextcloudOrdinace\Dokumentace_ke_zpracování`
|
||||
2. Ověří formát názvu souboru: `RC YYYY-MM-DD Jmeno, Jmeno. [prvnizavorka] [druhazavorka].pdf`
|
||||
3. Ověří rodné číslo v KAR tabulce
|
||||
4. Seskupí soubory podle RC (jeden pacient = jeden dekurs)
|
||||
5. Pro každý PDF zavolá `funkce_ext.zapis_file_ext()` → zapíše do externí DB
|
||||
6. Přesune soubor do `u:\NextcloudOrdinace\Dokumentace_zpracovaná`
|
||||
7. Sestaví RTF se záložkami (klikatelné odkazy na soubory v Medicusu)
|
||||
8. Zapíše dekurs do DEKURS tabulky
|
||||
|
||||
### Klíčové soubory
|
||||
- `funkce_ext.py` – zápis PDF do měsíční externí FDB (náhrada za funkce.zapis_file)
|
||||
- `funkce.py` – původní funkce (zapis_file, zapis_dekurs, get_files_id, get_idpac, convert_to1250)
|
||||
- `s03soubory.py` – hlavní import script (spouštět na Windows)
|
||||
- `s04_presun_externi_db.py` – utility: přesun ext DB souborů do u:\externi\ a update PATH v EXTERNI_DB
|
||||
- `test_ext_db4.py` – ověření BODY bajty z FILES tabulky (hex dump)
|
||||
|
||||
### Formát názvu souboru pro import
|
||||
```
|
||||
RC YYYY-MM-DD Prijmeni, Jmeno. [prvnizavorka] [druhazavorka].pdf
|
||||
např: 7309208104 2026-03-17 Buzalka, Vladimír. [EKG] [normální nález].pdf
|
||||
```
|
||||
|
||||
## Oprava RTF klikacích odkazů (2026-03-18)
|
||||
|
||||
### Problém
|
||||
`s03soubory.py` generoval RTF s `\cs22` pro styl odkazu, ale Medicus vyžaduje `\cs32`.
|
||||
Druhý+ bookmark neměl link styling vůbec. `poradi` se nikdy neinkrementoval.
|
||||
|
||||
### Zjištěno analýzou Medicusem vytvořeného DEKURS (ID=263480, AhojClaude.pdf)
|
||||
Správný RTF formát klikacího odkazu:
|
||||
```
|
||||
{\*\cs32\f0\ul\fs20\cf1 Odkaz;} ← stylesheet: cs32, NE cs22
|
||||
\uc1\pard\s10\plain\cs20\f0\i\fs20 Přílohy: {\*\bkmkstart 0}\plain\cs32\f0\ul\fs20\cf1 TEXT{\*\bkmkend 0}\par
|
||||
```
|
||||
- "Přílohy:" je inline s prvním odkazem na stejném `\pard` řádku
|
||||
- Každý další odkaz: `\pard\s10{\*\bkmkstart N}\plain\cs32\f0\ul\fs20\cf1 TEXT{\*\bkmkend N}\par`
|
||||
|
||||
### Opraveno v s03soubory.py + test_import_3files.py
|
||||
1. `\cs22` → `\cs32` v stylesheet i těle RTF
|
||||
2. Header `Vložené přílohy:` je na **samostatném** `\pard` řádku (RTF: `Vlo\'9een\'e9 p\'f8\'edlohy:`)
|
||||
3. Všechny bookmarky mají stejný formát: `\pard\s10{\*\bkmkstart N}\plain\cs32\f0\ul\fs20\cf1 TEXT{\*\bkmkend N}\par`
|
||||
4. Přidáno `poradi += 1` (bug: poradi se nikdy neinkrementoval)
|
||||
5. Odstraněna proměnná `prvnibookmark` – již nepotřebná
|
||||
|
||||
### RTF kódování českých znaků (win1250)
|
||||
- ž = `\'9e`, é = `\'e9`, ř = `\'f8`, í = `\'ed`, á = `\'e1`
|
||||
- "Vložené přílohy:" → `Vlo\'9een\'e9 p\'f8\'edlohy:`
|
||||
|
||||
## Merge do existujícího dekurzu (2026-03-18)
|
||||
|
||||
### Rozhodovací logika (3 případy)
|
||||
1. Poslední dekurs pacienta je z dnešního dne A má `Vložené přílohy:`
|
||||
→ **přidat soubor DO existující sekce** (`pridat_do_sekce_prilohy`)
|
||||
2. Poslední dekurs je z dnešního dne, ale sekci nemá
|
||||
→ **prepend nové sekce na začátek** (`merge_rtf_prepend`)
|
||||
3. Poslední dekurs je z jiného dne / neexistuje
|
||||
→ **nový dekurs pro dnešek**
|
||||
- Funkce: `najdi_posledni_dekurs_dnes(conn, idpac, datum_vlozeni)`
|
||||
|
||||
### pridat_do_sekce_prilohy (přidání do existující sekce)
|
||||
1. Spočítat `"Files:"` v `{\info{\bookmarks}}` = N → nový bkmkstart = N
|
||||
2. Posunout všechny bkmkstart/bkmkend ≥ N o +1 (uvolnit index N)
|
||||
3. Vložit nový `\pard` před `\pard\s10\plain\cs15\f0\fs20 \par` (konec sekce)
|
||||
4. Vložit bookmark na pozici N do `{\info{\bookmarks}}`
|
||||
|
||||
### merge_rtf_prepend (prepend nové sekce)
|
||||
1. Posunout existující `\bkmkstart N` / `\bkmkend N` o počet nových souborů
|
||||
2. Přidat naše bookmarky NA ZAČÁTEK `{\info{\bookmarks ...}}`
|
||||
3. Vložit naše `\pard` tělo PŘED první `\uc1\pard` existujícího těla
|
||||
|
||||
### Detekce sekce
|
||||
- Přítomnost: `PRILOHY_HEADER = r"Vlo\'9een\'e9 p\'f8\'edlohy:"` – hledáme v RTF
|
||||
- Konec sekce: `PRILOHY_CLOSING = r'\pard\s10\plain\cs15\f0\fs20 \par'`
|
||||
|
||||
### Skripty
|
||||
- `test_import_merge.py` – 3 soubory → merge do dnešního dekurzu (bez sekce přílohy)
|
||||
- `test_import_single.py` – 1 soubor → merge DO existující sekce přílohy
|
||||
- `test_import_3files.py` – 3 soubory → vždy nový dekurs (bez merge logiky, starší)
|
||||
|
||||
### Stav testování (2026-03-18)
|
||||
- `test_import_3files.py` ✅ ověřeno – klikací odkazy fungují, "Vložené přílohy:" správně
|
||||
- `test_import_merge.py` – připraveno, nespuštěno
|
||||
- `test_import_single.py` – připraveno, nespuštěno
|
||||
|
||||
### TODO – integrace do s03soubory.py
|
||||
- Přidat `najdi_posledni_dekurs_dnes()` do s03soubory.py
|
||||
- Přidat `pridat_do_sekce_prilohy()` a `merge_rtf_prepend()` do s03soubory.py
|
||||
- Nahradit přímý INSERT DEKURS rozhodovací logikou (3 případy)
|
||||
- Pozn: s03soubory.py má starý `prvnibookmark=True` blok – odstranit (relikt)
|
||||
|
||||
## Další postup (nápady)
|
||||
- Napsat `rtf_to_text()` pro extrakci čistého textu z dekurzů
|
||||
- Prozkoumat tabulky: LECH/LECD (léky?), POU (poukazy?), AMBULEKY (výkony?)
|
||||
|
||||
37
MedicusWithClaude/SPUST_TRACE.bat
Normal file
37
MedicusWithClaude/SPUST_TRACE.bat
Normal file
@@ -0,0 +1,37 @@
|
||||
@echo off
|
||||
:: Firebird SQL trace pro Medicus
|
||||
:: Zachytí všechny SQL příkazy při exportu souborů do externích DB
|
||||
::
|
||||
:: INSTRUKCE:
|
||||
:: 1. Spusť tento soubor jako Administrator (pravé tlačítko → Spustit jako správce)
|
||||
:: 2. Nechej okno otevřené
|
||||
:: 3. V Medicusu proveď export souborů do externích DB
|
||||
:: 4. Vrať se sem a stiskni Ctrl+C pro zastavení
|
||||
:: 5. Log najdeš v medicus_trace_output.txt
|
||||
|
||||
echo.
|
||||
echo === MEDICUS SQL TRACE ===
|
||||
echo Hledam Firebird fbtracemgr...
|
||||
echo.
|
||||
|
||||
set FB_BIN=C:\Program Files\Firebird\Firebird_2_5_CGM\bin
|
||||
|
||||
if not exist "%FB_BIN%\fbtracemgr.exe" (
|
||||
echo CHYBA: fbtracemgr.exe nenalezen v %FB_BIN%
|
||||
echo Zkontroluj cestu a uprav tento soubor.
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo Nalezen: %FB_BIN%\fbtracemgr.exe
|
||||
echo.
|
||||
echo POZOR: Nyni PROVEĎ export v Medicusu, pak se vrat a stiskni Ctrl+C
|
||||
echo Výstup se zapisuje do: medicus_trace_output.txt
|
||||
echo.
|
||||
|
||||
powershell -Command "& '%FB_BIN%\fbtracemgr.exe' -se localhost:service_mgr -user SYSDBA -password masterkey -start -config '%~dp0medicus_trace.conf' | Tee-Object -FilePath '%~dp0medicus_trace_output.txt'"
|
||||
|
||||
echo.
|
||||
echo === TRACE ZASTAVEN ===
|
||||
echo Výsledky jsou v medicus_trace_output.txt
|
||||
pause
|
||||
42
MedicusWithClaude/check_last_dekurs.py
Normal file
42
MedicusWithClaude/check_last_dekurs.py
Normal file
@@ -0,0 +1,42 @@
|
||||
"""check_last_dekurs.py – zobrazí posledních 5 záznamů v DEKURS + FILES pro pacienta 9742"""
|
||||
import fdb
|
||||
|
||||
conn = fdb.connect(
|
||||
dsn=r'localhost:c:\medicus 3\data\medicus.fdb',
|
||||
user='SYSDBA', password='masterkey', charset='WIN1250'
|
||||
)
|
||||
cur = conn.cursor()
|
||||
|
||||
print("=== Posledních 5 záznamů DEKURS pro Buzalka (idpac=9742) ===")
|
||||
cur.execute("""
|
||||
SELECT id, datum, cas, OCTET_LENGTH(dekurs) as delka
|
||||
FROM dekurs WHERE idpac = 9742
|
||||
ORDER BY id DESC ROWS 5
|
||||
""")
|
||||
for row in cur.fetchall():
|
||||
print(f" ID={row[0]} datum={row[1]} cas={row[2]} délka={row[3]} B")
|
||||
|
||||
print()
|
||||
print("=== Obsah posledního DEKURS záznamu ===")
|
||||
cur.execute("""
|
||||
SELECT dekurs FROM dekurs WHERE idpac = 9742
|
||||
ORDER BY id DESC ROWS 1
|
||||
""")
|
||||
row = cur.fetchone()
|
||||
if row:
|
||||
text = row[0]
|
||||
if isinstance(text, bytes):
|
||||
text = text.decode('cp1250', errors='replace')
|
||||
print(text)
|
||||
|
||||
print()
|
||||
print("=== Posledních 5 záznamů FILES pro Buzalka (idpac=9742) ===")
|
||||
cur.execute("""
|
||||
SELECT id, filename, datum, OCTET_LENGTH(body) as bodylen
|
||||
FROM files WHERE idpac = 9742
|
||||
ORDER BY id DESC ROWS 5
|
||||
""")
|
||||
for row in cur.fetchall():
|
||||
print(f" ID={row[0]} filename={row[1]} datum={row[2]} body={row[3]} B")
|
||||
|
||||
conn.close()
|
||||
70
MedicusWithClaude/db_query.py
Normal file
70
MedicusWithClaude/db_query.py
Normal file
@@ -0,0 +1,70 @@
|
||||
"""
|
||||
Pomocný skript pro Clauda – spusť na Windows: python db_query.py
|
||||
Výsledky zapíše do db_query_result.txt
|
||||
"""
|
||||
import fdb
|
||||
import json
|
||||
import sys
|
||||
|
||||
conn = fdb.connect(
|
||||
dsn=r'localhost:c:\medicus 3\data\medicus.fdb',
|
||||
user='SYSDBA',
|
||||
password='masterkey',
|
||||
charset='win1250'
|
||||
)
|
||||
cur = conn.cursor()
|
||||
|
||||
results = {}
|
||||
|
||||
# 1. Tabulky s klíčovými slovy (soubory, dokumenty)
|
||||
cur.execute("""
|
||||
SELECT RDB$RELATION_NAME
|
||||
FROM RDB$RELATIONS
|
||||
WHERE RDB$SYSTEM_FLAG = 0 AND RDB$VIEW_BLR IS NULL
|
||||
ORDER BY RDB$RELATION_NAME
|
||||
""")
|
||||
all_tables = [row[0].strip() for row in cur.fetchall()]
|
||||
|
||||
keywords = ['FILE', 'SOUB', 'DOC', 'SCAN', 'OBRAZ', 'IMG', 'ATTACH',
|
||||
'EXTERN', 'PRILOHA', 'ZPRAV', 'ARCH', 'PRIL', 'FOTO']
|
||||
matches = [t for t in all_tables if any(k in t.upper() for k in keywords)]
|
||||
results['tables_matching'] = matches
|
||||
results['total_tables'] = len(all_tables)
|
||||
|
||||
# 2. Podrobnosti o nalezených tabulkách (sloupce + počet řádků)
|
||||
table_details = {}
|
||||
for t in matches:
|
||||
try:
|
||||
cur.execute(f"SELECT COUNT(*) FROM {t}")
|
||||
count = cur.fetchone()[0]
|
||||
except:
|
||||
count = "error"
|
||||
|
||||
cur.execute("""
|
||||
SELECT r.RDB$FIELD_NAME, f.RDB$FIELD_TYPE, f.RDB$FIELD_LENGTH
|
||||
FROM RDB$RELATION_FIELDS r
|
||||
JOIN RDB$FIELDS f ON f.RDB$FIELD_NAME = r.RDB$FIELD_SOURCE
|
||||
WHERE r.RDB$RELATION_NAME = ?
|
||||
ORDER BY r.RDB$FIELD_POSITION
|
||||
""", (t,))
|
||||
cols = [(row[0].strip(), row[1], row[2]) for row in cur.fetchall()]
|
||||
table_details[t] = {"count": count, "columns": cols}
|
||||
|
||||
results['table_details'] = table_details
|
||||
|
||||
# 3. Uložit výsledky
|
||||
output = []
|
||||
output.append(f"=== VÝSLEDKY DB PRŮZKUMU ===\n")
|
||||
output.append(f"Celkem tabulek v DB: {results['total_tables']}\n")
|
||||
output.append(f"\nTabulky obsahující klíčová slova (soubory/dokumenty):\n")
|
||||
for t in results['tables_matching']:
|
||||
d = results['table_details'].get(t, {})
|
||||
output.append(f"\n ** {t} ** (řádků: {d.get('count', '?')})")
|
||||
for col in d.get('columns', []):
|
||||
output.append(f" - {col[0]} (type={col[1]}, len={col[2]})")
|
||||
|
||||
with open('db_query_result.txt', 'w', encoding='utf-8') as f:
|
||||
f.write('\n'.join(output))
|
||||
|
||||
print("Hotovo! Výsledky jsou v db_query_result.txt")
|
||||
conn.close()
|
||||
75
MedicusWithClaude/db_query2.py
Normal file
75
MedicusWithClaude/db_query2.py
Normal file
@@ -0,0 +1,75 @@
|
||||
"""
|
||||
Podrobný průzkum FILES a EXTERNI_DB – spusť na Windows: python db_query2.py
|
||||
"""
|
||||
import fdb
|
||||
|
||||
conn = fdb.connect(
|
||||
dsn=r'localhost:c:\medicus 3\data\medicus.fdb',
|
||||
user='SYSDBA',
|
||||
password='masterkey',
|
||||
charset='win1250'
|
||||
)
|
||||
cur = conn.cursor()
|
||||
out = []
|
||||
|
||||
# 1. Obsah EXTERNI_DB
|
||||
out.append("=== EXTERNI_DB (konfigurace externích databází) ===")
|
||||
cur.execute("SELECT DBNAME, PATH, SERVER, HESLO FROM EXTERNI_DB")
|
||||
for row in cur.fetchall():
|
||||
out.append(f" DBNAME={row[0]} PATH={row[1]} SERVER={row[2]} HESLO={row[3]}")
|
||||
|
||||
# 2. FILES – přehled po rocích
|
||||
out.append("\n=== FILES – počty záznamů po rocích ===")
|
||||
cur.execute("""
|
||||
SELECT EXTRACT(YEAR FROM DATUM) as ROK, COUNT(*) as POCET,
|
||||
SUM(OCTET_LENGTH(BODY)) as CELKEM_BYTU
|
||||
FROM FILES
|
||||
GROUP BY EXTRACT(YEAR FROM DATUM)
|
||||
ORDER BY ROK
|
||||
""")
|
||||
total_bytes = 0
|
||||
for row in cur.fetchall():
|
||||
rok, pocet, bytu = row
|
||||
mb = (bytu or 0) / 1024 / 1024
|
||||
total_bytes += (bytu or 0)
|
||||
out.append(f" Rok {int(rok) if rok else '?'}: {pocet} souborů, {mb:.1f} MB")
|
||||
out.append(f" CELKEM: {total_bytes/1024/1024:.1f} MB v BLOB datech FILES")
|
||||
|
||||
# 3. FILES – ukázka typů souborů
|
||||
out.append("\n=== FILES – typy souborů (dle přípony FILENAME) ===")
|
||||
cur.execute("""
|
||||
SELECT LOWER(SUBSTRING(FILENAME FROM CHAR_LENGTH(FILENAME) - 3)) as EXT,
|
||||
COUNT(*) as POCET
|
||||
FROM FILES
|
||||
WHERE FILENAME IS NOT NULL
|
||||
GROUP BY 1
|
||||
ORDER BY 2 DESC
|
||||
""")
|
||||
for row in cur.fetchall():
|
||||
out.append(f" {row[0]} : {row[1]} souborů")
|
||||
|
||||
# 4. FILES – ukázka prvních 5 záznamů (bez BODY)
|
||||
out.append("\n=== FILES – ukázka 5 záznamů (bez binárních dat) ===")
|
||||
cur.execute("""
|
||||
SELECT ID, IDPAC, FILENAME, DATUM, OCTET_LENGTH(BODY) as VELIKOST,
|
||||
POZNAMKA, IDDOCTYP
|
||||
FROM FILES
|
||||
ORDER BY DATUM DESC
|
||||
ROWS 5
|
||||
""")
|
||||
for row in cur.fetchall():
|
||||
out.append(f" ID={row[0]} IDPAC={row[1]} soubor={row[2]} datum={row[3]}"
|
||||
f" velikost={row[4]}B pozn={row[5]} typ={row[6]}")
|
||||
|
||||
# 5. DOCTYP – typy dokumentů
|
||||
out.append("\n=== DOCTYP – číselník typů dokumentů ===")
|
||||
cur.execute("SELECT ID, NAZEV, SYSID FROM DOCTYP ORDER BY ID")
|
||||
for row in cur.fetchall():
|
||||
out.append(f" ID={row[0]} nazev={row[1]} sysid={row[2]}")
|
||||
|
||||
result = '\n'.join(out)
|
||||
print(result)
|
||||
with open('db_query2_result.txt', 'w', encoding='utf-8') as f:
|
||||
f.write(result)
|
||||
print("\nUloženo do db_query2_result.txt")
|
||||
conn.close()
|
||||
532
MedicusWithClaude/db_query_result.txt
Normal file
532
MedicusWithClaude/db_query_result.txt
Normal file
@@ -0,0 +1,532 @@
|
||||
=== VÝSLEDKY DB PRŮZKUMU ===
|
||||
|
||||
Celkem tabulek v DB: 993
|
||||
|
||||
|
||||
Tabulky obsahující klíčová slova (soubory/dokumenty):
|
||||
|
||||
|
||||
** CHAT_ZPRAVY ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- IDADRESAR (type=8, len=4)
|
||||
- ODCHOZI (type=14, len=1)
|
||||
- ODESLANO (type=35, len=8)
|
||||
- TEXT (type=261, len=8)
|
||||
- OTHER_ID (type=8, len=4)
|
||||
- PRECTENO (type=35, len=8)
|
||||
- SENT (type=35, len=8)
|
||||
|
||||
** CLICKDOC ** (řádků: 2)
|
||||
- KEY (type=37, len=100)
|
||||
- VALUE (type=37, len=100)
|
||||
|
||||
** CLICKDOC_CINNOSTI ** (řádků: 0)
|
||||
- IDCLICKDOC (type=8, len=4)
|
||||
- IDCINNOSTI (type=8, len=4)
|
||||
|
||||
** CLICKDOC_KAR ** (řádků: 0)
|
||||
- IDCLICKDOC (type=8, len=4)
|
||||
- IDPAC (type=8, len=4)
|
||||
|
||||
** CLICKDOC_OBJ ** (řádků: 0)
|
||||
- IDCLICKDOC (type=8, len=4)
|
||||
- IDOBJ (type=8, len=4)
|
||||
- REMOTECREATE (type=14, len=1)
|
||||
- REMOTECHANGE (type=14, len=1)
|
||||
- APPROVAL (type=7, len=2)
|
||||
- SEND_REMINDER_SMS (type=14, len=1)
|
||||
|
||||
** CLICKDOC_UZIVATEL ** (řádků: 0)
|
||||
- IDCLICKDOC (type=8, len=4)
|
||||
- IDUZI (type=8, len=4)
|
||||
|
||||
** DEKIMG ** (řádků: 8)
|
||||
- ID (type=8, len=4)
|
||||
- HASH (type=37, len=32)
|
||||
- REFCOUNT (type=8, len=4)
|
||||
- DATA (type=261, len=8)
|
||||
|
||||
** DEKIMGREF ** (řádků: 7)
|
||||
- ID (type=8, len=4)
|
||||
- IDPAC (type=8, len=4)
|
||||
- IDDEKURS (type=8, len=4)
|
||||
- IDDEKIMG (type=8, len=4)
|
||||
|
||||
** DOCLIST ** (řádků: 461429)
|
||||
- ID (type=8, len=4)
|
||||
- DATUM (type=12, len=4)
|
||||
- TABULKA (type=37, len=20)
|
||||
- IDREC (type=8, len=4)
|
||||
- TYP (type=7, len=2)
|
||||
- POPIS (type=37, len=40)
|
||||
- IDPAC (type=8, len=4)
|
||||
- IDODDEL (type=8, len=4)
|
||||
|
||||
** DOCTYP ** (řádků: 27)
|
||||
- ID (type=8, len=4)
|
||||
- NAZEV (type=37, len=32)
|
||||
- SYSID (type=8, len=4)
|
||||
|
||||
** DOMPECEARCHIV ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- CREATED (type=35, len=8)
|
||||
- DATA (type=261, len=8)
|
||||
|
||||
** ED_BOOKOFSUBMISSIONATTACH ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- BOOK_OF_SUBMISSION_ID (type=8, len=4)
|
||||
- ORDER (type=8, len=4)
|
||||
- HAS_ALREADY_BEEN_SENT (type=14, len=1)
|
||||
- NAME (type=37, len=255)
|
||||
- CONTENT (type=261, len=8)
|
||||
|
||||
** EET_ZPRAVARECORD ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- UUID_ZPRAVY (type=14, len=16)
|
||||
- ID_TRZBA (type=8, len=4)
|
||||
- GUID_TRZBA (type=14, len=16)
|
||||
- DAT_ODESL (type=35, len=8)
|
||||
- CERTTHUMBPRINT (type=37, len=64)
|
||||
- REQUEST (type=261, len=8)
|
||||
- RESPONSE (type=261, len=8)
|
||||
- RESP_TYPE (type=8, len=4)
|
||||
- RESP_UUID_ZPRAVY (type=37, len=50)
|
||||
- RESP_DAT_PRIJ (type=35, len=8)
|
||||
- RESP_DAT_ODMIT (type=35, len=8)
|
||||
- RESP_BKP (type=37, len=44)
|
||||
- RESP_FIK (type=37, len=39)
|
||||
- RESP_KOD (type=8, len=4)
|
||||
- RESP_CHYBA (type=37, len=100)
|
||||
- PRVNI_ZASLANI (type=7, len=2)
|
||||
- RESP_TEST (type=7, len=2)
|
||||
- RESP_EXCEPTIONMESSAGE (type=261, len=8)
|
||||
|
||||
** ES_KONZULTACE_FILE ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- ID_KONZULTACE (type=8, len=4)
|
||||
- CAS (type=35, len=8)
|
||||
- NAME (type=37, len=256)
|
||||
- CONTENT (type=261, len=8)
|
||||
- MIME (type=37, len=100)
|
||||
- PATIENT_DOC (type=14, len=1)
|
||||
- PORADI (type=8, len=4)
|
||||
|
||||
** EXTERNI_DB ** (řádků: 1)
|
||||
- DBNAME (type=37, len=12)
|
||||
- PATH (type=37, len=120)
|
||||
- SERVER (type=37, len=32)
|
||||
- HESLO (type=37, len=64)
|
||||
|
||||
** FILES ** (řádků: 10305)
|
||||
- ID (type=8, len=4)
|
||||
- IDPAC (type=8, len=4)
|
||||
- DOCID (type=8, len=4)
|
||||
- TYP (type=8, len=4)
|
||||
- FILENAME (type=37, len=254)
|
||||
- BODY (type=261, len=8)
|
||||
- DATUM (type=12, len=4)
|
||||
- IDDOCTYP (type=8, len=4)
|
||||
- IDPRAC (type=8, len=4)
|
||||
- IDUZI (type=8, len=4)
|
||||
- POZNAMKA (type=37, len=100)
|
||||
- DATSOUBORU (type=35, len=8)
|
||||
- ID_EDOKUMENT (type=8, len=4)
|
||||
- EXT_ID (type=37, len=36)
|
||||
|
||||
** FNUSA_ATTACHMENT ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- DATA (type=261, len=8)
|
||||
- ATTACH_INT_TYP (type=37, len=1)
|
||||
- ATTACH_INT_ID (type=8, len=4)
|
||||
- LAST_UPDATED (type=35, len=8)
|
||||
|
||||
** GRARCH ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- NAME (type=37, len=16)
|
||||
- PATH (type=37, len=150)
|
||||
|
||||
** GRDOC ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- IDNEM (type=37, len=60)
|
||||
- IDPAC (type=8, len=4)
|
||||
- SKUPINA (type=8, len=4)
|
||||
- DATUM (type=12, len=4)
|
||||
- PREVIEW (type=261, len=8)
|
||||
- PICT (type=261, len=8)
|
||||
- LOCATION (type=37, len=16)
|
||||
|
||||
** HISTDOC ** (řádků: 32250)
|
||||
- ID (type=8, len=4)
|
||||
- TYP (type=37, len=7)
|
||||
- DATUM (type=12, len=4)
|
||||
- DATA (type=261, len=8)
|
||||
- CENA (type=16, len=8)
|
||||
- REPPOZN (type=37, len=60)
|
||||
- REPDATUM (type=12, len=4)
|
||||
- IDPACI (type=8, len=4)
|
||||
- IDZAR (type=8, len=4)
|
||||
- IDODD (type=8, len=4)
|
||||
- IDPRAC (type=8, len=4)
|
||||
- IDUZIV (type=8, len=4)
|
||||
- IDLEK (type=8, len=4)
|
||||
- IDZARPR (type=8, len=4)
|
||||
- IDODDPR (type=8, len=4)
|
||||
- IDPRACPR (type=8, len=4)
|
||||
- IDLEKPR (type=8, len=4)
|
||||
- STAV (type=14, len=1)
|
||||
- REPSTAV (type=14, len=1)
|
||||
- IDSABLONPRAC (type=37, len=55)
|
||||
- REPTEXT (type=261, len=8)
|
||||
- TYPCENY (type=14, len=1)
|
||||
- CENAPACIENT (type=16, len=8)
|
||||
- IDDOKLAD (type=8, len=4)
|
||||
- POZNAMKA (type=37, len=100)
|
||||
- PRINTED (type=14, len=1)
|
||||
- PRIJALJINE (type=37, len=150)
|
||||
- BMKDATA (type=261, len=8)
|
||||
- PORCISLO (type=8, len=4)
|
||||
- DRUHPOJ (type=8, len=4)
|
||||
- IDLEKZPR (type=8, len=4)
|
||||
- IDHLAV (type=8, len=4)
|
||||
- CREATED (type=35, len=8)
|
||||
- IDSOUHLASPACSABL (type=8, len=4)
|
||||
- REPIDUZIVINS (type=8, len=4)
|
||||
- REPIDUZIVUPD (type=8, len=4)
|
||||
- CGMNUMBER_ODESILATEL (type=37, len=12)
|
||||
- CGMNUMBER_PRIJEMCE (type=37, len=12)
|
||||
- CLICKBOX_ATT_ID (type=8, len=4)
|
||||
- CLICKBOX_MAILBOX (type=37, len=255)
|
||||
- ID_EDOKUMENT (type=8, len=4)
|
||||
|
||||
** HISTDOCLAB ** (řádků: 27185)
|
||||
- ID (type=8, len=4)
|
||||
- IDHISTDOC (type=8, len=4)
|
||||
- IDMETOD (type=8, len=4)
|
||||
- POZN (type=261, len=8)
|
||||
- IDPLADET (type=8, len=4)
|
||||
|
||||
** HISTDOCLABPARAMS ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- IDHISTDOC (type=8, len=4)
|
||||
- IDHISTDOCLAB (type=8, len=4)
|
||||
- IDPARAM (type=8, len=4)
|
||||
- TYP (type=14, len=1)
|
||||
- TEXT (type=14, len=8)
|
||||
|
||||
** HISTDOCSABL ** (řádků: 7)
|
||||
- ID (type=8, len=4)
|
||||
- TYP (type=37, len=7)
|
||||
- DATA (type=261, len=8)
|
||||
- IDZAR (type=8, len=4)
|
||||
- IDODD (type=8, len=4)
|
||||
- IDPRAC (type=8, len=4)
|
||||
- IDUZIV (type=8, len=4)
|
||||
- IDLEK (type=8, len=4)
|
||||
- IDZARPR (type=8, len=4)
|
||||
- IDODDPR (type=8, len=4)
|
||||
- IDPRACPR (type=8, len=4)
|
||||
- IDLEKPR (type=8, len=4)
|
||||
- STAV (type=14, len=1)
|
||||
- IDSABLONPRAC (type=37, len=55)
|
||||
- NAZEV (type=37, len=48)
|
||||
- REPSTAV (type=14, len=1)
|
||||
- CENA (type=37, len=20)
|
||||
- DOPLATEK (type=37, len=20)
|
||||
- USEPRAC (type=8, len=4)
|
||||
- USEUZIV (type=8, len=4)
|
||||
|
||||
** HISTDOCSABLLAB ** (řádků: 19)
|
||||
- ID (type=8, len=4)
|
||||
- IDHISTDOC (type=8, len=4)
|
||||
- IDMETOD (type=8, len=4)
|
||||
|
||||
** HISTDOCVYK ** (řádků: 1868)
|
||||
- IDHDVYK (type=8, len=4)
|
||||
- ID (type=8, len=4)
|
||||
- KOD (type=14, len=7)
|
||||
- POCET (type=16, len=8)
|
||||
- CENA (type=16, len=8)
|
||||
- CENADOPL (type=16, len=8)
|
||||
- POJ (type=14, len=3)
|
||||
- ICZ (type=14, len=8)
|
||||
- ICP (type=14, len=8)
|
||||
- DATUM (type=12, len=4)
|
||||
- REV (type=14, len=1)
|
||||
- TYP (type=7, len=2)
|
||||
- NOT_CENA_PRUMER (type=14, len=1)
|
||||
- VARSYM (type=37, len=20)
|
||||
- SKUPINA (type=14, len=2)
|
||||
|
||||
** HISTDOC_DEF ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- KOD (type=37, len=5)
|
||||
- NAZEV (type=37, len=40)
|
||||
- IDUZI (type=8, len=4)
|
||||
- DATA (type=261, len=8)
|
||||
- SKUPINA (type=8, len=4)
|
||||
|
||||
** HISTDOC_EPOUKAZ ** (řádků: 849)
|
||||
- IDHISTDOC (type=8, len=4)
|
||||
- ID_DOKLADU (type=14, len=9)
|
||||
- IDUZI (type=8, len=4)
|
||||
- IDPRAC (type=8, len=4)
|
||||
- ODESLANO (type=35, len=8)
|
||||
- CHYBA (type=14, len=1)
|
||||
- SCHVALENI (type=14, len=1)
|
||||
- MODIFIED (type=14, len=1)
|
||||
- ODESLANO_LAST (type=35, len=8)
|
||||
- ID_ZP (type=37, len=36)
|
||||
- ID_DOKLADU_VYDEJ (type=37, len=9)
|
||||
- ID_ZP_VYDEJ (type=37, len=36)
|
||||
- VYDANO (type=35, len=8)
|
||||
|
||||
** HISTDOC_EPOUKAZ_ZMENY ** (řádků: 3)
|
||||
- ID_LEKAR (type=37, len=36)
|
||||
- LAST_DATE (type=12, len=4)
|
||||
|
||||
** HISTDOC_EPRILOHY ** (řádků: 17)
|
||||
- ID (type=8, len=4)
|
||||
- IDHISTDOC (type=8, len=4)
|
||||
- NAZEV (type=37, len=255)
|
||||
- POPIS (type=37, len=255)
|
||||
- TYP (type=37, len=7)
|
||||
- SOUBOR (type=261, len=8)
|
||||
- ID_PRILOHY (type=37, len=36)
|
||||
|
||||
** HISTDOC_EZADANKA ** (řádků: 2195)
|
||||
- ID (type=8, len=4)
|
||||
- IDHISTDOC (type=8, len=4)
|
||||
- TYP (type=37, len=10)
|
||||
- DATUMVYS (type=12, len=4)
|
||||
- CASVYS (type=13, len=4)
|
||||
- CISLO (type=37, len=30)
|
||||
- POZNAMKA (type=261, len=8)
|
||||
- HOTOVO (type=14, len=1)
|
||||
- IDZAD (type=8, len=4)
|
||||
- VYSTEXT (type=261, len=8)
|
||||
- DATUMEXP (type=12, len=4)
|
||||
- CASEXP (type=13, len=4)
|
||||
- SABLONY (type=261, len=8)
|
||||
- PRINTED (type=35, len=8)
|
||||
- SENDED (type=35, len=8)
|
||||
- TEMPDAT (type=35, len=8)
|
||||
- SEZNAMMETOD (type=261, len=8)
|
||||
- SEZNAMSABLON (type=261, len=8)
|
||||
- DIAG1 (type=37, len=10)
|
||||
- DIAG2 (type=37, len=10)
|
||||
- DIAG3 (type=37, len=10)
|
||||
- STATIM (type=14, len=1)
|
||||
- ODEBRANO (type=35, len=8)
|
||||
- BEZODBERU (type=14, len=1)
|
||||
- EXPORTOVAT (type=35, len=8)
|
||||
- NAH1 (type=37, len=10)
|
||||
- NAH2 (type=37, len=10)
|
||||
- ODEBRAL (type=37, len=30)
|
||||
- POCETZKUM (type=8, len=4)
|
||||
- OS_NAZEV (type=37, len=100)
|
||||
- OS_ID (type=37, len=20)
|
||||
- PARAMETRY (type=261, len=8)
|
||||
- POZNAMKY (type=261, len=8)
|
||||
- STRINGPARAMETRY (type=261, len=8)
|
||||
- VZOREK1 (type=37, len=25)
|
||||
- VZOREK2 (type=37, len=25)
|
||||
- VZOREK3 (type=37, len=25)
|
||||
- VZOREK4 (type=37, len=25)
|
||||
- PLATCE (type=37, len=30)
|
||||
- OSVOBOZENDPH (type=14, len=1)
|
||||
- PLATCEPOZNAMKA (type=37, len=100)
|
||||
- KATALOGALIAS (type=37, len=20)
|
||||
- KATALOGNAZEV (type=37, len=100)
|
||||
- PRIMARNIVZORKY (type=37, len=256)
|
||||
|
||||
** HISTDOC_SCHVALENI ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- IDHISTDOC (type=8, len=4)
|
||||
- IDVZPARC (type=8, len=4)
|
||||
- PRILOHA (type=261, len=8)
|
||||
- ODESLANO (type=14, len=1)
|
||||
|
||||
** HOSP_ZPRAVY ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- DATUM (type=12, len=4)
|
||||
- CAS (type=13, len=4)
|
||||
- ZPRAVA (type=261, len=8)
|
||||
- IDUZI (type=8, len=4)
|
||||
- IDPAC (type=8, len=4)
|
||||
- ID_EDOKUMENT (type=8, len=4)
|
||||
- IDHOSP (type=8, len=4)
|
||||
|
||||
** IZIPDOC ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- IDPAC (type=8, len=4)
|
||||
- DATUM (type=12, len=4)
|
||||
- STATUS (type=8, len=4)
|
||||
- IDENT (type=8, len=4)
|
||||
- ZAPIS (type=261, len=8)
|
||||
- DEKID (type=8, len=4)
|
||||
- DGN (type=14, len=5)
|
||||
- CAS (type=13, len=4)
|
||||
- IDZAR (type=8, len=4)
|
||||
- IDODD (type=8, len=4)
|
||||
- IDPRAC (type=8, len=4)
|
||||
- AUTOR (type=8, len=4)
|
||||
- LOCKED (type=14, len=1)
|
||||
- TYP (type=14, len=1)
|
||||
- VDGN1 (type=14, len=5)
|
||||
- VDGN2 (type=14, len=5)
|
||||
- VDGN3 (type=14, len=5)
|
||||
- VDGN4 (type=14, len=5)
|
||||
|
||||
** IZIPFILES ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- DOCID (type=8, len=4)
|
||||
- TYP (type=8, len=4)
|
||||
- FILENAME (type=37, len=50)
|
||||
- BODY (type=261, len=8)
|
||||
- DATUM (type=12, len=4)
|
||||
|
||||
** LEKZPRAVY ** (řádků: 13748)
|
||||
- ID (type=8, len=4)
|
||||
- IDPAC (type=8, len=4)
|
||||
- DEKURSID (type=8, len=4)
|
||||
- DATUM (type=12, len=4)
|
||||
- TEXT (type=261, len=8)
|
||||
- IDUZI (type=8, len=4)
|
||||
- IDNOSVYK (type=8, len=4)
|
||||
- TYP (type=14, len=1)
|
||||
- ODESILATEL (type=37, len=254)
|
||||
- DEKURS_COPYED (type=35, len=8)
|
||||
- EISPUBLIC (type=14, len=1)
|
||||
- PRIJEMCE (type=37, len=254)
|
||||
- IDPRAC (type=8, len=4)
|
||||
- SIGNATURE (type=261, len=8)
|
||||
- SIGNATURE_INFO (type=261, len=8)
|
||||
- IDCERTIFICATE (type=8, len=4)
|
||||
- TST (type=261, len=8)
|
||||
- NAZEV (type=37, len=80)
|
||||
- ID_EDOKUMENT (type=8, len=4)
|
||||
- PRIJATO (type=14, len=1)
|
||||
- JMENOLEK (type=37, len=50)
|
||||
- ICP (type=14, len=8)
|
||||
- ES_STAV (type=37, len=1)
|
||||
- PR_TYP (type=14, len=1)
|
||||
- PR_ID (type=8, len=4)
|
||||
- STORNO (type=14, len=1)
|
||||
- UID (type=37, len=16)
|
||||
- PUVODNI (type=8, len=4)
|
||||
- CAS (type=13, len=4)
|
||||
- DATAKT (type=35, len=8)
|
||||
- ODALIAS (type=37, len=8)
|
||||
- PDF (type=261, len=8)
|
||||
- PREPIS (type=8, len=4)
|
||||
- OZNACENI_O (type=37, len=50)
|
||||
- STAV (type=14, len=1)
|
||||
- CLICKBOX_ATT_ID (type=8, len=4)
|
||||
- CGMNUMBER_ODESILATEL (type=37, len=12)
|
||||
- CLICKBOX_MAILBOX (type=37, len=255)
|
||||
- CGMNUMBER_PRIJEMCE (type=37, len=12)
|
||||
- CGMNUMBER (type=37, len=12)
|
||||
|
||||
** LEKZPRAVY_PR ** (řádků: 134)
|
||||
- ID (type=8, len=4)
|
||||
- LEKZPRID (type=8, len=4)
|
||||
- PRID (type=8, len=4)
|
||||
- IDUZI (type=8, len=4)
|
||||
- TYP (type=14, len=1)
|
||||
- EXT (type=14, len=4)
|
||||
|
||||
** LEKZPRAVY_SEND ** (řádků: 0)
|
||||
- LEKZPRID (type=8, len=4)
|
||||
- KDY (type=35, len=8)
|
||||
- KOMU (type=37, len=80)
|
||||
|
||||
** MEDINETIN_ATTACHMENT ** (řádků: 120)
|
||||
- ID (type=8, len=4)
|
||||
- ID_MEDINETIN (type=8, len=4)
|
||||
- FILE_NAME (type=37, len=254)
|
||||
- FILE_EXT (type=37, len=5)
|
||||
- FILE_TYPE (type=8, len=4)
|
||||
- DATA (type=261, len=8)
|
||||
- ID_FILES (type=8, len=4)
|
||||
- ZPRACOVANO (type=14, len=1)
|
||||
|
||||
** MEDINETOUT_ATTACHMENT ** (řádků: 2236)
|
||||
- ID (type=8, len=4)
|
||||
- ID_MEDINETOUT (type=8, len=4)
|
||||
- FILE_ID (type=37, len=36)
|
||||
- FILE_NAME (type=37, len=254)
|
||||
- FILE_EXT (type=37, len=5)
|
||||
- FILE_TYPE (type=8, len=4)
|
||||
- DATA (type=261, len=8)
|
||||
- ATTACH_INT_TYP (type=37, len=1)
|
||||
- ATTACH_INT_ID (type=8, len=4)
|
||||
|
||||
** OSE_ZPRAVY ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- IDPAC (type=8, len=4)
|
||||
- DATUM (type=35, len=8)
|
||||
- UZI (type=37, len=3)
|
||||
- DATA (type=261, len=8)
|
||||
- SIGNATURE (type=261, len=8)
|
||||
- SIGNATURE_INFO (type=261, len=8)
|
||||
- IDCERTIFICATE (type=8, len=4)
|
||||
- STORNO (type=35, len=8)
|
||||
- STORNOBY (type=14, len=3)
|
||||
|
||||
** SOC_FINPRIJEM_HISTDOC ** (řádků: 0)
|
||||
- ID_SFH (type=8, len=4)
|
||||
- ID_SFP (type=8, len=4)
|
||||
- ID_HDC (type=8, len=4)
|
||||
|
||||
** ZPRAVY ** (řádků: 26)
|
||||
- ID (type=8, len=4)
|
||||
- IDZPRAVY (type=8, len=4)
|
||||
- IDOD (type=8, len=4)
|
||||
- IDKOMUZAR (type=8, len=4)
|
||||
- IDKOMUODD (type=8, len=4)
|
||||
- IDKOMUPRAC (type=8, len=4)
|
||||
- IDKOMUUZIV (type=8, len=4)
|
||||
- PREDMET (type=37, len=100)
|
||||
- TEXT (type=261, len=8)
|
||||
- DATUM (type=12, len=4)
|
||||
- CAS (type=13, len=4)
|
||||
- URGENTNI (type=8, len=4)
|
||||
- PRECTENA (type=8, len=4)
|
||||
- DATUMPRECT (type=12, len=4)
|
||||
- CASPRECT (type=13, len=4)
|
||||
- SMAZANA (type=8, len=4)
|
||||
- OZNAMOPRECT (type=8, len=4)
|
||||
- TYP (type=8, len=4)
|
||||
- KOMU (type=261, len=8)
|
||||
- PLATNOST (type=35, len=8)
|
||||
- LZE_ODPOVED (type=14, len=1)
|
||||
- ID_EXT (type=8, len=4)
|
||||
|
||||
** ZPRAVY_ANKETY ** (řádků: 0)
|
||||
- ID (type=8, len=4)
|
||||
- IDUZI (type=8, len=4)
|
||||
- IDPRIJEMCE (type=8, len=4)
|
||||
- ID_EXT (type=8, len=4)
|
||||
- DATA (type=261, len=8)
|
||||
- DATUM (type=12, len=4)
|
||||
- ODESLANO (type=14, len=1)
|
||||
|
||||
** ZPRAVY_EXT ** (řádků: 18)
|
||||
- ID (type=8, len=4)
|
||||
- ID_EXT (type=8, len=4)
|
||||
- ID_ODESILATEL (type=8, len=4)
|
||||
- TYP (type=37, len=1)
|
||||
- PRIORITA (type=37, len=1)
|
||||
- DATUM (type=35, len=8)
|
||||
- PREDMET (type=37, len=254)
|
||||
- DATA (type=261, len=8)
|
||||
- STAV (type=37, len=1)
|
||||
- AKCE (type=37, len=20)
|
||||
- PRIJEMCE (type=37, len=3)
|
||||
- ODESLAL (type=37, len=20)
|
||||
- ODB (type=37, len=3)
|
||||
|
||||
** ZPRAVY_LOCK ** (řádků: 1)
|
||||
- IDUZI (type=8, len=4)
|
||||
- BEGINTIME (type=35, len=8)
|
||||
- ENDTIME (type=35, len=8)
|
||||
114
MedicusWithClaude/funkce.py
Normal file
114
MedicusWithClaude/funkce.py
Normal file
@@ -0,0 +1,114 @@
|
||||
import os,fdb,datetime
|
||||
|
||||
# conn = fdb.connect(
|
||||
# dsn=r'localhost:u:\medicus 3\data\medicus.fdb', # Database path
|
||||
# user='SYSDBA', # Username
|
||||
# password="masterkey", # Password,
|
||||
# charset="win1250")
|
||||
# cur = conn.cursor()
|
||||
|
||||
def zapis_file(vstupconnection,idpac,cesta,souborname,prvnizavorka,soubordate,souborfiledate,poznamka):
|
||||
import funkce
|
||||
cur=vstupconnection.cursor()
|
||||
fileid = funkce.get_files_id(vstupconnection)
|
||||
with open(os.path.join(cesta,souborname), 'rb') as f:
|
||||
daticka = f.read()
|
||||
query = "insert into files (id,iduzi,iddoctyp,typ,idpac,filename,body,datum,datsouboru,poznamka) values(?,?,?,?,?,?,?,?,?,?)"
|
||||
cur.execute(query,(fileid,6,1,1,idpac,prvnizavorka+".pdf",daticka,soubordate,souborfiledate,poznamka[:99]))
|
||||
vstupconnection.commit()
|
||||
return fileid
|
||||
def zapis_dekurs(vstupconnection, idpac, idodd, iduzi, idprac, idfile, filename, text, datumzpravy,
|
||||
datumsouboru):
|
||||
import funkce
|
||||
dekursid = funkce.get_dekurs_id(vstupconnection)
|
||||
cur = vstupconnection.cursor()
|
||||
print("Funkce zapis_dekurs hlasí OK")
|
||||
print("idpac", idpac)
|
||||
print("idodd", idodd)
|
||||
print("iduzi", iduzi)
|
||||
print("idfile", idfile)
|
||||
print("filename", filename)
|
||||
print("text", text)
|
||||
print("datumzpravy", datumzpravy)
|
||||
print("datumsouboru", datumsouboru)
|
||||
print("dekursid", dekursid)
|
||||
|
||||
# rtf = r"""{\rtf1\ansi\ansicpg1250\uc1\deff0\deflang1029{\info{\bookmarks "BOOKMARKNAME","Files:FILEID",9}}{\fonttbl{\f0\fnil\fcharset238 Arial;}{\f5\fnil\fcharset238 Symbol;}}
|
||||
# {\colortbl ;\red0\green0\blue255;\red0\green128\blue0;\red0\green0\blue0;}
|
||||
# {\stylesheet{\s0\fi0\li0\ql\ri0\sb0\sa0 Norm\'e1ln\'ed;}{\*\cs15\f0\fs20 Norm\'e1ln\'ed;}{\*\cs20\f0\i\fs20 Z\'e1hlav\'ed;}{\*\cs32\f0\ul\fs20\cf1 Odkaz;}}
|
||||
# \uc1\pard\s0\plain\cs20\f0\i\fs20 P\'f8\'edlohy: {\*\bkmkstart 0}\plain\cs32\f0\ul\fs20\cf1 BOOKMARKNAME{\*\bkmkend 0}\par
|
||||
# \pard\s0\plain\cs15\f0\fs20 \par
|
||||
# }
|
||||
# """
|
||||
rtf = r"""{\rtf1\ansi\ansicpg1250\uc1\deff0\deflang1029{\info{\bookmarks "BOOKMARKNAME","Files:FILEID",9}}{\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;}{\*\cs22\f0\ul\fs20\cf1 Odkaz;}}
|
||||
\uc1\pard\s10\plain\cs20\f0\i\fs20 P\'f8\'edlohy:\par
|
||||
\pard\s10{\*\bkmkstart 0}\plain\cs22\f0\ul\fs20\cf1 BOOKMARKNAME{\*\bkmkend 0}\par
|
||||
\pard\s10\plain\cs15\f0\fs20 \par
|
||||
}
|
||||
|
||||
"""
|
||||
# id idpac filename body docid typ datum iddoctyp poznamka idpac=2 iduzi=2 datsouboru id_edokument ext_id
|
||||
encodedbookmark = funkce.convert_to1250(filename)
|
||||
print("Encodedbookmark", encodedbookmark)
|
||||
rtf = rtf.replace("BOOKMARKNAME", encodedbookmark)
|
||||
rtf = rtf.replace("FILEID", str(idfile))
|
||||
rtf = rtf.replace("TEXTENTER", text)
|
||||
datumzapisu = datetime.datetime.now().date()
|
||||
caszapisu = datetime.datetime.now().time()
|
||||
print("Datumzapisu", datumzapisu)
|
||||
print("Caszapisu", caszapisu)
|
||||
print("RTF", rtf)
|
||||
cur.execute("insert into dekurs (id,idpac,idodd,iduzi,idprac,datum,cas,dekurs) values(?,?,?,?,?,?,?,?)",
|
||||
(dekursid, idpac, idodd, iduzi, idprac, datumzapisu, caszapisu, rtf))
|
||||
vstupconnection.commit()
|
||||
|
||||
|
||||
def convert_to1250(retezec):
|
||||
retezec=retezec.encode("cp1250")
|
||||
retezec=str(retezec)[2:]
|
||||
retezec = retezec[:-1]
|
||||
retezec=retezec.replace(r"\x",r"\'")
|
||||
return retezec
|
||||
|
||||
|
||||
# x=convert_to1250("Příloha")
|
||||
# print(x,len(x))
|
||||
|
||||
def get_dekurs_id(connection):
|
||||
try:
|
||||
query = "SELECT GEN_ID(Gen_Dekurs, 1) FROM RDB$DATABASE"
|
||||
cur = connection.cursor()
|
||||
cur.execute(query)
|
||||
newid=cur.fetchone()[0]
|
||||
print("Funkce GET_DEKURS_ID přiřadila nové ID:",newid)
|
||||
return(newid)
|
||||
except:
|
||||
print("Funkce GET_DEKURS_ID nepřiřadila nové ID")
|
||||
return(None)
|
||||
|
||||
def get_files_id(connection):
|
||||
try:
|
||||
query = "SELECT GEN_ID(Gen_Files, 1) FROM RDB$DATABASE"
|
||||
cur=connection.cursor()
|
||||
cur.execute(query)
|
||||
newid=cur.fetchone()[0]
|
||||
print(newid)
|
||||
return(newid)
|
||||
except:
|
||||
return(None)
|
||||
|
||||
def get_idpac(rodnecislo,connection):
|
||||
try:
|
||||
query = "SELECT idpac,prijmeni FROM kar where rodcis=?"
|
||||
cur = connection.cursor()
|
||||
cur.execute(query,(rodnecislo,))
|
||||
tmp_nacteno=cur.fetchone()
|
||||
tmp_id = tmp_nacteno[0]
|
||||
tmp_jmeno=tmp_nacteno[1]
|
||||
print(f"Pacient s rodným číslem {rodnecislo} má ID {tmp_id} a jméno {tmp_jmeno}")
|
||||
return (tmp_id)
|
||||
except:
|
||||
return(None)
|
||||
|
||||
184
MedicusWithClaude/funkce_ext.py
Normal file
184
MedicusWithClaude/funkce_ext.py
Normal file
@@ -0,0 +1,184 @@
|
||||
"""funkce_ext.py – zápis PDF souborů přímo do měsíční externí Firebird DB
|
||||
místo do hlavní medicus.fdb – spouštět na Windows
|
||||
|
||||
Náhrada za funkce.zapis_file() v s03soubory.py.
|
||||
Binární data souboru se uloží do MEDICUS_FILES_YYYYMM.fdb (DATA tabulka),
|
||||
do hlavní FILES.BODY se vloží 48bajtová reference.
|
||||
|
||||
Formát FILES.BODY reference (48 B):
|
||||
magic 4 B = b'\\xee\\xbb\\xaa\\x0b'
|
||||
uid 32 B = UUID4 hex (ASCII, 32 znaků)
|
||||
dblen 4 B = délka DBNAME jako little-endian uint32
|
||||
dbname N B = DBNAME ASCII (např. 'DB202603', 8 B)
|
||||
"""
|
||||
|
||||
import os
|
||||
import struct
|
||||
import uuid
|
||||
import fdb
|
||||
|
||||
|
||||
# Magic bajty identifikující referenci na externí DB
|
||||
MAGIC = b'\xee\xbb\xaa\x0b'
|
||||
|
||||
|
||||
# ─── Pomocné funkce ──────────────────────────────────────────────────────────
|
||||
|
||||
def make_body_ref(uid: str, dbname: str) -> bytes:
|
||||
"""Sestaví 48bajtovou binární referenci pro FILES.BODY."""
|
||||
uid_bytes = uid.encode('ascii') # 32 B
|
||||
dbname_bytes = dbname.encode('ascii') # typicky 8 B ('DB202603')
|
||||
return MAGIC + uid_bytes + struct.pack('<I', len(dbname_bytes)) + dbname_bytes
|
||||
|
||||
|
||||
def _get_ext_server(vstupconnection):
|
||||
"""Zjistí SERVER z existující EXTERNI_DB (např. 'localhost/3053')."""
|
||||
cur = vstupconnection.cursor()
|
||||
cur.execute(
|
||||
"SELECT SERVER FROM EXTERNI_DB WHERE DBNAME LIKE 'DB%' ORDER BY DBNAME DESC ROWS 1"
|
||||
)
|
||||
row = cur.fetchone()
|
||||
return row[0] if row else 'localhost/3053'
|
||||
|
||||
|
||||
def _get_ext_heslo(vstupconnection):
|
||||
"""Přečte šifrované heslo z existující EXTERNI_DB.
|
||||
Všechny externí DB mají stejné heslo (masterkey, jen zašifrované Medicusem),
|
||||
takže stačí vzít heslo z libovolné existující položky."""
|
||||
cur = vstupconnection.cursor()
|
||||
cur.execute(
|
||||
"SELECT HESLO FROM EXTERNI_DB WHERE DBNAME LIKE 'DB%' ORDER BY DBNAME DESC ROWS 1"
|
||||
)
|
||||
row = cur.fetchone()
|
||||
return row[0] if row else 'masterkey'
|
||||
|
||||
|
||||
def _vytvor_externi_db(ext_path):
|
||||
"""Vytvoří novou prázdnou externí Firebird DB s tabulkou DATA a generátorem GEN_UID.
|
||||
Schéma odpovídá tomu, co vytváří Medicus sám při prvním exportu daného měsíce."""
|
||||
print(f" Vytvářím novou ext DB: {ext_path}")
|
||||
conn = fdb.create_database(
|
||||
dsn=f'localhost:{ext_path}',
|
||||
user='SYSDBA',
|
||||
password='masterkey',
|
||||
charset='WIN1250',
|
||||
page_size=16384
|
||||
)
|
||||
cur = conn.cursor()
|
||||
cur.execute("""
|
||||
CREATE TABLE DATA (
|
||||
UID VARCHAR(32) NOT NULL,
|
||||
DATA BLOB SUB_TYPE 0,
|
||||
DATASIZE INTEGER,
|
||||
CHUNK INTEGER
|
||||
)
|
||||
""")
|
||||
cur.execute("CREATE GENERATOR GEN_UID")
|
||||
conn.commit()
|
||||
print(f" Nová ext DB vytvořena: {ext_path}")
|
||||
return conn
|
||||
|
||||
|
||||
# ─── Hlavní funkce ───────────────────────────────────────────────────────────
|
||||
|
||||
def zapis_file_ext(vstupconnection, idpac, cesta, souborname, prvnizavorka,
|
||||
soubordate, souborfiledate, poznamka,
|
||||
ext_base_path=r'u:\externi'):
|
||||
"""Zapíše PDF soubor do měsíční externí DB a vrátí fileid.
|
||||
|
||||
Parametry jsou shodné s funkce.zapis_file() – stačí prohodit import.
|
||||
|
||||
Postup:
|
||||
1. Určí měsíc z soubordate → DBNAME (např. 'DB202603')
|
||||
2. Načte binární data PDF
|
||||
3. Najde nebo vytvoří měsíční MEDICUS_FILES_YYYYMM.fdb
|
||||
4. Zapíše data do DATA tabulky pod novým UID (UUID4 hex)
|
||||
5. Sestaví 48bajtovou BODY referenci
|
||||
6. Získá nové FILES ID z Gen_Files
|
||||
7. Vloží záznam do hlavní FILES tabulky (BODY = reference, ne BLOB)
|
||||
8. Vrátí fileid (shodné s funkce.zapis_file())
|
||||
"""
|
||||
import funkce # get_files_id ze stávajícího funkce.py
|
||||
|
||||
# 1. Měsíc a DBNAME
|
||||
yyyymm = soubordate.strftime('%Y%m')
|
||||
dbname = f'DB{yyyymm}'
|
||||
print(f" DBNAME: {dbname}")
|
||||
|
||||
# 2. Binární data PDF
|
||||
soubor_cesta = os.path.join(cesta, souborname)
|
||||
with open(soubor_cesta, 'rb') as f:
|
||||
data = f.read()
|
||||
print(f" Načten soubor: {souborname} ({len(data):,} B)")
|
||||
|
||||
# 3. Připojení k externí DB
|
||||
cur = vstupconnection.cursor()
|
||||
cur.execute(
|
||||
"SELECT SERVER, PATH FROM EXTERNI_DB WHERE DBNAME = ?", (dbname,)
|
||||
)
|
||||
row = cur.fetchone()
|
||||
|
||||
if row:
|
||||
# Existující měsíční DB – připojíme se
|
||||
ext_server_raw, ext_path = row[0], row[1]
|
||||
# SERVER je "localhost/3053" (FBScanner proxy) – bereme jen hostname
|
||||
ext_server = ext_server_raw.split('/')[0]
|
||||
print(f" Existující ext DB: {dbname} → {ext_path}")
|
||||
conn_ext = fdb.connect(
|
||||
dsn=f'{ext_server}:{ext_path}',
|
||||
user='SYSDBA',
|
||||
password='masterkey',
|
||||
charset='WIN1250'
|
||||
)
|
||||
else:
|
||||
# Nová měsíční DB – vytvoříme a zaregistrujeme
|
||||
ext_filename = f'MEDICUS_FILES_{yyyymm}.fdb'
|
||||
ext_path = os.path.join(ext_base_path, ext_filename)
|
||||
conn_ext = _vytvor_externi_db(ext_path)
|
||||
|
||||
# Zaregistrovat do EXTERNI_DB (heslo zkopírujeme z existující položky)
|
||||
ext_server = _get_ext_server(vstupconnection)
|
||||
heslo = _get_ext_heslo(vstupconnection)
|
||||
cur.execute(
|
||||
"INSERT INTO EXTERNI_DB (DBNAME, SERVER, PATH, HESLO) VALUES (?, ?, ?, ?)",
|
||||
(dbname, ext_server, ext_path, heslo)
|
||||
)
|
||||
vstupconnection.commit()
|
||||
print(f" Registrována v EXTERNI_DB: {dbname}, server={ext_server}")
|
||||
|
||||
# 4. Zápis do DATA tabulky
|
||||
uid = uuid.uuid4().hex # 32 hex znaků, vždy unikátní
|
||||
cur_ext = conn_ext.cursor()
|
||||
cur_ext.execute(
|
||||
"INSERT INTO DATA (UID, DATA, DATASIZE, CHUNK) VALUES (?, ?, ?, ?)",
|
||||
(uid, data, len(data), 0)
|
||||
)
|
||||
conn_ext.commit()
|
||||
conn_ext.close()
|
||||
print(f" Zapsáno do ext DB: UID={uid}")
|
||||
|
||||
# 5. BODY reference (48 B)
|
||||
body_ref = make_body_ref(uid, dbname)
|
||||
print(f" BODY ref: {body_ref.hex()}")
|
||||
|
||||
# 6. Nové FILES ID
|
||||
fileid = funkce.get_files_id(vstupconnection)
|
||||
if fileid is None:
|
||||
raise RuntimeError("Nepodařilo se získat nové FILES ID (Gen_Files selhal)!")
|
||||
|
||||
# 7. INSERT do hlavní FILES tabulky
|
||||
cur.execute(
|
||||
"INSERT INTO FILES "
|
||||
"(id, iduzi, iddoctyp, typ, idpac, filename, body, datum, datsouboru, poznamka) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
(fileid, 6, 1, 1, idpac,
|
||||
prvnizavorka + '.pdf',
|
||||
body_ref,
|
||||
soubordate, souborfiledate,
|
||||
poznamka[:99])
|
||||
)
|
||||
vstupconnection.commit()
|
||||
print(f" FILES záznam vytvořen: ID={fileid}, idpac={idpac}, "
|
||||
f"soubor={prvnizavorka}.pdf")
|
||||
|
||||
return fileid
|
||||
16
MedicusWithClaude/medicus_trace.conf
Normal file
16
MedicusWithClaude/medicus_trace.conf
Normal file
@@ -0,0 +1,16 @@
|
||||
# Firebird trace konfigurace – zachytí SQL příkazy Medicusu
|
||||
# Soubor: medicus_trace.conf
|
||||
|
||||
<database c:\\medicus 3\\data\\medicus.fdb>
|
||||
enabled true
|
||||
log_connections false
|
||||
log_transactions false
|
||||
log_statement_prepare false
|
||||
log_statement_start false
|
||||
log_statement_finish true
|
||||
log_procedure_finish false
|
||||
print_plan false
|
||||
print_perf false
|
||||
time_threshold 0
|
||||
max_sql_length 32768
|
||||
</database>
|
||||
BIN
MedicusWithClaude/medicus_trace_output.txt
Normal file
BIN
MedicusWithClaude/medicus_trace_output.txt
Normal file
Binary file not shown.
2764
MedicusWithClaude/precti_log.txt
Normal file
2764
MedicusWithClaude/precti_log.txt
Normal file
File diff suppressed because one or more lines are too long
22
MedicusWithClaude/read_last_dekurs.py
Normal file
22
MedicusWithClaude/read_last_dekurs.py
Normal file
@@ -0,0 +1,22 @@
|
||||
"""read_last_dekurs.py – jednorázový skript: vypíše obsah posledního DEKURS záznamu pro Buzalka"""
|
||||
import fdb
|
||||
|
||||
conn = fdb.connect(
|
||||
dsn=r'localhost:c:\medicus 3\data\medicus.fdb',
|
||||
user='SYSDBA', password='masterkey', charset='win1250'
|
||||
)
|
||||
cur = conn.cursor()
|
||||
|
||||
cur.execute("""
|
||||
SELECT FIRST 1 ID, DATUM, CAS, CHAR_LENGTH(DEKURS), DEKURS
|
||||
FROM DEKURS
|
||||
WHERE IDPAC = 9742
|
||||
ORDER BY ID DESC
|
||||
""")
|
||||
row = cur.fetchone()
|
||||
idek, datum, cas, delka, obsah = row
|
||||
|
||||
print(f"ID={idek} datum={datum} cas={cas} délka={delka} B")
|
||||
print("=" * 60)
|
||||
print(obsah)
|
||||
conn.close()
|
||||
@@ -1,5 +1,5 @@
|
||||
import os,shutil,fdb,time
|
||||
import re,datetime,funkce
|
||||
import re,datetime,funkce,funkce_ext
|
||||
|
||||
# Connect to the Firebird database
|
||||
conn = fdb.connect(
|
||||
@@ -148,12 +148,12 @@ BOOKMARKSTEXT
|
||||
}"""
|
||||
|
||||
for key in skupiny.keys():
|
||||
rtf = r"""{\rtf1\ansi\ansicpg1250\uc1\deff0\deflang1029{\info{\bookmarks BOOKMARKNAMES }}{\fonttbl{\f0\fnil\fcharset238 Arial;}{\f5\fnil\fcharset238 Symbol;}}
|
||||
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;}{\*\cs22\f0\ul\fs20\cf1 Odkaz;}}
|
||||
\uc1\pard\s10\plain\cs20\f0\i\fs20 Vlo\'9eena skenovan\'e1 dokumentace:\par
|
||||
{\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;}}
|
||||
\uc1\pard\s10\plain\cs20\f0\i\fs20 Vlo\'9een\'e9 p\'f8\'edlohy:\par
|
||||
BOOKMARKSTEXT
|
||||
\pard\s10\plain\cs15\f0\fs20\par
|
||||
\pard\s10\plain\cs15\f0\fs20 \par
|
||||
}"""
|
||||
|
||||
|
||||
@@ -169,9 +169,9 @@ BOOKMARKSTEXT
|
||||
# print(row)
|
||||
pacid=row[1]
|
||||
filename=row[6]
|
||||
fileid= funkce.zapis_file(vstupconnection=conn, idpac=row[1],
|
||||
cesta=cesta, souborname=row[6], prvnizavorka=row[4],
|
||||
soubordate=row[2], souborfiledate=row[7], poznamka=row[5])
|
||||
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])
|
||||
|
||||
for attempt in range(3):
|
||||
try:
|
||||
@@ -202,11 +202,8 @@ BOOKMARKSTEXT
|
||||
bookmark=bookmark+'"'+filenameforbookmark+'","Files:'+str(fileid)+'",'+str(cislo)+";"
|
||||
cislo+=7
|
||||
# print(bookmark)
|
||||
if prvnibookmark:
|
||||
bookmarks=bookmarks+r'\pard\s10{\*\bkmkstart '+str(poradi)+r"}\plain\cs22\f0\ul\fs20\cf1 "+filenameforbookmark+r"{\*\bkmkend "+str(poradi)+r"}\par"
|
||||
prvnibookmark=False
|
||||
else:
|
||||
bookmarks=bookmarks+r'\pard\s10{\*\bkmkstart '+str(poradi)+r"}" + filenameforbookmark + r"{\*\bkmkend " + str(poradi) + r"}\par"
|
||||
bookmarks += r'\pard\s10{\*\bkmkstart ' + str(poradi) + r'}\plain\cs32\f0\ul\fs20\cf1 ' + filenameforbookmark + r'{\*\bkmkend ' + str(poradi) + r'}\par'
|
||||
poradi += 1
|
||||
bookmark=bookmark[:-1]
|
||||
# bookmarks=bookmarks[:-2]
|
||||
print(bookmark)
|
||||
108
MedicusWithClaude/s04_presun_externi_db.py
Normal file
108
MedicusWithClaude/s04_presun_externi_db.py
Normal file
@@ -0,0 +1,108 @@
|
||||
"""s04_presun_externi_db.py – Přesun externích DB souborů z u:\ do u:\externi\
|
||||
|
||||
Spustit na Windows s ZAVŘENÝM Medicusem!
|
||||
|
||||
Co dělá:
|
||||
1. Připojí se k hlavní medicus.fdb
|
||||
2. Načte všechny záznamy z EXTERNI_DB
|
||||
3. Pro každý záznam zkopíruje FDB soubor z původní lokace do u:\externi\
|
||||
4. Aktualizuje EXTERNI_DB.PATH na novou lokaci
|
||||
5. Vytiskne přehled výsledků
|
||||
|
||||
Po spuštění zkus v Medicusu otevřít přílohu pacienta – mělo by to fungovat.
|
||||
Pokud ne, zálohuj si databázi a spusť znovu (skript je idempotentní).
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import fdb
|
||||
|
||||
# ── Konfigurace ──────────────────────────────────────────────────────────────
|
||||
MAIN_DB = r'c:\medicus 3\data\medicus.fdb'
|
||||
CÍL_SLOŽKA = r'u:\externi'
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
def main():
|
||||
os.makedirs(CÍL_SLOŽKA, exist_ok=True)
|
||||
print(f"Cílová složka: {CÍL_SLOŽKA}")
|
||||
print()
|
||||
|
||||
print("Připojuji se k hlavní DB...")
|
||||
conn = fdb.connect(
|
||||
dsn=f'localhost:{MAIN_DB}',
|
||||
user='SYSDBA',
|
||||
password='masterkey',
|
||||
charset='WIN1250'
|
||||
)
|
||||
cur = conn.cursor()
|
||||
|
||||
# Načti všechny záznamy z EXTERNI_DB
|
||||
cur.execute("SELECT DBNAME, SERVER, PATH, HESLO FROM EXTERNI_DB ORDER BY DBNAME")
|
||||
zaznamy = cur.fetchall()
|
||||
print(f"Nalezeno {len(zaznamy)} záznamů v EXTERNI_DB:")
|
||||
print()
|
||||
|
||||
ok = 0
|
||||
preskoceno = 0
|
||||
chyba = 0
|
||||
|
||||
for dbname, server, path_puvodni, heslo in zaznamy:
|
||||
print(f" [{dbname}] {path_puvodni}")
|
||||
|
||||
# Název souboru (jen basename, bez cesty)
|
||||
basename = os.path.basename(path_puvodni)
|
||||
# Normalize: Medicus někdy ukládá s malým .fdb, někdy velkým .FDB
|
||||
path_cil = os.path.join(CÍL_SLOŽKA, basename)
|
||||
|
||||
# Zkontroluj, jestli zdrojový soubor existuje
|
||||
# (zkus obě varianty přípony)
|
||||
path_src = None
|
||||
for kandidat in [path_puvodni,
|
||||
path_puvodni.replace('.fdb', '.FDB'),
|
||||
path_puvodni.replace('.FDB', '.fdb')]:
|
||||
if os.path.isfile(kandidat):
|
||||
path_src = kandidat
|
||||
break
|
||||
|
||||
if path_src is None:
|
||||
print(f" ⚠ ZDROJOVÝ SOUBOR NENALEZEN: {path_puvodni} – přeskakuji")
|
||||
chyba += 1
|
||||
continue
|
||||
|
||||
# Pokud je soubor už v cíli, přeskoč kopírování
|
||||
if os.path.isfile(path_cil):
|
||||
velikost = os.path.getsize(path_cil)
|
||||
print(f" → Soubor již existuje v cíli ({velikost:,} B), přeskakuji kopírování")
|
||||
else:
|
||||
velikost = os.path.getsize(path_src)
|
||||
print(f" → Kopíruji ({velikost:,} B)...", end=' ', flush=True)
|
||||
shutil.copy2(path_src, path_cil)
|
||||
print("OK")
|
||||
|
||||
# Aktualizuj PATH v EXTERNI_DB pokud se liší
|
||||
if path_puvodni != path_cil:
|
||||
cur.execute(
|
||||
"UPDATE EXTERNI_DB SET PATH = ? WHERE DBNAME = ?",
|
||||
(path_cil, dbname)
|
||||
)
|
||||
print(f" → EXTERNI_DB.PATH aktualizováno: {path_cil}")
|
||||
else:
|
||||
print(f" → PATH již ukazuje na cíl, není třeba měnit")
|
||||
preskoceno += 1
|
||||
|
||||
ok += 1
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
print()
|
||||
print("=" * 60)
|
||||
print(f"Hotovo! Zpracováno: {ok}, přeskočeno: {preskoceno}, chyb: {chyba}")
|
||||
print()
|
||||
if chyba > 0:
|
||||
print("⚠ Některé soubory nebyly nalezeny – viz výpis výše.")
|
||||
print(" Pokud jsou to staré DB které již neexistují, nevadí to.")
|
||||
print("Nyní spusť Medicus a zkus otevřít přílohu pacienta.")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
4202
MedicusWithClaude/scanneroutput.txt
Normal file
4202
MedicusWithClaude/scanneroutput.txt
Normal file
File diff suppressed because it is too large
Load Diff
53
MedicusWithClaude/test_ext_db.py
Normal file
53
MedicusWithClaude/test_ext_db.py
Normal file
@@ -0,0 +1,53 @@
|
||||
"""Test připojení k externí DB a prozkoumání její struktury - spusť na Windows"""
|
||||
import fdb, os, glob
|
||||
|
||||
# Najde první existující externí FDB soubor
|
||||
soubory = glob.glob(r'u:\MEDICUS_FILES_*.fdb')
|
||||
if not soubory:
|
||||
soubory = glob.glob(r'u:\externi\MEDICUS_FILES_*.fdb')
|
||||
|
||||
if not soubory:
|
||||
print("Žádné externí FDB soubory nenalezeny!")
|
||||
exit()
|
||||
|
||||
soubor = sorted(soubory)[-1] # vezme nejnovější
|
||||
print(f"Zkouším: {soubor}")
|
||||
|
||||
# Test 1: masterkey
|
||||
try:
|
||||
conn = fdb.connect(dsn=f'localhost:{soubor}', user='SYSDBA', password='masterkey', charset='win1250')
|
||||
print("✓ Připojení s masterkey FUNGUJE!")
|
||||
|
||||
cur = conn.cursor()
|
||||
|
||||
# Jaké tabulky jsou v externí DB?
|
||||
cur.execute("SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$SYSTEM_FLAG=0 AND RDB$VIEW_BLR IS NULL")
|
||||
tabulky = [r[0].strip() for r in cur.fetchall()]
|
||||
print(f"Tabulky v externí DB: {tabulky}")
|
||||
|
||||
# Kolik záznamů v FILES?
|
||||
if 'FILES' in tabulky:
|
||||
cur.execute("SELECT COUNT(*), MIN(ID), MAX(ID) FROM FILES")
|
||||
row = cur.fetchone()
|
||||
print(f"FILES: {row[0]} záznamů, ID od {row[1]} do {row[2]}")
|
||||
|
||||
cur.execute("SELECT ID, IDPAC, FILENAME, DATUM, OCTET_LENGTH(BODY) FROM FILES ORDER BY ID ROWS 3")
|
||||
for r in cur.fetchall():
|
||||
print(f" ID={r[0]} IDPAC={r[1]} FILE={r[2]} DATUM={r[3]} BODY={r[4]}B")
|
||||
|
||||
# Zjistit generátor
|
||||
cur.execute("SELECT RDB$GENERATOR_NAME, RDB$GENERATOR_ID FROM RDB$GENERATORS WHERE RDB$SYSTEM_FLAG=0")
|
||||
for r in cur.fetchall():
|
||||
print(f"Generátor: {r[0].strip()} = {r[1]}")
|
||||
|
||||
conn.close()
|
||||
except Exception as e:
|
||||
print(f"✗ masterkey NEFUNGUJE: {e}")
|
||||
|
||||
# Test s jiným heslem - zkus prázdné
|
||||
try:
|
||||
conn = fdb.connect(dsn=f'localhost:{soubor}', user='SYSDBA', password='', charset='win1250')
|
||||
print("✓ Připojení s prázdným heslem FUNGUJE!")
|
||||
conn.close()
|
||||
except Exception as e2:
|
||||
print(f"✗ Prázdné heslo také nefunguje: {e2}")
|
||||
46
MedicusWithClaude/test_ext_db2.py
Normal file
46
MedicusWithClaude/test_ext_db2.py
Normal file
@@ -0,0 +1,46 @@
|
||||
"""Prozkoumá strukturu tabulky DATA v externí DB - spusť na Windows"""
|
||||
import fdb, glob
|
||||
|
||||
soubory = glob.glob(r'u:\MEDICUS_FILES_*.fdb') + glob.glob(r'u:\MEDICUS_FILES_*.FDB')
|
||||
if not soubory:
|
||||
soubory = glob.glob(r'u:\externi\MEDICUS_FILES_*.fdb') + glob.glob(r'u:\externi\MEDICUS_FILES_*.FDB')
|
||||
|
||||
soubor = sorted(soubory)[-1]
|
||||
print(f"Soubor: {soubor}\n")
|
||||
|
||||
conn = fdb.connect(dsn=f'localhost:{soubor}', user='SYSDBA', password='masterkey', charset='win1250')
|
||||
cur = conn.cursor()
|
||||
|
||||
# Sloupce tabulky DATA
|
||||
print("=== Sloupce tabulky DATA ===")
|
||||
cur.execute("""
|
||||
SELECT r.RDB$FIELD_NAME, f.RDB$FIELD_TYPE, f.RDB$FIELD_LENGTH, f.RDB$SEGMENT_LENGTH
|
||||
FROM RDB$RELATION_FIELDS r
|
||||
JOIN RDB$FIELDS f ON f.RDB$FIELD_NAME = r.RDB$FIELD_SOURCE
|
||||
WHERE r.RDB$RELATION_NAME = 'DATA'
|
||||
ORDER BY r.RDB$FIELD_POSITION
|
||||
""")
|
||||
for row in cur.fetchall():
|
||||
typ = {7:'SMALLINT',8:'INTEGER',12:'DATE',13:'TIME',14:'CHAR',16:'INT64',35:'TIMESTAMP',37:'VARCHAR',261:'BLOB'}.get(row[1], str(row[1]))
|
||||
print(f" {row[0].strip():30} {typ} len={row[2]}")
|
||||
|
||||
# Generátory
|
||||
print("\n=== Generátory ===")
|
||||
cur.execute("SELECT RDB$GENERATOR_NAME, RDB$GENERATOR_ID FROM RDB$GENERATORS WHERE RDB$SYSTEM_FLAG=0")
|
||||
for row in cur.fetchall():
|
||||
print(f" {row[0].strip()} = {row[1]}")
|
||||
|
||||
# Počet záznamů a ukázka
|
||||
print("\n=== Počet záznamů ===")
|
||||
cur.execute("SELECT COUNT(*) FROM DATA")
|
||||
print(f" {cur.fetchone()[0]} záznamů")
|
||||
|
||||
print("\n=== Ukázka 3 záznamů (bez BLOB) ===")
|
||||
cur.execute("""
|
||||
SELECT ID, OCTET_LENGTH(BODY) as VELIKOST
|
||||
FROM DATA ORDER BY ID ROWS 3
|
||||
""")
|
||||
for row in cur.fetchall():
|
||||
print(f" ID={row[0]} BODY={row[1]}B")
|
||||
|
||||
conn.close()
|
||||
47
MedicusWithClaude/test_ext_db3.py
Normal file
47
MedicusWithClaude/test_ext_db3.py
Normal file
@@ -0,0 +1,47 @@
|
||||
"""Zjistí propojení mezi hlavní DB a externí DB - spusť na Windows"""
|
||||
import fdb, glob
|
||||
|
||||
# Hlavní DB
|
||||
conn_main = fdb.connect(dsn=r'localhost:c:\medicus 3\data\medicus.fdb',
|
||||
user='SYSDBA', password='masterkey', charset='win1250')
|
||||
cur = conn_main.cursor()
|
||||
|
||||
# Najít exportované záznamy v FILES (BODY není velký BLOB)
|
||||
print("=== FILES záznamy po exportu (malý BODY = reference na externí DB) ===")
|
||||
cur.execute("""
|
||||
SELECT ID, IDPAC, FILENAME, DATUM, EXT_ID, DOCID,
|
||||
OCTET_LENGTH(BODY) as BODY_LEN,
|
||||
CAST(BODY AS VARCHAR(100)) as BODY_TEXT
|
||||
FROM FILES
|
||||
WHERE OCTET_LENGTH(BODY) < 100
|
||||
ORDER BY ID DESC ROWS 5
|
||||
""")
|
||||
for r in cur.fetchall():
|
||||
print(f" ID={r[0]} IDPAC={r[1]} FILE={r[2]}")
|
||||
print(f" DATUM={r[3]} EXT_ID={r[4]} DOCID={r[5]}")
|
||||
print(f" BODY_LEN={r[6]} BODY_TEXT='{r[7]}'")
|
||||
|
||||
# Ukázka záznamu s plným BODY (ještě ne exportovaný)
|
||||
print("\n=== FILES záznamy PŘED exportem (velký BODY = binary data) ===")
|
||||
cur.execute("""
|
||||
SELECT ID, FILENAME, DATUM, EXT_ID, OCTET_LENGTH(BODY) as BODY_LEN
|
||||
FROM FILES
|
||||
WHERE OCTET_LENGTH(BODY) > 1000
|
||||
ORDER BY ID DESC ROWS 3
|
||||
""")
|
||||
for r in cur.fetchall():
|
||||
print(f" ID={r[0]} FILE={r[1]} DATUM={r[2]} EXT_ID={r[3]} BODY={r[4]}B")
|
||||
|
||||
conn_main.close()
|
||||
|
||||
# Porovnat s externí DB
|
||||
print("\n=== DATA záznamy v externí DB ===")
|
||||
soubory = glob.glob(r'u:\MEDICUS_FILES_*.fdb') + glob.glob(r'u:\MEDICUS_FILES_*.FDB')
|
||||
soubor = sorted(soubory)[0] # vezmeme nejstarší
|
||||
print(f"Soubor: {soubor}")
|
||||
conn_ext = fdb.connect(dsn=f'localhost:{soubor}', user='SYSDBA', password='masterkey', charset='win1250')
|
||||
cur_ext = conn_ext.cursor()
|
||||
cur_ext.execute("SELECT UID, DATASIZE, CHUNK FROM DATA ORDER BY CHUNK ROWS 5")
|
||||
for r in cur_ext.fetchall():
|
||||
print(f" UID='{r[0]}' DATASIZE={r[1]} CHUNK={r[2]}")
|
||||
conn_ext.close()
|
||||
20
MedicusWithClaude/test_ext_db4.py
Normal file
20
MedicusWithClaude/test_ext_db4.py
Normal file
@@ -0,0 +1,20 @@
|
||||
"""Čte přesné bajty BODY z exportovaného záznamu FILES - spusť na Windows"""
|
||||
import fdb
|
||||
|
||||
conn = fdb.connect(dsn=r'localhost:c:\medicus 3\data\medicus.fdb',
|
||||
user='SYSDBA', password='masterkey', charset='win1250')
|
||||
cur = conn.cursor()
|
||||
|
||||
# Vezmi jeden exportovaný záznam
|
||||
cur.execute("SELECT ID, BODY FROM FILES WHERE ID = 10487")
|
||||
row = cur.fetchone()
|
||||
fileid = row[0]
|
||||
body_bytes = row[1] # fdb vrací BLOB jako bytes přímo
|
||||
|
||||
print(f"FILE ID: {fileid}")
|
||||
print(f"BODY délka: {len(body_bytes)} bajtů")
|
||||
print(f"BODY hex: {body_bytes.hex()}")
|
||||
print(f"BODY repr: {repr(body_bytes)}")
|
||||
print(f"BODY jako string (latin1): {body_bytes.decode('latin1')}")
|
||||
|
||||
conn.close()
|
||||
108
MedicusWithClaude/test_import_3files.py
Normal file
108
MedicusWithClaude/test_import_3files.py
Normal file
@@ -0,0 +1,108 @@
|
||||
"""test_import_3files.py – jednorázový test: 3 soubory jednoho pacienta → 1 dekurs s klikacími odkazy
|
||||
Testuje opravenou RTF logiku (cs32, Přílohy: inline, poradi++)
|
||||
Spustit na Windows.
|
||||
"""
|
||||
import datetime
|
||||
import os
|
||||
import fdb
|
||||
import funkce
|
||||
import funkce_ext
|
||||
|
||||
CESTA = r'u:\\'
|
||||
IDPAC = 9742 # Buzalka Vladimír, RC 7309208104
|
||||
|
||||
SOUBORY = [
|
||||
{
|
||||
'souborname': '7309208104 2026-03-18 Buzalka, Vladimír [vyšetření] [ahoj Claude copy1].pdf',
|
||||
'prvnizavorka': 'vyšetření',
|
||||
'druhazavorka': 'ahoj Claude copy1',
|
||||
'datum': datetime.date(2026, 3, 18),
|
||||
},
|
||||
{
|
||||
'souborname': '7309208104 2026-03-18 Buzalka, Vladimír [vyšetření] [ahoj Claude copy2].pdf',
|
||||
'prvnizavorka': 'vyšetření',
|
||||
'druhazavorka': 'ahoj Claude copy2',
|
||||
'datum': datetime.date(2026, 3, 18),
|
||||
},
|
||||
{
|
||||
'souborname': '7309208104 2026-03-18 Buzalka, Vladimír [vyšetření] [ahoj Claude].pdf',
|
||||
'prvnizavorka': 'vyšetření',
|
||||
'druhazavorka': 'ahoj Claude',
|
||||
'datum': datetime.date(2026, 3, 18),
|
||||
},
|
||||
]
|
||||
|
||||
# ── Připojení ─────────────────────────────────────────────────────────────────
|
||||
conn = fdb.connect(
|
||||
dsn=r'localhost:c:\medicus 3\data\medicus.fdb',
|
||||
user='SYSDBA', password='masterkey', charset='WIN1250'
|
||||
)
|
||||
|
||||
# ── Krok 1: vložit každý soubor do ext DB ─────────────────────────────────────
|
||||
bookmark = ''
|
||||
bookmarks = ''
|
||||
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}")
|
||||
|
||||
# {\info{\bookmarks ...}} sekce
|
||||
filenameforbookmark = s['datum'].strftime('%Y-%m-%d') + ' ' + s['prvnizavorka'] + ': ' + s['druhazavorka']
|
||||
bookmark += '"' + filenameforbookmark + '","Files:' + str(fileid) + '",' + str(cislo) + ';'
|
||||
cislo += 7
|
||||
|
||||
# tělo RTF – klikatelné záložky (cs32, všechny stejný formát)
|
||||
bookmarks += (r'\pard\s10{\*\bkmkstart ' + str(poradi) + r'}'
|
||||
r'\plain\cs32\f0\ul\fs20\cf1 ' + filenameforbookmark +
|
||||
r'{\*\bkmkend ' + str(poradi) + r'}\par')
|
||||
poradi += 1
|
||||
|
||||
bookmark = bookmark[:-1] # odstranit poslední ;
|
||||
|
||||
# ── Krok 2: sestavit RTF ──────────────────────────────────────────────────────
|
||||
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;}}
|
||||
\uc1\pard\s10\plain\cs20\f0\i\fs20 Vlo\'9een\'e9 p\'f8\'edlohy:\par
|
||||
BOOKMARKSTEXT
|
||||
\pard\s10\plain\cs15\f0\fs20 \par
|
||||
}"""
|
||||
|
||||
rtf = rtf.replace('BOOKMARKNAMES', bookmark)
|
||||
rtf = rtf.replace('BOOKMARKSTEXT', bookmarks)
|
||||
|
||||
print('\n=== Výsledný RTF ===')
|
||||
print(rtf)
|
||||
|
||||
# ── Krok 3: zapsat dekurs ─────────────────────────────────────────────────────
|
||||
dekursid = funkce.get_dekurs_id(conn)
|
||||
datumzapisu = datetime.datetime.now().date()
|
||||
caszapisu = datetime.datetime.now().time()
|
||||
|
||||
cur = conn.cursor()
|
||||
cur.execute(
|
||||
"INSERT INTO DEKURS (id, iduzi, idprac, idodd, idpac, datum, cas, dekurs)"
|
||||
" VALUES (?,?,?,?,?,?,?,?)",
|
||||
(dekursid, 6, 2, 2, IDPAC, datumzapisu, caszapisu, rtf)
|
||||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
print(f'\n=== HOTOVO ===')
|
||||
print(f'DEKURS.ID = {dekursid}')
|
||||
print('Otevři Medicus → karta Buzalka Vladimír → najdi dnešní záznam → klikej na odkazy!')
|
||||
47
MedicusWithClaude/test_import_april2026.py
Normal file
47
MedicusWithClaude/test_import_april2026.py
Normal file
@@ -0,0 +1,47 @@
|
||||
"""test_import_april2026.py – jednorázový testovací import do DB202604
|
||||
|
||||
Spustit na Windows (Medicus může být spuštěný, jen ne na kartě tohoto pacienta).
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import fdb
|
||||
import funkce_ext
|
||||
|
||||
SOUBOR_CESTA = r'u:\\'
|
||||
SOUBOR_NAZEV = '7309208104 Buzalka, Vladimír 2026-04-01 [testovaci zprava] [všechno OK].pdf'
|
||||
|
||||
IDPAC = 9742 # Buzalka Vladimír (RC 7309208104)
|
||||
PRVNI_ZAVORKA = 'testovaci zprava'
|
||||
POZNAMKA = 'všechno OK'
|
||||
DATUM_ZPRAVY = datetime.date(2026, 4, 1)
|
||||
DATUM_SOUBORU = datetime.datetime.fromtimestamp(
|
||||
os.path.getmtime(os.path.join(SOUBOR_CESTA, SOUBOR_NAZEV)))
|
||||
|
||||
print(f"Soubor: {os.path.join(SOUBOR_CESTA, SOUBOR_NAZEV)}")
|
||||
print(f"Datum zprávy: {DATUM_ZPRAVY}")
|
||||
print(f"Datum souboru:{DATUM_SOUBORU}")
|
||||
print()
|
||||
|
||||
conn = fdb.connect(
|
||||
dsn=r'localhost:c:\medicus 3\data\medicus.fdb',
|
||||
user='SYSDBA',
|
||||
password='masterkey',
|
||||
charset='WIN1250'
|
||||
)
|
||||
|
||||
fileid = funkce_ext.zapis_file_ext(
|
||||
vstupconnection=conn,
|
||||
idpac=IDPAC,
|
||||
cesta=SOUBOR_CESTA,
|
||||
souborname=SOUBOR_NAZEV,
|
||||
prvnizavorka=PRVNI_ZAVORKA,
|
||||
soubordate=DATUM_ZPRAVY,
|
||||
souborfiledate=DATUM_SOUBORU,
|
||||
poznamka=POZNAMKA,
|
||||
)
|
||||
|
||||
conn.close()
|
||||
print()
|
||||
print(f"Hotovo! FILES.ID = {fileid}")
|
||||
print("Otevři Medicus, přejdi na kartu Buzalka Vladimír a zkontroluj záložku Soubory.")
|
||||
182
MedicusWithClaude/test_import_merge.py
Normal file
182
MedicusWithClaude/test_import_merge.py
Normal file
@@ -0,0 +1,182 @@
|
||||
"""test_import_merge.py – vloží přílohy do dekurzu daného dne.
|
||||
Pokud dekurs pro daný den existuje → vloží přílohy NAHORU před stávající text.
|
||||
Pokud neexistuje → vytvoří nový dekurs.
|
||||
Spustit na Windows.
|
||||
"""
|
||||
import datetime, os, re, fdb
|
||||
import funkce, funkce_ext
|
||||
|
||||
CESTA = r'u:\\'
|
||||
IDPAC = 9742 # Buzalka Vladimír
|
||||
DATUM = datetime.date(2026, 3, 18)
|
||||
|
||||
SOUBORY = [
|
||||
{'souborname': '7309208104 2026-03-18 Buzalka, Vladimír [vyšetření] [ahoj Claude copy1].pdf',
|
||||
'prvnizavorka': 'vyšetření', 'druhazavorka': 'ahoj Claude copy1', 'datum': DATUM},
|
||||
{'souborname': '7309208104 2026-03-18 Buzalka, Vladimír [vyšetření] [ahoj Claude copy2].pdf',
|
||||
'prvnizavorka': 'vyšetření', 'druhazavorka': 'ahoj Claude copy2', 'datum': DATUM},
|
||||
{'souborname': '7309208104 2026-03-18 Buzalka, Vladimír [vyšetření] [ahoj Claude].pdf',
|
||||
'prvnizavorka': 'vyšetření', 'druhazavorka': 'ahoj Claude', 'datum': DATUM},
|
||||
]
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
def najdi_posledni_dekurs_dnes(conn, idpac, datum_vlozeni):
|
||||
"""Najde POSLEDNÍ dekurs pacienta (jakýkoli datum) a vrátí (id, rtf)
|
||||
pouze pokud je ze stejného dne jako datum_vlozeni. Jinak vrátí None.
|
||||
|
||||
Logika: zajímá nás jen poslední zápis – pokud je z dnešního dne,
|
||||
vložíme přílohy do něj. Pokud je starší, zakládáme nový dnešní záznam.
|
||||
"""
|
||||
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" → shoduje se s dneškem ({datum_vlozeni}), budeme mergovat")
|
||||
return (dekurs_id, dekurs_rtf)
|
||||
else:
|
||||
print(f" → jiný den ({dekurs_datum} ≠ {datum_vlozeni}), vytvoříme nový")
|
||||
return None
|
||||
|
||||
|
||||
def merge_rtf_prepend(existing_rtf, new_bkm_list, new_body_pards, n_new):
|
||||
"""Vloží nový obsah (přílohy) na ZAČÁTEK stávajícího dekurzu.
|
||||
|
||||
existing_rtf – stávající RTF string z DB
|
||||
new_bkm_list – list stringů typu '"popis","Files:123",9'
|
||||
new_body_pards – RTF string: header \par + \pard řádky s odkazy
|
||||
n_new – počet nových bkmkstart indexů (= počet souborů)
|
||||
"""
|
||||
rtf = existing_rtf
|
||||
|
||||
# 1. Posunout stávající bkmkstart/bkmkend indexy o n_new,
|
||||
# aby nedošlo ke kolizi s našimi novými (0, 1, 2 …)
|
||||
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)
|
||||
|
||||
# 2. Přidat naše bookmarky na ZAČÁTEK {\info{\bookmarks ...}}
|
||||
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:
|
||||
# žádný {\info} blok – vložíme za \deflang...
|
||||
rtf = re.sub(r'(\\deflang\d+)',
|
||||
r'\1{\\info{\\bookmarks ' + new_bkm_str + '}}', rtf, count=1)
|
||||
|
||||
# 3. Vložit naše tělo před první \uc1\pard těla stávajícího dekurzu
|
||||
match = re.search(r'\\uc1\\pard', rtf)
|
||||
if match:
|
||||
pos = rtf.index(r'\uc1\pard', match.start())
|
||||
rtf = rtf[:pos] + new_body_pards + '\n' + rtf[pos:]
|
||||
else:
|
||||
# fallback – připojit před poslední }
|
||||
rtf = rtf.rstrip()
|
||||
if rtf.endswith('}'):
|
||||
rtf = rtf[:-1] + new_body_pards + '\n}'
|
||||
|
||||
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
|
||||
|
||||
# Tělo přílohy (záhlaví + odkaz řádky + prázdný řádek)
|
||||
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: existující dekurs pro tento den? ──────────────────────────────────
|
||||
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
|
||||
print(f"\n>>> Nalezen existující dekurs pro {DATUM}: ID={dekurs_id}")
|
||||
print(">>> Vkládám přílohy na začátek...")
|
||||
|
||||
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:
|
||||
print(f"\n>>> Žádný dekurs pro {DATUM} nenalezen – 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!")
|
||||
238
MedicusWithClaude/test_import_single.py
Normal file
238
MedicusWithClaude/test_import_single.py
Normal file
@@ -0,0 +1,238 @@
|
||||
"""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!")
|
||||
Reference in New Issue
Block a user