README popisovalo stav před v2.1.1 a chyběla v něm celá jedna entita.
- Doplněny samostatné nálezy (PAS) včetně vlastní atributové tabulky,
filtry podle data a "Pouze projektové akce".
- Filtry rozepsány do matice dostupnosti podle entity — dosud byly
uvedené jako jeden společný seznam, což neplatí ani pro Organizaci,
ani pro PIAN – přesnost a Areál.
- Doplněno CRS výstupních vrstev (EPSG:5514), které chybělo úplně.
- Doplněno, že hesláře vznikají i z facet Digiarchivu (f_vedouci,
f_nalezce), nejen z OAI-PMH.
- Upozornění, že PIAN – přesnost je jediný předvyplněný filtr, takže
nedotčený dialog už záznamy lokalizované katastrem vynechává.
- Opraveno tvrzení "developed using the PyQt6 framework": kód importuje
přes qgis.PyQt, což je právě důvod, proč běží na Qt5 i Qt6.
- Nová sekce Development s tabulkou CI jobů a příkazy pro lokální běh.
Popisky filtrů odpovídají stavu na main. Jejich sjednocení ("Materiál",
pomlčka u stavu dochování) jde samostatně do version/v2.2.0, takže se
dokumentace nedostane před kód.
Anglická terminologie převzata ze slovníku Digiarchivu
(api/assets/i18n/en.json), ne z nápovědy — ta o PAS ani datových
filtrech nic neví. Matice filtrů ověřena výpisem dialogu v headless
QGIS, názvy polí a aliasy porovnány skriptem proti amcr_tools.py
(43 názvů a 43 aliasů, všechny doslova sedí).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GptqiE8kzeUUsx6h9apwiP
Workflow code_quality.yml pouští při každém PR a při pushi do main
kontroly, které se dosud dělaly ručně, ve čtyřech jobech:
- Lint a bezpečnost: check_sources.py, bandit, detect-secrets, flake8,
ruff. Bandit a detect-secrets jsou tytéž kontroly, které blokují
schválení na plugins.qgis.org.
- Kompatibilita s Qt6: pyqgis4-checker v dockeru. Skript končí kódem 0,
i když něco najde, výsledek je jen v logu; job proto ověřuje, že log
obsahuje pouze hlavičku.
- Smoke test: smoke_test.py v qgis/qgis:ltr (3.44, Qt5) i
qgis/qgis:stable (4.x, Qt6). Tagy se posouvají schválně, aby bylo
vidět, že plugin drží krok s aktuálním QGISem.
- Balíček pluginu: sestaví amcr_viewer.zip stejně jako release
workflow, ověří, že v něm je metadata.txt, __init__.py i .flake8
a nejsou v něm git soubory, a přiloží ho jako artefakt běhu.
Recenzent ho nainstaluje přes Install from ZIP bez ručního balení.
detect-secrets se pouští s --all-files. Bez toho prohledá jen soubory
sledované gitem a o nesledovaném souboru mlčí, což vypadá jako čistý
výsledek.
Verze nástrojů jsou napevno. Bez pinu by se výsledek měnil s každým
vydáním ruffu, které rozšíří výchozí sadu pravidel.
CodeQL a GitGuardian běží zvlášť, nastavené na úrovni organizace,
a schválně se tu neduplikují.
AGENTS.md popisuje, jak totéž pustit lokálně, a tři místa, kde kontroly
tiše lžou (výstupní kód pyqgis4-checkeru, detect-secrets bez
--all-files, umístění config souborů pro scanner).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WhQyc1uQFcpkezLwM8if6T
tests/check_sources.py hlídá pravidla, která nepotřebují QGIS a jejichž
porušení je tiché:
- UTF-8 BOM na začátku .py souboru. Pythonu ani QGISu nevadí, ale
oficiální pyqgis4-checker na něm spadne a soubor vůbec nezkontroluje,
takže rozbitý soubor vypadá čistě. Stalo se tady už dvakrát.
- přímý import z PyQt5/PyQt6 mimo shim qgis.PyQt
- spustitelná práva, skryté soubory a podezřelé typy souborů, které
hlásí analýza souborů na plugins.qgis.org
tests/smoke_test.py načte plugin ve skutečném QGIS, přečte scoped
enumy, vytvoří UpdateCodelistsTask a všechny tři filtrační dialogy
a ověří doplňování hraničního data. Běží offline a bez X serveru
(QT_QPA_PLATFORM=offscreen), takže nezávisí na dostupnosti API.
Očekávaná hodnota filtru je v testu napsaná natvrdo, ne přes
DATE_OPEN_TO. Porovnání proti konstantě z modulu dokazuje jen to, že se
modul shodne sám se sebou, a prošlo i s rozbitým sentinelem.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WhQyc1uQFcpkezLwM8if6T
Bez explicitní konfigurace se výsledek lintů mění sám od sebe: výchozí
sada pravidel ruffu se liší verzi od verze a flake8 hlásí generovaný
resources.py, který se ručně neformátuje.
Konfigurace je rozdělená schválně. amcr_viewer/.flake8 leží vedle
metadata.txt, protože scanner na plugins.qgis.org hledá config soubory
jen v kořeni balíčku uvnitř ZIPu; stejná pravidla tak platí v CI,
lokálně i při uploadu. Konfigurace ruffu je v kořenovém pyproject.toml,
ruff se do balíčku pluginu nedistribuuje.
Ignorovaná pravidla mají v pyproject.toml odůvodnění: UP009 (hlavička
utf-8 je konvence šablony Plugin Builderu), BLE001 (except Exception je
záměr, výjimka nesmí propadnout do QGISu), SIM103 a SIM105 (čitelnost).
Dvě opravy, které z konfigurace plynou:
- open(path, 'r', encoding=...) -> open(path, encoding=...) [UP015]
- zbytečné else: po return v get_komponenty() [RET505]
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WhQyc1uQFcpkezLwM8if6T
Commit 9aba283 vrátil UTF-8 BOM do amcr_dialog.py a amcr_tools.py –
patrně ho doplnil editor při uložení. Oficiální pyqgis4-checker na nich
kvůli tomu znovu padal na SyntaxError, tedy přesně to, co d398d2c
opravoval.
Zároveň zalomen sloučený import z qgis.core v amcr_dialog.py, který měl
87 znaků.
Bez změny chování. Kontroly, které pouští plugins.qgis.org (flake8),
plus ruff.
flake8: odstraněny koncové bílé znaky, srovnány nadbytečné prázdné řádky
a zalomeno 12 řádků přes 79 znaků. Hlášku o HTTP chybě v login_to_api()
si nešlo jen zalomit – tělo odpovědi je nově v proměnné `telo`, výsledný
text je stejný.
ruff: odstraněny zbytečné prefixy u'' u překládaných řetězců (6×),
.format() nahrazen f-stringem, str() uvnitř f-stringu převedeno na !s,
`k in dict.keys()` na `k in dict`, prázdný komentář; nepoužitá rozbalená
proměnná `existing_cfg` nahrazena `_`.
Vědomě neřešeno:
- resources.py (5 zbylých nálezů flake8) je generovaný výstup pyrcc,
nese hlavičku "All changes made in this file will be lost", není nikde
importovaný a v repu k němu chybí zdrojový .qrc.
- ruff BLE001 (10×) hlásí `except Exception`. Ty jsou v pluginu záměrné:
drží pád mimo QGIS a chybu ukážou v liště zpráv. Změna by byla zásah
do chování, ne úklid.
- ruff SIM103 (2×) navrhuje sloučit strážní podmínky do jednoho výrazu.
Obě místa mají ke každé větvi vysvětlující komentář, sloučením by se
staly hůř čitelnými.
- ruff UP009 a I001 (coding hlavička a řazení importů) jsou celoprojektová
konvence; jejich změna patří do samostatného rozhodnutí, ne sem.
Ověřeno v QGIS 3.44.13 (Qt5) i QGIS 4.2.1 (Qt6): importy, vytvoření tasku
i všechny tři filtrační dialogy fungují shodně. Bandit, detect-secrets
i pyqgis4-checker hlásí nula nálezů.
Oficiální kontrola pyqgis4-checker (skript pyqt5_to_pyqt6.py z QGISu)
hlásila u pluginu 13 nekompatibilit a tři soubory vůbec nepřečetla.
Odstraněn UTF-8 BOM z amcr_codelists.py, amcr_dialog.py a amcr_tools.py.
Checker čte zdroják jako UTF-8 bez utf-8-sig a na BOM padá na
SyntaxError: invalid non-printable character U+FEFF, takže se ty soubory
nezkontrolovaly vůbec. Pythonu při běhu BOM nevadí, proto to nikdy
nevyskočilo. heslar.csv si BOM ponechává, tam je kvůli Excelu.
Enumy převedeny na plně kvalifikované tvary (13 míst):
Qgis.{Info,Warning,Critical} -> Qgis.MessageLevel.*,
QgsTask.CanCancel -> QgsTask.Flag.CanCancel,
QgsWkbTypes.*Geometry -> QgsWkbTypes.GeometryType.*Geometry.
Zkrácené tvary v QGIS 4.2.1 zatím fungují, ale kontrola je vytýká
a aliasy do budoucna mizí. Zbytek kódu už scoped tvary používal.
Do AGENTS.md doplněna sekce o kompatibilitě s Qt6 / QGIS 4 se závaznými
pravidly a příkazy na ověření.
Ověřeno spuštěním v QGIS 3.44.13 (Qt 5.15.18) i QGIS 4.2.1 (Qt 6.10.3):
importy, vytvoření tasku i všechny tři filtrační dialogy fungují shodně.
Log pyqgis4-checkeru je nově prázdný.
Shrnuje změny sloučené do této větve oproti main: projektové akce (#53), úklid kódu (#54), stahování samostatných nálezů (#57), diagnostiku prázdných výsledků z API (#58) a filtrování podle data se scrollovatelným dialogem (#59).
* fix: scrollovatelný filtrační dialog
Obsah dialogu přesahoval okno u všech tří typů dat – u akcí zabíral
přes 1280 px v okně vysokém 750 px, takže spodní filtry i tlačítka
byly nedostupné.
Filtry se nově scrollují. Tlačítka OK / Aktualizovat hesláře / Cancel
zůstávají mimo scrollovanou oblast, aby se kvůli potvrzení dialogu
nemuselo scrollovat na konec seznamu.
* feat: filtrování záznamů podle data
Přidává filtr na datum zahájení a ukončení u akcí a na datum nálezu
u samostatných nálezů (#56). Lokalita filtr nedostává – v jejím indexu
žádné datumové pole není, takže by šlo o ovládací prvek bez účinku.
API vyžaduje obě meze intervalu: jednostranný rozsah shodí server na
ArrayIndexOutOfBoundsException a hvězdičku nepřijímá. Prázdné pole se
proto nahrazuje zarážkou 0001-01-01 / 9999-12-31, což jsou shodou
okolností i výchozí meze QgsDateEdit. Blok s oběma poli prázdnými
neposílá do dotazu nic.
Obrácené rozmezí vrací API jako nula záznamů bez chybové hlášky, což
je k nerozeznání od skutečně prázdného výsledku – dialog ho proto
odmítne už při potvrzení a vypíše, kterých filtrů se to týká.
- logování odeslané URL a chyb z těla odpovědi v _api_get_json
- výpis filtrů z dialogu před zahájením stahování
- rozlišení chyby API od prázdného výsledku (api_error)
- dávky geometrií PIAN hlásí chybějící blok 'response'
API vrací chyby s HTTP 200 a klíčem 'error' místo bloku 'response'; resp_json.get('response', {}) z toho udělal prázdný výsledek, takže neplatný parametr, prázdné okno mapy i chyba serveru končily stejnou hláškou "Žádné záznamy nenalezeny".
* feature: dialog: přidána nová pole
přidána pole samostatných nálezů pro filtrovací dialog + upravena viditelnost některých spolčných polí (např. skrýt areál, zobrazit organizaci nejen pro akce, ale i pro PAS, ...)
* feature: tlačítko v menu
v kontextové nabídce přibylo tlačítko pro filtrování PASových záznamů; ikona je zatím placeholder
* feature: rozšíření slovníčku
slovníček interních vs api klíčů byl rozšířen o nová pole (nálezce, okolnosti, ...) a zároveň byla změněna jeho struktura: nově obsahuje i base url vzhledem k tomu, že si skript pro data sahá do dvou různých API; přidáno base url pro digiarchiv
* feature: update funkcí pro stahování dat
funkce fetch_set a download_heslare byly upraveny pro stahování dat nejen z OAI-PMH API, ale nově i z API digiarchivu (= osoby se nově nestahují z hesláře osob, ale z facetek digiarchivu, kde mají osoby přidělené "role" nálezce/vedoucí)
* feature: globals pro PAS
založeny nové heslářové globals, pak přidány do funkce refresh_globals
* feature: nové heslářové globals + cache v dialogu
* feature: aktualizace hesláře
* fix: oprava typ_dat = "pas" na typ_dat = "samostatny_nalez"
* feature: dynamičtjší způsob interpretace typu dat
- archeologicky_zaznam nově čerpá human-readable název pro název vrstvy v typ_dat_vocab
- archeologicky_zaznam_l pro ověřování, jestli je současný typ_dat akce nebo lokalita
* feature (wip): první krůčky logiky pro parsování PAS záznamů
- dosavadní logika parsování platná pro akce a lokality je podmíněna typ_dat
- stub logiky parsování pro samostatné nálezy
* feature: čtení dat z JSON payload
získávání sn-specific dat, jako je nálezce, hloubka nálezu, ale i vlastní wkt, které není závislé na PIANu
* feature: párovací slovník metadat pro samostatné nálezy
* fix: Přístupnost přidána do hesláře aliasů
* fix: oprava chyb z dialogu znemožňujících stahování SN
* fix: předávání filtrů k samostatným nálezům z dialogu do "tools" skriptu
* feat: drobné změny
- escapování názvů vrstev (podtržítko místo mezery)
- `actions_with_geom` -> `entries_with_geom`
- čitelný `typ_dat` pro PAS: `PAS` -> `Samostatný nález`
* feat: dokončení smyčky na ukládání metadat k SN z docs
* feat: plnění vrstvy daty SN
* feat: update ikon pro samostatné nálezy a login
* feature/projektove-akce: do dialogu akce přidán checkbox pro filtrování projektových akcí + backend logika
* feature/projektove-akce: do atributové tabulky akcí přidáno pole Projekt (prázdné, pokud nejde o projektovou akci)
Opravy chyb a optimalizace napříč pluginem
Souhrn revize celého kódu pluginu:
- Opravy pádů: chybějící locale při startu QGIS; životní cyklus
úlohy aktualizace heslářů (GC reference, zákaz souběhu, message
boxy nad hlavním oknem).
- Datová korektnost: transformace fallback geometrií WGS-84 do
S-JTSK, oprava nevalidních polygonů přes makeValid(), normalizace
hodnot pian_presnost/pian_typ, heslář přístupnosti bez záznamů
s kódem None, ošetření null hodnot u komponent.
- Přihlašování a stahování: ověření údajů před uložením do správce
autentizace, zřetelné hlášení síťových chyb a neúplných výsledků,
jedno parsování JSON odpovědí, úspornější stránkování, guard proti
souběžným stahováním, logování do QgsMessageLog.
- Metadata a CI: oprava ikony pluginu, akce ve workflow povýšeny na
aktuální verze a připnuty na commit hash, poznámka o závislosti
na requests v README.
Otestováno ručně v QGIS dle checklistu v PR (včetně hraničních
případů: výpadek sítě, expirovaná session, špatné heslo, zrušení
úlohy, prázdné výsledky, limit záznamů).
* vyměnit xml.etree.ElementTree za defusedxml.ElementTree
* zpátky xml.etree.ElementTree, ale přidáno # nosec; jde o false positive
* switch z ukládání hesel v registrech na používání QGIS Auth Manager
* přidáno nové tlačítko do toolbaru
* přihlašovací dialog
* funkce pro přihlašování
* aplikace získávání dat z API přes session
* zastřešující akce v main skriptu
* ošetření prodlužování session/opětovné přihlášení
* přidání přístupnosti do hesláře
* aktualizace přibaleného hesláře
* oprava stahování hesláře (pristupnost vyžaduje písmeno [A/B/C/D], ne heslo; aktualizace hesláře
* aplikace přístupnosti do filtračního dialogu
* úpravy přihlašovacího dialogu
* čištění amcr_tools.py od zbytečných prvků souvisejících se standalone tabulkou komponent
* aplikace nové logiky přípravy dat v případě požadavku na komponenty
* nové aliasy + přidání dat komponent do finálních tabulek
* oprava pořadí polí v tabulce
* přechod od statického hesláře k dynamickému načítání z OAI-PMH API AMČR
* aplikace načítání heslářů a task management (backend)
* frontend + debugging
* aktualizace přibaleného hesláře
* kosmetické drobnosti
* ošetření speciální případů při stahování hesláře (katastr, okres) + s tím spojená aktualizace přiloženého hesláře
Comprehensive update to improve plugin efficiency and code quality:
- Performance: Increased BATCH_PIAN to 200 and optimized attribute parsing loops.
- Performance: Optimized codelist caching to reload only necessary data.
- UI/UX: Fixed plugin unloading (toolbar icon duplication) and added safe cursor handling.
- Refactoring: Moved GUI helper methods to class level for better OOP structure.
- Modernization: Updated dialog execution syntax to modern PyQt5/6 standards.
- Documentation: Added full inline English documentation across all modules.