diff --git a/buzzrss/bot.py b/buzzrss/bot.py index 994ab67..1a4d48e 100644 --- a/buzzrss/bot.py +++ b/buzzrss/bot.py @@ -158,23 +158,38 @@ class RSSBot(Plugin): except Exception: self.log.exception("Fatal error while polling feeds") + @staticmethod + def _matches_in(text: str, match_filter: str) -> int: + """Aantal aaneengesloten match-clusters in text (0 als geen match). + Aaneengesloten matches (bv 'NS-trein', 'openbaar vervoer') tellen als 1.""" + spans = sorted((m.start(), m.end()) for m in re.finditer(match_filter, text)) + if not spans: + return 0 + clusters, prev_end = 1, spans[0][1] + for s, e in spans[1:]: + if s - prev_end <= 1: + prev_end = max(prev_end, e) + else: + clusters += 1 + prev_end = e + return clusters + @staticmethod def _filter_score(title: str, summary: str, match_filter: str) -> int: - """Score = 2× hits in titel + 1× hits in summary. Aaneengesloten matches - (bv 'NS-trein', 'openbaar vervoer') tellen als 1 cluster.""" - def count(text: str) -> int: - spans = sorted((m.start(), m.end()) for m in re.finditer(match_filter, text)) - if not spans: - return 0 - clusters, prev_end = 1, spans[0][1] - for s, e in spans[1:]: - if s - prev_end <= 1: - prev_end = max(prev_end, e) - else: - clusters += 1 - prev_end = e - return clusters - return 2 * count(title) + count(summary) + """Score = 2× hits in titel + 1× hits in summary.""" + return 2 * RSSBot._matches_in(title, match_filter) + RSSBot._matches_in(summary, match_filter) + + @staticmethod + def _filter_passes(title: str, summary: str, match_filter: str) -> bool: + """Regel C: doorlaten bij (titel-match >= 1) of (totaalscore >= 3). + + Een OV-trefwoord in de titel is een sterke intentieverklaring (score 2 + volstaat). Treffers alleen in de samenvatting moeten dubbel bevestigd + worden (>= 3): zo houdt 'bussen rijden om' in de lead van een + woningbrand-bericht het artikel niet meer binnen.""" + if RSSBot._matches_in(title, match_filter) >= 1: + return True + return RSSBot._filter_score(title, summary, match_filter) >= 3 async def _send( self, feed: Feed, entry: Entry, sub: Subscription, *, check_filter: bool = True @@ -183,7 +198,7 @@ class RSSBot(Plugin): match_filter = self.config["match_filter"] if match_filter: summary = html.unescape(re.sub(r"<[^>]+>", "", entry.summary)) - if self._filter_score(entry.title, summary, match_filter) < 2: + if not self._filter_passes(entry.title, summary, match_filter): return None message = sub.notification_template.safe_substitute( @@ -217,7 +232,7 @@ class RSSBot(Plugin): match_filter = self.config["match_filter"] if match_filter: summary = html.unescape(re.sub(r"<[^>]+>", "", entry.summary)) - if self._filter_score(entry.title, summary, match_filter) < 2: + if not self._filter_passes(entry.title, summary, match_filter): return 0, 1, 0 spam_sleep = self.config["spam_sleep"] if spam_sleep >= 0: diff --git a/maubot.yaml b/maubot.yaml index a76cf33..a30c5b7 100644 --- a/maubot.yaml +++ b/maubot.yaml @@ -1,5 +1,5 @@ id: nl.eddydevink.rss -version: 1.5.2 +version: 1.5.3 modules: - buzzrss main_class: RSSBot