70 lines
1.5 KiB
Python
70 lines
1.5 KiB
Python
from dataclasses import dataclass, field
|
|
from typing import Any
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class SourceConfig:
|
|
name: str
|
|
type: str
|
|
role: str = "supplement"
|
|
priority: int = 100
|
|
required: bool = False
|
|
enabled: bool = True
|
|
timeout_seconds: int = 25
|
|
retries: int = 0
|
|
min_items: int = 0
|
|
url: str = ""
|
|
max_item_age_days: int | None = None
|
|
failure_policy: str = "warn"
|
|
|
|
|
|
@dataclass
|
|
class SourceResult:
|
|
source: str
|
|
role: str
|
|
ok: bool
|
|
status: str
|
|
items: list[dict[str, Any]] = field(default_factory=list)
|
|
error: str | None = None
|
|
elapsed_ms: int = 0
|
|
retry_count: int = 0
|
|
fetched_at: str = ""
|
|
|
|
|
|
@dataclass
|
|
class NewsItem:
|
|
id: str
|
|
source_group: str
|
|
source_label: str
|
|
source_role: str
|
|
source_priority: int
|
|
title_raw: str
|
|
title_norm: str
|
|
summary_raw: str
|
|
url: str
|
|
canonical_url: str
|
|
published_at: str | None = None
|
|
collected_at: str = ""
|
|
origin_type: str = ""
|
|
section_hint: str = ""
|
|
language_hint: str = ""
|
|
title: str | None = None
|
|
summary: str | None = None
|
|
section: str | None = None
|
|
quality_flags: list[str] = field(default_factory=list)
|
|
duplicate_sources: list[dict[str, Any]] = field(default_factory=list)
|
|
|
|
|
|
@dataclass
|
|
class PublishedUrlEntry:
|
|
first_seen: str
|
|
last_published: str
|
|
titles: list[str] = field(default_factory=list)
|
|
|
|
|
|
@dataclass
|
|
class PublishedUrls:
|
|
version: int = 1
|
|
urls: dict[str, PublishedUrlEntry] = field(default_factory=dict)
|
|
updated_at: str = ""
|