v0.5.59: item counter evidence for fears, catch up Web features to site version.
Ship OpenDota counter-stats reordering for feared items, finalize SITE_VERSION/docs for rankings/streamers/trends/matches/mechanics and draft archetypes, and ignore regenerable Web data caches. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+37
-2
@@ -11,7 +11,7 @@ Sources:
|
||||
Only patches within the past year (default 365 days from today) are kept,
|
||||
descending. Per-patch detail keeps the raw ability_id / hero_id values; a
|
||||
shared `lookup` resolves only the referenced ids to {key, name_loc} so the
|
||||
read-only preview can render names + icons with no runtime network calls.
|
||||
read-only Climperor web site can render names + icons with no runtime network calls.
|
||||
|
||||
Referenced item / ability icons are downloaded into assets/item_icons and
|
||||
assets/ability_icons so the static export stays self-contained.
|
||||
@@ -22,6 +22,7 @@ Usage:
|
||||
python fetch_patches.py --since 2025-07-27
|
||||
python fetch_patches.py --no-icons
|
||||
python fetch_patches.py --force # refetch every patch detail
|
||||
python fetch_patches.py --check # list vs cache; JSON on stdout
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -58,7 +59,7 @@ DEFAULT_WINDOW_DAYS = 365
|
||||
# Bundled shared badges — never fetched from CDN (many innate keys 404).
|
||||
SKIP_ABILITY_ICON_KEYS = frozenset({"innate", "talent_tree"})
|
||||
# Non-hero units that Valve places in patchnotes heroes[] under a pseudo hero_id
|
||||
# absent from herolist. Resolve to a Chinese name + portrait key so the preview
|
||||
# absent from herolist. Resolve to a Chinese name + portrait key so the web site
|
||||
# never shows #1961. Portrait files live in assets/hero_portraits/<key>.png.
|
||||
UNIT_NAMES = {1961: {"key": "spirit_bear", "name_loc": "熊灵"}}
|
||||
|
||||
@@ -372,6 +373,30 @@ def load_existing_details() -> dict[str, dict]:
|
||||
return out
|
||||
|
||||
|
||||
def check_for_new_patches(*, days: int, since: str | None) -> dict:
|
||||
"""Compare Valve patch list to local details cache; do not write files.
|
||||
|
||||
Returns a JSON-serializable dict with has_new / new_versions / latest / …
|
||||
"""
|
||||
if since:
|
||||
since_dt = datetime.strptime(since, "%Y-%m-%d").replace(tzinfo=timezone.utc)
|
||||
else:
|
||||
since_dt = datetime.now(tz=timezone.utc) - timedelta(days=days)
|
||||
since_ts = int(since_dt.timestamp())
|
||||
patches = fetch_patch_list(since_ts)
|
||||
cached = load_existing_details()
|
||||
new_versions = [p["version"] for p in patches if p["version"] not in cached]
|
||||
latest = patches[0]["version"] if patches else None
|
||||
return {
|
||||
"has_new": bool(new_versions),
|
||||
"new_versions": new_versions,
|
||||
"latest": latest,
|
||||
"window_count": len(patches),
|
||||
"cached_details": len(cached),
|
||||
"since": since_dt.date().isoformat(),
|
||||
}
|
||||
|
||||
|
||||
def main() -> None:
|
||||
ap = argparse.ArgumentParser(description=__doc__)
|
||||
ap.add_argument("--days", type=int, default=DEFAULT_WINDOW_DAYS, help="window in days from today")
|
||||
@@ -379,8 +404,18 @@ def main() -> None:
|
||||
ap.add_argument("--delay", type=float, default=0.3, help="seconds between detail/icon requests")
|
||||
ap.add_argument("--no-icons", action="store_true", help="skip icon downloads")
|
||||
ap.add_argument("--force", action="store_true", help="refetch every patch detail")
|
||||
ap.add_argument(
|
||||
"--check",
|
||||
action="store_true",
|
||||
help="only compare patch list to local details; print JSON to stdout",
|
||||
)
|
||||
args = ap.parse_args()
|
||||
|
||||
if args.check:
|
||||
result = check_for_new_patches(days=args.days, since=args.since)
|
||||
print(json.dumps(result, ensure_ascii=False), flush=True)
|
||||
return
|
||||
|
||||
if args.since:
|
||||
since_dt = datetime.strptime(args.since, "%Y-%m-%d").replace(tzinfo=timezone.utc)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user