import logging from collections import OrderedDict from services.dates import date_part from structs.headline import Headline logger = logging.getLogger(__name__) class Story: """A cluster of headlines, drawn from one or more sources, that all report the same underlying news story.""" def __init__(self, headlines: list[Headline]): self.headlines = list(headlines) logger.debug("Created Story with %d headline(s)", len(self.headlines)) @property def sources(self) -> list[str]: """Distinct outlet domains for this story, in first-seen order.""" seen = OrderedDict() for h in self.headlines: if h.domain: seen.setdefault(h.domain, None) return list(seen.keys()) @property def source_count(self) -> int: return len(self.sources) @property def representative(self) -> str: """The most descriptive headline text for this story (longest, first on tie).""" return max(self.headlines, key=lambda h: len(h.display_text)).display_text @property def latest_date(self): """The most recent publication date among this story's headlines, or None.""" dates = [date_part(h.published_at) for h in self.headlines if h.published_at is not None] return max(dates) if dates else None