7ed2cca15f
2 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
19e5fe4691 |
Phase J: SN EDAS-XML-Adapter (#26/#38) — Sachsen aktiv via XML-Export
Reaktiviert die in Phase J vertagte Adapter-Implementation: statt
ASP.NET-Postbacks zu simulieren (blockt durch __VIEWSTATE-Komplexität
plus robots.txt: Disallow: /), liest die neue ``SNEdasXmlAdapter``-
Klasse einen wöchentlich manuell aus EDAS exportierten XML-Dump.
Workflow:
1. User exportiert in der EDAS-Suchmaske mit Filter "Dokumententyp =
Antr" einen XML-Dump (bis zu 2500 Treffer/Export, sortiert
newest-first nach Datum)
2. Datei wird unter ``data/sn-edas-export.xml`` abgelegt (ins
persistent volume des prod-containers)
3. ``search()``/``get_document()`` lesen die XML-Datei lokal — keine
Server-Calls gegen edas.landtag.sachsen.de
4. ``download_text()`` resolved die echte PDF-URL on-demand über einen
einzelnen GET gegen ``viewer_navigation.aspx`` (single GET, kein
Postback) und holt dann das PDF von ``ws.landtag.sachsen.de/images``
XML-Schema (ISO-8859-1):
- ``<ID>`` interne EDAS-Doc-ID
- ``<Wahlperiode>``, ``<Dokumentenart>``, ``<Dokumentennummer>``
- ``<Fundstelle>`` z.B. ``"Antr CDU, BSW, SPD 01.10.2024 Drs 8/2"`` —
enthält Typ, Urheber und Datum, parsen via Regex
- ``<Titel>`` Volltext-Titel
PDF-URL-Schema (extrahiert aus dem viewer_navigation.aspx onLoad-
Handler): ``ws.landtag.sachsen.de/images/{wp}_Drs_{nr}_{...}.pdf``
mit variablen Suffix-Komponenten — wir machen die Resolution lazy.
Mapper-Erweiterung:
- ``parteien.PARTEIEN``-Tabelle um ``BÜNDNISGRÜNE``/``Bündnisgrüne``
ergänzt — der Sachsen-spezifische zusammengeschriebene Eigenname der
GRÜNEN-Fraktion (sonst wären 8/2100 etc. mit leerer Fraktionen-Liste
rausgekommen)
BL-Eintrag:
- ``SN.aktiv = True``
- ``doku_system="EDAS-XML-Export"`` (klare Klassifikation, dass es
KEIN normaler Webcrawler ist)
- Test ``test_sn_is_eigensystem_not_parldok`` umbenannt in
``test_sn_uses_xml_export_not_parldok``
Live-Probe lokal:
```
search('Klima', limit=5):
8/2100 2025-03-17 | [GRÜNE] | Fahrradoffensive Sachsen ...
7/192 2019-10-11 | [LINKE] | Erste Schritte zur Klimager...
7/2067 2020-03-19 | [CDU, SPD, GRÜNE] | Sächsische Waldbesitzer ...
```
176 Unit-Tests grün. Container braucht beim Deploy einen XML-Upload
ins data/-Volume — separater scp-Schritt.
Refs: #26, #38, #59 (Phase J revived)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
eb045d0ed3 |
Phase B: Parteinamen-Mapper #55 (Roadmap #59)
Zentrale `app/parteien.py` als Single Source of Truth für die Partei- Auflösung: - `PARTEIEN`-Tabelle mit kanonischem Key, langem Display-Namen, allen bekannten Aliasen, optionalem `bundesland_scope` und Government- Marker. 14 Einträge (CDU, CSU, SPD, GRÜNE, FDP, LINKE, AfD, BSW, SSW, BiW + die Freie-Wähler-Familie BVB-FW, FW-BAYERN, FW-SL und der generische FREIE WÄHLER-Eintrag). - `normalize_partei(raw, *, bundesland=None)` für Single-String-Lookups mit Government-Vorrang und FW-Familien-Disambiguierung - `extract_fraktionen(text, *, bundesland=None)` als Funnel für die vier alten Adapter-Helper. Kommagetrennte Listen, MdL-mit-Klammer- partei, HTML-Reste — alles fließt durch eine Stelle, mit BL-Scope- Filter (SSW nur in SH, BVB-FW nur in BB, etc.). - `display_name(canonical, *, long=False)` für UI/PDF — kurze Form bleibt der kanonische Key, lange Form ist "BÜNDNIS 90/DIE GRÜNEN" statt "GRÜNE" etc. Adapter-Migration in `app/parlamente.py`: - Vier nahezu identische `_normalize_fraktion()`-Methoden in PortalaAdapter, ParLDokAdapter, StarFinderCGIAdapter, PARLISAdapter durch einen einzeiligen Shim ersetzt, der `extract_fraktionen` mit `self.bundesland` aufruft. ~120 Zeilen Duplikation entfernt. - `@staticmethod` aufgehoben, weil wir jetzt `self.bundesland` brauchen für die FW-Disambiguierung — alle Aufrufer waren bereits `self._...`, also keine Call-Site-Änderung nötig. `app/embeddings.py:496` Workaround-Hack entfernt: - `partei.upper() if partei != "GRÜNE" else "GRÜNE"` durch zentralen `normalize_partei()`-Aufruf ersetzt — der Hack war ein Kommentarzeichen dafür, dass die Partei-Schreibweise irgendwo zwischen Adapter und Embedding-Lookup driften konnte. Mit dem Mapper ist die Schreibweise überall garantiert kanonisch. Tests: - Neue `tests/test_parteien.py` mit 52 Cases — Single-Lookup, FW- Disambiguierung (BVB/Bayern/Saarland/RP), Volltext-Extraktion, Government-Marker, Tabellen-Konsistenz - `tests/test_parlamente.py` Test-Klasse umgeschrieben: statt der 6 statischen `PortalaAdapter._normalize_fraktion(...)`-Tests jetzt 4 Roundtrip-Tests über echte Adapter-Instanzen, inkl. expliziter BB→BVB-FW vs. RP→FREIE WÄHLER-Verifikation 157 Unit-Tests grün (105 alt + 52 neu). Backwards-kompatibel — die kanonischen Keys sind exakt die in der DB stehenden Strings, kein Migrations-Schritt nötig. Refs: #55, #59 (Phase B) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |