fix: enforce community cooldown per site
This commit is contained in:
@@ -7,6 +7,7 @@ import sys
|
||||
import time
|
||||
from dataclasses import asdict
|
||||
from pathlib import Path
|
||||
from urllib.parse import urlsplit
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
from .community_sources import (
|
||||
@@ -32,6 +33,16 @@ MIN_FETCH_INTERVAL_SECONDS = 30 * 60
|
||||
DEFAULT_STATE_FILE = Path(".cache/community-fetch-state.json")
|
||||
|
||||
|
||||
def fetch_site_key(url: str) -> str:
|
||||
"""Return a stable cooldown key shared by all endpoints of one site."""
|
||||
hostname = (urlsplit(url).hostname or "").lower()
|
||||
if hostname.startswith("www."):
|
||||
hostname = hostname[4:]
|
||||
if not hostname:
|
||||
raise ValueError("source URL must include a hostname")
|
||||
return hostname
|
||||
|
||||
|
||||
def enforce_fetch_interval(
|
||||
source: str, *, state_file: Path, now: float | None = None,
|
||||
) -> None:
|
||||
@@ -83,9 +94,11 @@ def main(argv: list[str] | None = None) -> int:
|
||||
default_url, parse = SOURCES.get(args.source, (None, DETAIL_SOURCES.get(args.source)))
|
||||
url = args.url or default_url
|
||||
try:
|
||||
enforce_fetch_interval(args.source, state_file=args.state_file)
|
||||
site_key = fetch_site_key(url)
|
||||
enforce_fetch_interval(site_key, state_file=args.state_file)
|
||||
# Reserve before network I/O: failed attempts count toward the limit too.
|
||||
mark_fetch(site_key, state_file=args.state_file)
|
||||
html = fetch_html(url)
|
||||
mark_fetch(args.source, state_file=args.state_file)
|
||||
records = (parse(html, source_url=url) if args.source in DETAIL_SOURCES else parse(html))[:args.limit]
|
||||
except Exception as exc:
|
||||
print(f"community source failed: {exc}", file=sys.stderr)
|
||||
|
||||
Reference in New Issue
Block a user