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

@ -27,10 +27,10 @@ exclude_paywalled: true
# binnen X dagen, ook als de feed/URL anders is (zelfde uitgever, meerdere sites). # binnen X dagen, ook als de feed/URL anders is (zelfde uitgever, meerdere sites).
# 0 = uit. # 0 = uit.
title_dedup_days: 30 title_dedup_days: 30
# OV-matchfilter: VAST in code (gewogen families), niet via config te wijzigen. # OV-matchfilter: VAST in code (gewogen families + blacklist), niet via config te wijzigen.
# Doorlaten als 2×(titelscore) + 1×(samenvattingscore) >= 3. Zie de families in # Doorlaten als 2×(titelscore) + 1×(samenvattingscore) >= 3. Zie de families en de
# buzzrss/bot.py (MATCH_FILTER_FAMILIES). `!rss set-filter` en `!rss filter` # blacklist in buzzrss/bot.py (MATCH_FILTER_FAMILIES / MATCH_FILTER_BLACKLIST).
# tonen alleen de huidige (vaste) filter. # `!rss set-filter` en `!rss filter` tonen alleen de huidige (vaste) filter.
# Users who can bypass room permission checks # Users who can bypass room permission checks
admins: admins:
- "@user:example.com" - "@user:example.com"

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 # OV-woord combineren. Weert zo "VW-bus"/"schoolbus", "weer op de rails" en
# 112-berichten met "bussen rijden om" in de lead, zonder eenduidige # 112-berichten met "bussen rijden om" in de lead, zonder eenduidige
# bushalte/overweg/NS/trein-berichten te raken. # 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]] = [ MATCH_FILTER_FAMILIES: list[tuple[str, int]] = [
# sterk (3) # 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 (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). # Drempel voor doorlaten (score = 2×titel + 1×samenvatting).
MATCH_FILTER_THRESHOLD = 3 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]] = [ _compiled_match_families: list[tuple[re.Pattern, int]] = [
(re.compile(pat, re.IGNORECASE), w) for pat, w in MATCH_FILTER_FAMILIES (re.compile(pat, re.IGNORECASE), w) for pat, w in MATCH_FILTER_FAMILIES
] ]
@ -202,8 +220,19 @@ class RSSBot(Plugin):
@staticmethod @staticmethod
def _fam_score(text: str) -> int: def _fam_score(text: str) -> int:
"""Som van gewichten over de OV-families die in text voorkomen (1× per familie).""" """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))
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 @staticmethod
def _filter_passes(title: str, summary: str) -> bool: def _filter_passes(title: str, summary: str) -> bool:
@ -227,6 +256,8 @@ class RSSBot(Plugin):
"- Medium (2): tram, metro, openbaar vervoer/dienstregeling/inchecken, " "- Medium (2): tram, metro, openbaar vervoer/dienstregeling/inchecken, "
"ov-chipkaart/ovpay/reisproduct, ov-staking, pont\n" "ov-chipkaart/ovpay/reisproduct, ov-staking, pont\n"
"- Zwak (1): losse 'bus', 'kaartje', 'rails' — moet combineren met een ander OV-woord\n\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`" "Doorlaten: `2×(titel-score) + 1×(samenvatting-score) ≥ 3`"
) )

View file

@ -1,5 +1,5 @@
id: nl.eddydevink.rss id: nl.eddydevink.rss
version: 1.8.1 version: 1.8.2
modules: modules:
- buzzrss - buzzrss
main_class: RSSBot main_class: RSSBot