Files
AV-Watch/avwatch/sources/base.py
T

53 lines
1.6 KiB
Python
Raw Normal View History

"""Source protocol shared by every version adapter."""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Protocol
from ..http import HttpClient
from ..models import Item, VersionCheck
@dataclass
class Context:
"""Passed to every source. ``scratch`` lets an adapter fetch one shared
payload (a vendor-wide downloads feed, say) and reuse it across the dozens
of items that resolve from it."""
http: HttpClient
scratch: dict[str, Any] = field(default_factory=dict)
def memo(self, key: str, factory):
if key not in self.scratch:
self.scratch[key] = factory()
return self.scratch[key]
class Source(Protocol):
kind: str
def check(self, item: Item, ctx: Context) -> VersionCheck:
...
def error(item: Item, detail: str) -> VersionCheck:
return VersionCheck(item_id=item.id, status="error", detail=detail)
def manual(item: Item, detail: str = "No machine-readable feed; check by hand.") -> VersionCheck:
return VersionCheck(item_id=item.id, status="manual", detail=detail)
def unconfigured(item: Item, detail: str) -> VersionCheck:
"""AVWatch knows how to track this item, but the capability it needs is
not switched on.
Kept distinct from ``manual`` on purpose. "There is no firmware for this
passive splitter" and "your API key is missing so 60 items could not be
looked up" are completely different problems, and collapsing them into one
'check by hand' list makes a configuration gap look like the gear was
never tracked at all.
"""
return VersionCheck(item_id=item.id, status="unconfigured", detail=detail)