v1.8.2: blacklist straatnamen rond stations in OV-matchfilter

'de Stationsstraat afsluiten voor een festival' is geen OV-nieuws, maar
scored wel (familie \bstation\w*\b, gewicht 3; via `stations`+suffix
dingt `station\w*\b` op 'stationsstraat'). Regex-uitbreiding faalt op de
dubbele s (stations+straat): elke naamvorm vraagt opnieuw regex-herrie.

Daarom MATCH_FILTER_BLACKLIST: exact gematchte woorden die geen OV-waarde
hebben (straatnamen rond stations: stationsstraat/weg/laan/plein/... plus
treinstraat/treinweg) tellen niet meer mee. De genitief-s-vorm dekt zowel
'Stationsstraat' als 'Stationsweg' etc. Zwartgelijste woorden blokkeren de
familie niet: een echt station-/trein-woord ernaast scoort gewoon.
This commit is contained in:
Eddy de Vink 2026-09-10 08:42:33 +02:00
commit f4ea969f33
3 changed files with 38 additions and 7 deletions

View file

@ -59,6 +59,10 @@ rss_change_level = EventType.find("xyz.maubot.rss", t_class=EventType.Class.STAT
# OV-woord combineren. Weert zo "VW-bus"/"schoolbus", "weer op de rails" en
# 112-berichten met "bussen rijden om" in de lead, zonder eenduidige
# bushalte/overweg/NS/trein-berichten te raken.
# MATCH_FILTER_BLACKLIST: gematchte woorden die tóch geen OV-waarde hebben (o.a.
# straatnamen rond stations — "de Stationsstraat afsluiten voor een festival"
# is geen OV-nieuws). Zwartgelijste woorden leveren geen score op, maar
# blokkeren de familie niet: een écht "station"-woord ernaast scoort gewoon.
MATCH_FILTER_FAMILIES: list[tuple[str, int]] = [
# sterk (3)
(r"\b(?:ns|arriva|qbuzz|connexxion|cxx|transdev|keolis|ret|gvb|ebs|htm|syntus|breng|u-ov|allgo|flixbus|blauwnet|r-net|valleilijn|waterbus|eurostar|thalys|randstadrail|gvu|ov)\b", 3), # vervoerders
@ -82,6 +86,20 @@ MATCH_FILTER_FAMILIES: list[tuple[str, int]] = [
# Drempel voor doorlaten (score = 2×titel + 1×samenvatting).
MATCH_FILTER_THRESHOLD = 3
# Woorden die een familie wél matcht maar die geen OV-waarde hebben. Een hit dat
# hierin staat telt niet mee voor de score (en blokkeert de familie niet). Vorm:
# exact woord (lowercase), zoals door de familie-regex wordt gematcht.
MATCH_FILTER_BLACKLIST: frozenset[str] = frozenset({
# Straatnamen rond stations (genitief-s-vorm van "\bstation\w*\b"): een straat
# die toevallig bij een station ligt maakt een bericht nog geen OV-bericht.
"stationsstraat", "stationsweg", "stationslaan", "stationsplein",
"stationssingel", "stationskade", "stationsdreef", "stationshof",
"stationspad", "stationsboulevard", "stationsgracht", "stationsdijk",
"stationssteeg", "stationswal", "stationsbuurt", "stationswijk", "stationspark",
# Idem voor "\btrein\w*\b".
"treinstraat", "treinweg",
})
_compiled_match_families: list[tuple[re.Pattern, int]] = [
(re.compile(pat, re.IGNORECASE), w) for pat, w in MATCH_FILTER_FAMILIES
]
@ -202,8 +220,19 @@ class RSSBot(Plugin):
@staticmethod
def _fam_score(text: str) -> int:
"""Som van gewichten over de OV-families die in text voorkomen (1× per familie)."""
return sum(weight for family, weight in _compiled_match_families if family.search(text))
"""Som van gewichten over de OV-families die in text voorkomen (1× per familie).
Gematchte woorden uit MATCH_FILTER_BLACKLIST (o.a. 'stationsstraat')
tellen niet mee en blokkeren de familie niet: een écht OV-woord in
dezelfde tekst scoort gewoon verder."""
total = 0
for family, weight in _compiled_match_families:
for m in family.finditer(text):
if m.group(0).lower() in MATCH_FILTER_BLACKLIST:
continue
total += weight
break
return total
@staticmethod
def _filter_passes(title: str, summary: str) -> bool:
@ -227,6 +256,8 @@ class RSSBot(Plugin):
"- Medium (2): tram, metro, openbaar vervoer/dienstregeling/inchecken, "
"ov-chipkaart/ovpay/reisproduct, ov-staking, pont\n"
"- Zwak (1): losse 'bus', 'kaartje', 'rails' — moet combineren met een ander OV-woord\n\n"
"Uitgesloten (blacklist): woorden die wél matchen maar geen OV-waarde hebben, "
"o.a. straatnamen rond stations ('stationsstraat', 'stationsweg', ...)\n\n"
"Doorlaten: `2×(titel-score) + 1×(samenvatting-score) ≥ 3`"
)