diff --git a/src/server/utils/template_helpers.py b/src/server/utils/template_helpers.py index 0145419..dc16304 100644 --- a/src/server/utils/template_helpers.py +++ b/src/server/utils/template_helpers.py @@ -13,8 +13,8 @@ Series Identifier Convention: All template helpers that handle series data use `key` for identification and provide `folder` as display metadata only. """ +import hashlib import logging -import time from pathlib import Path from typing import Any, Dict, List, Optional @@ -27,10 +27,44 @@ logger = logging.getLogger(__name__) # Configure templates directory TEMPLATES_DIR = Path(__file__).parent.parent / "web" / "templates" +STATIC_DIR = Path(__file__).parent.parent / "web" / "static" templates = Jinja2Templates(directory=str(TEMPLATES_DIR)) -# Version token for static asset cache-busting; changes on every server start. -STATIC_VERSION: str = str(int(time.time())) +# Cache for static file hashes: {file_path: (mtime, hash)} +_hash_cache: Dict[str, tuple[float, str]] = {} + + +def get_static_version(file_path: str) -> str: + """ + Get cache-busting version for a static file based on content hash. + + Hash is computed once and cached; cache is invalidated when file mtime changes. + + Args: + file_path: Relative path to static file (e.g., 'css/styles.css') + + Returns: + 8-character hex hash of file content, or empty string if file not found + """ + full_path = STATIC_DIR / file_path + + if not full_path.exists(): + logger.warning(f"Static file not found: {file_path}") + return "" + + current_mtime = full_path.stat().st_mtime + + # Check cache validity + if file_path in _hash_cache: + cached_mtime, cached_hash = _hash_cache[file_path] + if cached_mtime == current_mtime: + return cached_hash + + # Compute new hash + file_hash = hashlib.md5(full_path.read_bytes()).hexdigest()[:8] + _hash_cache[file_path] = (current_mtime, file_hash) + + return file_hash def get_base_context( @@ -51,7 +85,7 @@ def get_base_context( "title": title, "app_name": "Aniworld Download Manager", "version": APP_VERSION, - "static_v": STATIC_VERSION, + "static_version": get_static_version, } diff --git a/src/server/web/templates/index.html b/src/server/web/templates/index.html index 2df8695..2fc701a 100644 --- a/src/server/web/templates/index.html +++ b/src/server/web/templates/index.html @@ -5,11 +5,11 @@ AniWorld Manager - + - + @@ -727,22 +727,22 @@ - - - - - - + + + + + + - - + + - - - - + + + + diff --git a/src/server/web/templates/loading.html b/src/server/web/templates/loading.html index b532988..e9c421c 100644 --- a/src/server/web/templates/loading.html +++ b/src/server/web/templates/loading.html @@ -5,7 +5,7 @@ AniWorld Manager - Initializing - +