# -*- coding: utf-8 -*- """ Roztřídí DASTA XML soubory do adresářové struktury podle DATA ODBĚRU. Zdroj: u:\\Dropbox\\Ordinace\\pomoc\\DASTA\\*.xml Cíl: U:\\DASTA_SUBGROUPS\\RRRR\\MM\\DD\\.xml (kopie, originál zůstává) Datum odběru = první element v souboru (první potomek prvního ). Hodnota má formát DTS (2016-06-20T08:00:00) nebo DT (2017-05-18T07:30) – v obou případech začíná YYYY-MM-DD, takže rok/měsíc/den čteme z prvních znaků. Speciální případy: _BEZ_DATUMU soubor neobsahuje žádný _CHYBY soubor se nepodařilo naparsovat Použití: python roztrid_dle_odberu.py # zdroj = výchozí (Dropbox) python roztrid_dle_odberu.py U:\\DASTA # jiný zdrojový adresář python roztrid_dle_odberu.py U:\\DASTA --dry-run # jen vypíše, co by udělal """ from __future__ import annotations import re import shutil import sys from collections import Counter from pathlib import Path from xml.etree import ElementTree as ET ZDROJ_VYCHOZI = Path(r"u:\dasta") CIL = Path(r"U:\DASTA_SUBGROUPS") # Záchytný regex pro případ, že ElementTree selže (poškozená hlavička apod.) _RE_DAT_DU = re.compile(rb"]*>\s*(\d{4})-(\d{2})-(\d{2})") def datum_odberu(cesta: Path) -> tuple[str, str, str] | None: """Vrátí (rok, měsíc, den) z prvního , nebo None když chybí.""" raw = cesta.read_bytes() # Rychlá a robustní cesta: najdi první v bytech. m = _RE_DAT_DU.search(raw) if m: return m.group(1).decode(), m.group(2).decode(), m.group(3).decode() # Záloha přes ElementTree (kdyby byl dat_du formátovaný jinak) try: root = ET.fromstring(raw) el = root.find(".//dat_du") if el is not None and el.text: d = el.text.strip() return d[0:4], d[5:7], d[8:10] except ET.ParseError: raise return None def main() -> None: dry = "--dry-run" in sys.argv pozicni = [a for a in sys.argv[1:] if not a.startswith("--")] zdroj = Path(pozicni[0]) if pozicni else ZDROJ_VYCHOZI soubory = sorted(zdroj.glob("*.xml")) print(f"Zdroj: {zdroj}") print(f"Cíl: {CIL}") print(f"Nalezeno souborů: {len(soubory)}" f"{' [DRY-RUN]' if dry else ''}") print("-" * 60) if not dry: CIL.mkdir(parents=True, exist_ok=True) stat = Counter() roky = Counter() chyby: list[str] = [] for src in soubory: try: d = datum_odberu(src) except ET.ParseError as e: d = None cilovy_dir = CIL / "_CHYBY" chyby.append(f"{src.name}: parse error – {e}") stat["chyba"] += 1 else: if d is None: cilovy_dir = CIL / "_BEZ_DATUMU" stat["bez_datumu"] += 1 else: rok, mes, den = d cilovy_dir = CIL / rok / mes / den stat["ok"] += 1 roky[rok] += 1 dst = cilovy_dir / src.name if dry: continue cilovy_dir.mkdir(parents=True, exist_ok=True) shutil.copy2(src, dst) print("Hotovo:") print(f" zařazeno dle data odběru : {stat['ok']}") print(f" bez data (_BEZ_DATUMU) : {stat['bez_datumu']}") print(f" chyby parsování (_CHYBY) : {stat['chyba']}") if roky: print("\nRozložení podle roku:") for rok in sorted(roky): print(f" {rok}: {roky[rok]}") if chyby: print("\nDetail chyb:") for c in chyby: print(f" {c}") if __name__ == "__main__": main()