Initial commit: AVWatch v1.0.0 with .gitignore and CLAUDE.md
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
"""Source registry and dispatch."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from ..models import Item, VersionCheck
|
||||
from .base import Context, error
|
||||
from .blackmagic import BlackmagicSource
|
||||
from .generic import HtmlSource, JsonSource, ManualSource, RssSource
|
||||
from .github_releases import GithubSource
|
||||
from .websearch import WebSearchSource
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
_SOURCES = {
|
||||
s.kind: s()
|
||||
for s in (
|
||||
BlackmagicSource,
|
||||
GithubSource,
|
||||
HtmlSource,
|
||||
JsonSource,
|
||||
RssSource,
|
||||
WebSearchSource,
|
||||
ManualSource,
|
||||
)
|
||||
}
|
||||
|
||||
KINDS = sorted(_SOURCES)
|
||||
|
||||
|
||||
def check_item(item: Item, ctx: Context) -> VersionCheck:
|
||||
"""Resolve the latest available version for one item. Never raises --
|
||||
an adapter blowing up must not abort a 90-item scan."""
|
||||
# An unconfirmed placeholder must not be searched on. A query built from
|
||||
# a guessed vendor returns a real, correct-looking version for the WRONG
|
||||
# product, and the team then acts on it. Silence is the safe answer until
|
||||
# somebody names the actual model.
|
||||
if not item.is_confirmed:
|
||||
return VersionCheck(
|
||||
item_id=item.id,
|
||||
status="unconfigured",
|
||||
detail=("Make/model not confirmed, so no version lookup is "
|
||||
"attempted -- a guessed vendor would return the wrong "
|
||||
"product's version. Set status: confirmed once you have "
|
||||
"filled in the real make and model."),
|
||||
)
|
||||
|
||||
kind = item.source_kind
|
||||
|
||||
# Nothing to decide, so nothing worth looking up.
|
||||
if item.update_class == "do_not_touch":
|
||||
return VersionCheck(
|
||||
item_id=item.id,
|
||||
status="unconfigured",
|
||||
detail=("Marked do_not_touch, so no version is looked up -- this "
|
||||
"is a licensed contractor's to update, never ours. "
|
||||
"Tracked for visibility only."),
|
||||
)
|
||||
|
||||
# Vendor-pushed items update on someone else's schedule. A paid lookup
|
||||
# buys a version number nobody can act on, so skip it -- but keep free
|
||||
# sources (GitHub, the Blackmagic feed), which cost nothing and do at
|
||||
# least tell us a change landed.
|
||||
if item.update_class == "vendor_pushed" and kind == "websearch":
|
||||
return VersionCheck(
|
||||
item_id=item.id,
|
||||
status="unconfigured",
|
||||
detail=("Marked vendor_pushed, so the paid version lookup is "
|
||||
"skipped -- it updates on the supplier's schedule and "
|
||||
"there is no install decision to inform. Watch for "
|
||||
"breaking-change notices instead."),
|
||||
)
|
||||
source = _SOURCES.get(kind)
|
||||
if source is None:
|
||||
return error(item, f"unknown source kind {kind!r}; known: {', '.join(KINDS)}")
|
||||
try:
|
||||
return source.check(item, ctx)
|
||||
except Exception as exc: # noqa: BLE001 - deliberate isolation boundary
|
||||
log.exception("source %s failed for %s", kind, item.id)
|
||||
return error(item, f"{type(exc).__name__}: {exc}")
|
||||
Reference in New Issue
Block a user