2026-04-28 08:37:31 +02:00
|
|
|
"""BL-uebergreifende Plenarprotokoll-Abstimmungsparser (#126).
|
|
|
|
|
|
|
|
|
|
Architektur (vgl. ADR 0009): pro Bundesland eine Modul-Datei
|
|
|
|
|
``app/protokoll_parsers/<bl-code>.py``, die mindestens eine Funktion
|
|
|
|
|
``parse_protocol(pdf_path: str) -> list[dict]`` exportiert. Die Registry
|
|
|
|
|
``PROTOKOLL_PARSERS`` mappt BL-Code → Parser-Funktion.
|
|
|
|
|
|
|
|
|
|
Erwartetes Result-Schema pro Eintrag in der Liste::
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
"drucksache": str | None, # z.B. "18/1234"; None bei nicht aufloesbar
|
|
|
|
|
"ergebnis": str, # angenommen | abgelehnt | ueberwiesen | ...
|
|
|
|
|
"einstimmig": bool, # explizit als einstimmig markiert
|
|
|
|
|
"kind": str, # parser-intern, fuer Debug
|
|
|
|
|
"votes": { # fraktions-Listen pro Vote-Kategorie
|
|
|
|
|
"ja": list[str],
|
|
|
|
|
"nein": list[str],
|
|
|
|
|
"enthaltung": list[str],
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NRW ist die Referenz-Implementierung. Folge-BL (HE/BB/MV/BE/...) bekommen
|
|
|
|
|
eigene Module mit demselben Funktions-Vertrag — neue Eintraege in der
|
|
|
|
|
Registry sind reine Tippelarbeit, das Reverse-Engineering pro Landtag
|
|
|
|
|
ist die eigentliche Arbeit.
|
|
|
|
|
"""
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from typing import Callable
|
|
|
|
|
|
|
|
|
|
from .nrw import parse_protocol as _parse_nrw
|
2026-04-28 23:21:39 +02:00
|
|
|
from .bund import parse_protocol as _parse_bund
|
feat(#150): BE-Parser produktiv — Berliner Abgeordnetenhaus-Plenarprotokolle
Dritter vollwertiger Plenarprotokoll-Parser nach NRW + BUND.
URL-Pattern verifiziert (WP19 Sitzungen 1, 10, 50, 80, 100):
https://www.parlament-berlin.de/ados/{wp}/IIIPlen/protokoll/plen{wp}-{n:03}-pp.pdf
Anchor-Sprache (NRW-aehnlich, mit Berliner-Eigenheit 'pro forma'):
Wer den Antrag auf Drucksache 19/X annehmen moechte, ... – Das sind
die Fraktionen Buendnis 90/Die Gruenen und Die Linke.
Wer stimmt dagegen? – Das sind die Fraktionen der CDU, SPD und AfD.
Wer enthaelt sich, pro forma? – Das ist niemand.
Damit ist der Antrag abgelehnt.
Pattern:
- Result-Anchor: Damit ist [Antrag/Aenderungsantrag/Gesetzentwurf/...]
(angenommen|abgelehnt)
- Vote-Block: 3 Q+A-Paare im Reden-Stil (annehmen moechte / dagegen /
enthaelt sich)
- Drucksachen-Lookup: 'Drucksache 19/N(-suffix)' rueckwaerts (1500-char Fenster)
Fraktions-Mapping WP19:
- Buendnis 90/Die Gruenen → GRÜNE
- Die Linke → LINKE
- CDU, SPD, AfD, FDP
21 Tests in test_protokoll_parsers_be.py.
Cron-PROTO_TARGETS erweitert um BE WP19 (~80 Sitzungen).
Stub-Test angepasst.
905 Tests gruen (889 → 905, +16 fuer BE).
2026-04-29 00:37:47 +02:00
|
|
|
from .be import parse_protocol as _parse_be
|
2026-04-29 00:57:58 +02:00
|
|
|
from .hh import parse_protocol as _parse_hh
|
2026-04-28 08:37:31 +02:00
|
|
|
|
|
|
|
|
# Typ-Alias fuer Lesbarkeit; Parser-Signatur ist bewusst minimal.
|
|
|
|
|
ProtokollParser = Callable[[str], list[dict]]
|
|
|
|
|
|
|
|
|
|
PROTOKOLL_PARSERS: dict[str, ProtokollParser] = {
|
|
|
|
|
"NRW": _parse_nrw,
|
2026-04-28 23:21:39 +02:00
|
|
|
"BUND": _parse_bund,
|
feat(#150): BE-Parser produktiv — Berliner Abgeordnetenhaus-Plenarprotokolle
Dritter vollwertiger Plenarprotokoll-Parser nach NRW + BUND.
URL-Pattern verifiziert (WP19 Sitzungen 1, 10, 50, 80, 100):
https://www.parlament-berlin.de/ados/{wp}/IIIPlen/protokoll/plen{wp}-{n:03}-pp.pdf
Anchor-Sprache (NRW-aehnlich, mit Berliner-Eigenheit 'pro forma'):
Wer den Antrag auf Drucksache 19/X annehmen moechte, ... – Das sind
die Fraktionen Buendnis 90/Die Gruenen und Die Linke.
Wer stimmt dagegen? – Das sind die Fraktionen der CDU, SPD und AfD.
Wer enthaelt sich, pro forma? – Das ist niemand.
Damit ist der Antrag abgelehnt.
Pattern:
- Result-Anchor: Damit ist [Antrag/Aenderungsantrag/Gesetzentwurf/...]
(angenommen|abgelehnt)
- Vote-Block: 3 Q+A-Paare im Reden-Stil (annehmen moechte / dagegen /
enthaelt sich)
- Drucksachen-Lookup: 'Drucksache 19/N(-suffix)' rueckwaerts (1500-char Fenster)
Fraktions-Mapping WP19:
- Buendnis 90/Die Gruenen → GRÜNE
- Die Linke → LINKE
- CDU, SPD, AfD, FDP
21 Tests in test_protokoll_parsers_be.py.
Cron-PROTO_TARGETS erweitert um BE WP19 (~80 Sitzungen).
Stub-Test angepasst.
905 Tests gruen (889 → 905, +16 fuer BE).
2026-04-29 00:37:47 +02:00
|
|
|
"BE": _parse_be,
|
2026-04-29 00:57:58 +02:00
|
|
|
"HH": _parse_hh,
|
2026-04-28 08:37:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_protocol(bundesland: str, pdf_path: str) -> list[dict]:
|
|
|
|
|
"""BL-uebergreifender Einstieg. Sucht den Parser in der Registry.
|
|
|
|
|
|
|
|
|
|
Raises:
|
|
|
|
|
NotImplementedError: wenn fuer das Bundesland (noch) kein Parser
|
|
|
|
|
registriert ist. Folge-Issue: BL-Adapter ergaenzen mit einem
|
|
|
|
|
eigenen Modul plus Eintrag hier.
|
|
|
|
|
"""
|
|
|
|
|
parser = PROTOKOLL_PARSERS.get(bundesland)
|
|
|
|
|
if parser is None:
|
|
|
|
|
supported = ", ".join(sorted(PROTOKOLL_PARSERS)) or "(keine)"
|
|
|
|
|
raise NotImplementedError(
|
|
|
|
|
f"Kein Plenarprotokoll-Parser fuer {bundesland!r}. "
|
|
|
|
|
f"Unterstuetzt: {supported}. Siehe #126."
|
|
|
|
|
)
|
|
|
|
|
return parser(pdf_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def supported_bundeslaender() -> list[str]:
|
|
|
|
|
"""Liste der BL-Codes mit registrierten Parsern."""
|
|
|
|
|
return sorted(PROTOKOLL_PARSERS)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__all__ = [
|
|
|
|
|
"ProtokollParser",
|
|
|
|
|
"PROTOKOLL_PARSERS",
|
|
|
|
|
"parse_protocol",
|
|
|
|
|
"supported_bundeslaender",
|
|
|
|
|
]
|