Source code for corvix.notifications.detector

"""Detect newly-arrived unread notifications by comparing snapshots."""

from __future__ import annotations

from corvix.domain import NotificationRecord, notification_key
from corvix.notifications.models import NotificationEvent


[docs] def detect_new_unread_events( previous: list[NotificationRecord], current: list[NotificationRecord], min_score: float = 0.0, include_read: bool = False, ) -> list[NotificationEvent]: """Return events for notifications that are new *or* newly-unread. A record qualifies when all of the following are true: * ``unread`` is ``True`` in the current snapshot, unless *include_read* is ``True`` in which case read records also qualify. * It is not excluded from dashboards and not dismissed. * Its ``score`` meets ``min_score``. * Either it did not exist in the previous snapshot *or* it existed but was ``unread=False`` (read → unread transition, rare but possible). Parameters ---------- previous: Records from the snapshot loaded *before* the current poll cycle. current: Records produced by the current poll cycle (post-score/rules). min_score: Minimum score for a record to generate an event (default 0 — all unread records qualify). include_read: When ``True``, read records also generate events (default ``False``). """ prev_by_id: dict[str, NotificationRecord] = {notification_key(r.notification): r for r in previous} events: list[NotificationEvent] = [] for record in current: notification = record.notification if not include_read and not notification.unread: continue if record.excluded or record.dismissed: continue if record.score < min_score: continue key = notification_key(notification) prev = prev_by_id.get(key) is_new = prev is None became_unread = prev is not None and not prev.notification.unread if not (is_new or became_unread): continue events.append( NotificationEvent( event_id=key, account_id=notification.account_id, thread_id=notification.thread_id, repository=notification.repository, reason=notification.reason, subject_title=notification.subject_title, subject_type=notification.subject_type, web_url=notification.web_url, updated_at=notification.updated_at, score=record.score, unread=notification.unread, ) ) return events