Compare commits

5 Commits

Author SHA1 Message Date
michaela.buzalkova 9001e1b70e Merge remote-tracking branch 'origin/master' 2026-04-25 08:27:39 +02:00
michaela.buzalkova 598a376000 lenovo 2026-04-25 08:27:31 +02:00
michaela.buzalkova 772a09ee7d Merge remote-tracking branch 'origin/master' 2026-04-11 08:55:19 +02:00
michaela.buzalkova 0b85a736db Merge remote-tracking branch 'origin/master' 2026-04-01 06:08:07 +02:00
michaela.buzalkova d2cc34f6dc lenovo 2026-03-29 08:51:01 +02:00
3 changed files with 52 additions and 11 deletions
+34
View File
@@ -7,6 +7,7 @@
- **2026-03-17**: Obnovena session Claude si přečetl poznámky, připraven pokračovat - **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. - **2026-03-18**: Obnovena session Claude si přečetl poznámky, připraven pokračovat. Průběžně zapisuje do tohoto souboru.
- **2026-03-20**: Obnovena session merge logika z `test_import_single.py` integrována do `s03soubory.py`. Import pipeline kompletní. - **2026-03-20**: Obnovena session merge logika z `test_import_single.py` integrována do `s03soubory.py`. Import pipeline kompletní.
- **2026-04-01**: Opravena chyba `BlobReader invalid BLOB handle` v `dekurz_report.py` viz níže.
## Bezpečnost ## Bezpečnost
- Pracujeme na **místní kopii** poškození DB nevadí, obnova = 5 minut - Pracujeme na **místní kopii** poškození DB nevadí, obnova = 5 minut
@@ -356,6 +357,39 @@ Správný RTF formát klikacího odkazu:
- `test_import_merge.py` ✅ otestováno merge 3 souborů (jen 2 případy, bez detekce sekce) - `test_import_merge.py` ✅ otestováno merge 3 souborů (jen 2 případy, bez detekce sekce)
- `test_import_single.py` ✅ otestováno všechny 3 případy, základ pro s03soubory.py - `test_import_single.py` ✅ otestováno všechny 3 případy, základ pro s03soubory.py
## Oprava BlobReader v dekurz_report.py (2026-04-01)
### Chyba
```
Exception ignored while calling deallocator <function BlobReader.__del__>:
fdb.fbcore.DatabaseError: BlobReader.close/isc_close_blob: invalid BLOB handle (-901)
```
Skript fungoval správně (exit code 0, Excel uložen), ale garbage collector házel warningy.
### Příčina
`fdb` vrací BLOB sloupce jako `BlobReader` objekty. Po `conn.close()` se při GC pokoušely
zavřít handle, který již neexistoval.
### Oprava
Explicitně zavřít `BlobReader` hned po `.read()`, ještě za živa spojení:
```python
# PŘED (špatně):
rtf = dekurs_blob.read() if hasattr(dekurs_blob, 'read') else (dekurs_blob or '')
# PO (správně):
if hasattr(dekurs_blob, 'read'):
rtf = dekurs_blob.read()
dekurs_blob.close()
else:
rtf = dekurs_blob or ''
```
### Obecné pravidlo
Kdykoli čteme BLOB z fdb, vždy `.close()` po `.read()` jinak GC po `conn.close()` hlásí chybu.
---
## Další postup (nápady) ## Další postup (nápady)
- Otestovat `s03soubory.py` na Windows se skutečnými soubory (všechny 3 případy) - Otestovat `s03soubory.py` na Windows se skutečnými soubory (všechny 3 případy)
- Napsat `rtf_to_text()` pro extrakci čistého textu z dekurzů - Napsat `rtf_to_text()` pro extrakci čistého textu z dekurzů
+10 -5
View File
@@ -5,15 +5,16 @@ import fdb
import openpyxl import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
VYSTUPNI_ADRESAR = r'u:\Dropbox\Ordinace\Reporty' VYSTUPNI_ADRESAR = r'z:\Dropbox\Ordinace\Reporty'
NAZEV_REPORTU = 'Dekurzy' NAZEV_REPORTU = 'Dekurzy'
DATUM_OD = '2025-01-01' DATUM_OD = '2025-01-01'
DATUM_DO = date.today().strftime('%Y-%m-%d') DATUM_DO = date.today().strftime('%Y-%m-%d')
conn = fdb.connect( conn = fdb.connect(
dsn=r'localhost:c:\medicus 3\data\medicus.fdb', host='192.168.1.10', database=r'm:\MEDICUS\data\medicus.FDB',
user='SYSDBA', password='masterkey', charset='win1250' user='sysdba', password='masterkey',charset='WIN1250')
)
cur = conn.cursor() cur = conn.cursor()
cur.execute(f""" cur.execute(f"""
@@ -56,7 +57,11 @@ def rtf_na_text(rtf):
# Parse dekurzů # Parse dekurzů
rows = [] rows = []
for datum, cas, zkratka, prijmeni, jmeno, rodcis, poj, dekurs_blob in raw_rows: for datum, cas, zkratka, prijmeni, jmeno, rodcis, poj, dekurs_blob in raw_rows:
rtf = dekurs_blob.read() if hasattr(dekurs_blob, 'read') else (dekurs_blob or '') if hasattr(dekurs_blob, 'read'):
rtf = dekurs_blob.read()
dekurs_blob.close()
else:
rtf = dekurs_blob or ''
pocty = {} pocty = {}
ids_by_typ = {t: [] for t in TOP_TYPY} ids_by_typ = {t: [] for t in TOP_TYPY}
ids_ostatni = [] ids_ostatni = []
+8 -6
View File
@@ -1,4 +1,4 @@
import fdb import firebirdsql as fdb
import openpyxl import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment from openpyxl.styles import Font, PatternFill, Alignment
from openpyxl.utils import get_column_letter from openpyxl.utils import get_column_letter
@@ -8,20 +8,22 @@ import sys
# --- Připojení --- # --- Připojení ---
conn = fdb.connect( conn = fdb.connect(
dsn=r'localhost:c:\medicus 3\data\medicus.fdb', host='192.168.1.10',
user='SYSDBA', password='masterkey', charset='win1250' port=3050,
database=r'm:\Medicus\data\MEDICUS.FDB',
user='SYSDBA', password='masterkey', charset='WIN1250'
) )
cur = conn.cursor() cur = conn.cursor()
# --- Výstupní soubor --- # --- Výstupní soubor ---
output_dir = r'u:\Dropbox\!!!Days\Downloads Z230' output_dir = r'z:\Dropbox\Ordinace\Reporty'
now = datetime.now() now = datetime.now()
filename = now.strftime('%Y-%m-%d_%H-%M-%S') + '_faktury.xlsx' filename = now.strftime('%Y-%m-%d %H-%M-%S') + ' faktury.xlsx'
output_path = os.path.join(output_dir, filename) output_path = os.path.join(output_dir, filename)
# --- Smazání předchozích verzí --- # --- Smazání předchozích verzí ---
for f in os.listdir(output_dir): for f in os.listdir(output_dir):
if f.endswith('_faktury.xlsx'): if f.endswith(' faktury.xlsx'):
os.remove(os.path.join(output_dir, f)) os.remove(os.path.join(output_dir, f))
wb = openpyxl.Workbook() wb = openpyxl.Workbook()