Riesige Überraschung aus dem BB-HAR-Trace: Brandenburg ist NICHT StarWeb wie in dokukratie und bundeslaender.py klassifiziert, sondern läuft auch auf dem portala/eUI-Backend. Endpoint /portal/browse.tt.json mit db_id=lbb.lissh. Das alte /starweb/LBB/ELVIS/-Frontend ist nur Legacy. Folgeprobing offenbarte: RP/opal.rlp.de läuft ebenfalls portala (db_id=rlp.lissh, 46759 hits in WP18), ebenso NI/HE/BB. Damit ist Phase 2 großteils KEIN StarWeb-Adapter-Bau, sondern PortalaAdapter- Wiederverwendung mit konfigurierbaren Parametern. Activated via Registry-Einträge: - "BB" → PortalaAdapter(base_url=parlamentsdokumentation.brandenburg.de, db_id=lbb.lissh, wahlperiode=8). Nutzt die BE-Card-Variante des Hit-Parsers (efxRecordRepeater). - "RP" → PortalaAdapter(base_url=opal.rlp.de, db_id=rlp.lissh, wahlperiode=18). NICHT mit dem NRW OPAL verwechseln — anderer Markenname, andere Engine. PortalaAdapter erweitert um zwei neue Konstruktor-Parameter mit backward-kompatiblen Defaults: - typ_filter: Optional[str] = "DOKDBE" Wenn None, wird die TYP=<value>-Klausel weggelassen. Manche Instanzen (HE/hlt.lis) lehnen DOKDBE ab. - omit_date_filter: bool = False Wenn True, wird der DAT/DDAT/SDAT-Term weggelassen. HE und ähnliche Instanzen haben andere Date-Field-Namen. Plus _parse_hit_list_cards Date-Regex erweitert: zusätzlich zum "vom DD.MM.YYYY"-Pattern (BE) jetzt auch "DD.MM.YYYY"-plain (BB schreibt Datum vor Drucksachen-Nummer ohne "vom"-Marker). Smoke-Test (lokal): BB q="": 5 hits in 5.9s BB q="Schule": 5 hits (Pflegeschulen, Genderverbot, Hochschulen) RP q="": 5 hits in 4.1s (Entlastung, Bildungschancen) RP q="Schule": 5 hits (Hochschulbau, G9-Gymnasien, Leistungsgerechtigkeit) bundeslaender.py: BB.doku_system "StarWeb"→"portala", RP analog, beide aktiv=True. Anmerkungen mit dem portala-Verweis und der Klarstellung "OPAL/RLP ≠ NRW OPAL" erweitert. NICHT in diesem Commit: - HE: portala-Backend (hlt.lis) ist erreichbar, aber das HE-Card- Layout ist anders (Title direkt im <h3> statt <h3><span>, kein <span class="h6"> für Meta) — eigener Parser-Pfad nötig, deferred. - NI: nilas.niedersachsen.de/portal/ ist eine Login-Page, das öffentliche Backend ist nicht zugänglich — deferred. - HB: kein /portal/-Endpoint, bleibt das alte StarWeb-Servlet — braucht eigenen HAR-Trace, deferred. - BB als StarWeb-Template (#27) ist hinfällig, weil BB portala ist. Phase 2 (3/6) aus Roadmap-Issue #49. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f82c60e40d
commit
02ff1423a7
@ -145,11 +145,19 @@ BUNDESLAENDER: dict[str, Bundesland] = {
|
||||
naechste_wahl="2029-09-23",
|
||||
regierungsfraktionen=["SPD", "BSW"],
|
||||
landtagsfraktionen=["SPD", "AfD", "CDU", "BSW"],
|
||||
doku_system="StarWeb",
|
||||
doku_system="portala",
|
||||
doku_base_url="https://www.parlamentsdokumentation.brandenburg.de",
|
||||
drucksache_format="8/1234",
|
||||
dokukratie_scraper="bb",
|
||||
anmerkung="Kabinett Woidke IV (SPD-BSW) seit Dezember 2024. Knappe Mehrheit (zwei Sitze).",
|
||||
aktiv=True,
|
||||
anmerkung=(
|
||||
"Kabinett Woidke IV (SPD-BSW) seit Dezember 2024. Knappe "
|
||||
"Mehrheit (zwei Sitze). Doku-System ist NICHT StarWeb wie "
|
||||
"ursprünglich klassifiziert (das alte /starweb/LBB/ELVIS/-"
|
||||
"Frontend ist nur Legacy), sondern das moderne portala/eUI-"
|
||||
"Backend auf /portal/browse.tt.json mit db_id=lbb.lissh. "
|
||||
"Wiederverwendet PortalaAdapter aus #2/#3 (#27)."
|
||||
),
|
||||
),
|
||||
"HB": Bundesland(
|
||||
code="HB",
|
||||
@ -282,14 +290,21 @@ BUNDESLAENDER: dict[str, Bundesland] = {
|
||||
naechste_wahl="2031-03-22",
|
||||
regierungsfraktionen=["SPD", "GRÜNE", "FDP"],
|
||||
landtagsfraktionen=["SPD", "CDU", "AfD", "GRÜNE", "FREIE WÄHLER", "FDP"],
|
||||
doku_system="StarWeb",
|
||||
doku_system="portala",
|
||||
doku_base_url="https://opal.rlp.de",
|
||||
drucksache_format="18/12345",
|
||||
dokukratie_scraper="rp",
|
||||
aktiv=True,
|
||||
anmerkung=(
|
||||
"OPAL in RLP basiert auf StarWeb. Wahl zum 19. Landtag fand am 22.03.2026 "
|
||||
"statt; Koalitionsverhandlungen CDU+SPD laufen, Kabinett Schweitzer I "
|
||||
"geschäftsführend. Nach Konstituierung müssen WP und Wahltermin aktualisiert werden."
|
||||
"OPAL in RLP läuft tatsächlich auf dem portala/eUI-Backend "
|
||||
"(NICHT StarWeb wie ursprünglich klassifiziert), erreichbar "
|
||||
"unter /portal/browse.tt.json mit db_id=rlp.lissh. "
|
||||
"Wiederverwendet PortalaAdapter aus #2/#3 (#30). NICHT "
|
||||
"verwechseln mit dem NRW OPAL — anderer Markenname, "
|
||||
"andere Engine. Wahl zum 19. Landtag fand am 22.03.2026 "
|
||||
"statt; Koalitionsverhandlungen CDU+SPD laufen, Kabinett "
|
||||
"Schweitzer I geschäftsführend. Nach Konstituierung müssen "
|
||||
"WP und Wahltermin aktualisiert werden."
|
||||
),
|
||||
),
|
||||
"SL": Bundesland(
|
||||
|
||||
@ -358,6 +358,8 @@ class PortalaAdapter(ParlamentAdapter):
|
||||
document_type: Optional[str] = "Antrag",
|
||||
pdf_url_prefix: str = "/files/",
|
||||
date_window_days: int = 730,
|
||||
typ_filter: Optional[str] = "DOKDBE",
|
||||
omit_date_filter: bool = False,
|
||||
) -> None:
|
||||
"""Configure a portala/eUI adapter for one specific parliament.
|
||||
|
||||
@ -380,6 +382,11 @@ class PortalaAdapter(ParlamentAdapter):
|
||||
relative PDF path returned by the server.
|
||||
date_window_days: how many days back ``search()`` looks by
|
||||
default.
|
||||
typ_filter: ``TYP=<value>`` term in the parsed string and
|
||||
JSON tree. ``DOKDBE`` works for LSA/BE/BB/BW (the
|
||||
lissh-style instances). For Hessen (``hlt.lis``) and
|
||||
similar instances the value is different or absent —
|
||||
pass ``None`` to drop the term entirely.
|
||||
"""
|
||||
self.bundesland = bundesland
|
||||
self.name = name
|
||||
@ -390,6 +397,8 @@ class PortalaAdapter(ParlamentAdapter):
|
||||
self.document_type = document_type
|
||||
self.pdf_url_prefix = "/" + pdf_url_prefix.strip("/") + "/"
|
||||
self.date_window_days = date_window_days
|
||||
self.typ_filter = typ_filter
|
||||
self.omit_date_filter = omit_date_filter
|
||||
|
||||
# ── LSA-style hit list (Perl Data::Dumper inside <pre> blocks) ──
|
||||
# Reverse-engineered "WEV*" record fields:
|
||||
@ -415,7 +424,13 @@ class PortalaAdapter(ParlamentAdapter):
|
||||
# The metadata h6 looks like:
|
||||
# <span class="h6">Antrag (Eilantrag) <a ...>Drucksache 19/3104</a> S. 1 bis 24 vom 31.03.2026</span>
|
||||
_RE_BE_DRUCKSACHE = re.compile(r'Drucksache\s+(\d+/\d+)')
|
||||
_RE_BE_DATUM = re.compile(r'vom\s+(\d{1,2}\.\d{1,2}\.\d{4})')
|
||||
# BE has "Drucksache 19/3104 S. 1 bis 24 vom 31.03.2026" — date is
|
||||
# marked by ``vom``. BB has the BE card format too but writes the
|
||||
# date BEFORE the Drucksachen-Nummer with no marker:
|
||||
# "Antrag Reinhard Simon (BSW) 17.10.2024 Drucksache 8/2 (1 S.)".
|
||||
# Try ``vom``-prefix first; fall back to the first plain date.
|
||||
_RE_BE_DATUM_VOM = re.compile(r'vom\s+(\d{1,2}\.\d{1,2}\.\d{4})')
|
||||
_RE_BE_DATUM_PLAIN = re.compile(r'(\d{1,2}\.\d{1,2}\.\d{4})')
|
||||
_RE_BE_DOCTYPE = re.compile(r'<span class="h6">\s*([^<&]+?)(?: |<)')
|
||||
|
||||
@staticmethod
|
||||
@ -527,6 +542,7 @@ class PortalaAdapter(ParlamentAdapter):
|
||||
]},
|
||||
]})
|
||||
|
||||
if not self.omit_date_filter:
|
||||
top_terms.append({"tn": "or", "num": 18, "terms": [
|
||||
{"tn": "or", "num": 19, "terms": [
|
||||
date_term("DAT", 20),
|
||||
@ -534,22 +550,24 @@ class PortalaAdapter(ParlamentAdapter):
|
||||
]},
|
||||
date_term("SDAT", 22),
|
||||
]})
|
||||
top_terms.append({"tn": "term", "t": "DOKDBE", "idx": 156, "l": 1,
|
||||
if self.typ_filter is not None:
|
||||
top_terms.append({"tn": "term", "t": self.typ_filter, "idx": 156, "l": 1,
|
||||
"sf": "TYP", "op": "eq", "num": 23})
|
||||
|
||||
# Mirror the same shape into the parsed/sref display strings
|
||||
typ_clause = f" AND TYP={self.typ_filter}" if self.typ_filter is not None else ""
|
||||
date_clause = (
|
||||
f" AND (DAT,DDAT,SDAT= {date_range_text})"
|
||||
if not self.omit_date_filter else ""
|
||||
)
|
||||
if document_type is not None:
|
||||
parsed = (
|
||||
f"((/WP {wahlperiode}) AND "
|
||||
f"(/ETYPF,ETYP2F,DTYPF,DTYP2F,1VTYPF (\"{document_type}\")) "
|
||||
f"AND (/DART,DARTS (\"D\")) AND "
|
||||
f"(DAT,DDAT,SDAT= {date_range_text})) AND TYP=DOKDBE"
|
||||
f"AND (/DART,DARTS (\"D\")){date_clause}){typ_clause}"
|
||||
)
|
||||
else:
|
||||
parsed = (
|
||||
f"((/WP {wahlperiode}) AND "
|
||||
f"(DAT,DDAT,SDAT= {date_range_text})) AND TYP=DOKDBE"
|
||||
)
|
||||
parsed = f"((/WP {wahlperiode}){date_clause}){typ_clause}"
|
||||
|
||||
return {
|
||||
"action": "SearchAndDisplay",
|
||||
@ -675,7 +693,7 @@ class PortalaAdapter(ParlamentAdapter):
|
||||
else:
|
||||
pdf_url = f"{self.base_url}{self.pdf_url_prefix}{href}"
|
||||
|
||||
m_dat = self._RE_BE_DATUM.search(chunk)
|
||||
m_dat = self._RE_BE_DATUM_VOM.search(chunk) or self._RE_BE_DATUM_PLAIN.search(chunk)
|
||||
datum_iso = self._datum_de_to_iso(m_dat.group(1) if m_dat else "")
|
||||
|
||||
m_doc = self._RE_BE_DOCTYPE.search(chunk)
|
||||
@ -1971,6 +1989,27 @@ ADAPTERS = {
|
||||
db_path="lisshfl.txt",
|
||||
document_typ_code="antrag",
|
||||
),
|
||||
"BB": PortalaAdapter(
|
||||
bundesland="BB",
|
||||
name="Landtag Brandenburg (parladoku)",
|
||||
base_url="https://www.parlamentsdokumentation.brandenburg.de",
|
||||
db_id="lbb.lissh",
|
||||
wahlperiode=8,
|
||||
portala_path="/portal",
|
||||
document_type="Antrag",
|
||||
# BB packs the date BEFORE the Drucksachen-Nummer in the h6
|
||||
# line and uses the BE-style efxRecordRepeater HTML cards;
|
||||
# the auto-detect picks the card path automatically.
|
||||
),
|
||||
"RP": PortalaAdapter(
|
||||
bundesland="RP",
|
||||
name="Landtag Rheinland-Pfalz (OPAL)",
|
||||
base_url="https://opal.rlp.de",
|
||||
db_id="rlp.lissh",
|
||||
wahlperiode=18,
|
||||
portala_path="/portal",
|
||||
document_type="Antrag",
|
||||
),
|
||||
"BY": BayernAdapter(),
|
||||
"BW": PARLISAdapter(
|
||||
bundesland="BW",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user