refactor: route sidecar/preview path derivation through sidecar_paths helpers

Phase 1 of #1045 (optional centralized sidecar storage): introduce
py/utils/sidecar_paths.py as the single place that resolves .metadata.json
and preview locations, and replace all inline splitext-based derivations
across scanners, services, download manager, and route handlers.

No behavior change: the default 'alongside' storage mode resolves every
path exactly as before. .civitai.info (third-party sidecar) derivation is
intentionally left co-located.
This commit is contained in:
Will Miao
2026-09-26 09:02:37 +08:00
parent ede15032ce
commit 297d8787bd
14 changed files with 302 additions and 57 deletions
+21 -8
View File
@@ -68,6 +68,7 @@ from ...utils.example_images_paths import (
)
from ...utils.lora_metadata import extract_trained_words
from ...utils.session_logging import get_standalone_session_log_snapshot
from ...utils.sidecar_paths import get_metadata_path, get_preview_dir
from ...utils.usage_stats import UsageStats
from .base_model_handlers import BaseModelHandlerSet
@@ -943,15 +944,24 @@ class DoctorHandler:
os.rename(path, new_path)
for suffix in (".metadata.json", ".civitai.info"):
old_sidecar = old_base_no_ext + suffix
new_sidecar = new_base_no_ext + suffix
if os.path.exists(old_sidecar):
os.rename(old_sidecar, new_sidecar)
old_metadata_path = get_metadata_path(path)
new_metadata_path = get_metadata_path(new_path)
if os.path.exists(old_metadata_path):
os.rename(old_metadata_path, new_metadata_path)
old_sidecar = old_base_no_ext + ".civitai.info"
new_sidecar = new_base_no_ext + ".civitai.info"
if os.path.exists(old_sidecar):
os.rename(old_sidecar, new_sidecar)
for preview_ext in PREVIEW_EXTENSIONS:
old_preview = old_base_no_ext + preview_ext
new_preview = new_base_no_ext + preview_ext
old_preview = os.path.join(
get_preview_dir(path), base_name + preview_ext
)
new_preview = os.path.join(
get_preview_dir(new_path),
candidate_base + preview_ext,
)
if os.path.exists(old_preview):
os.rename(old_preview, new_preview)
@@ -963,7 +973,10 @@ class DoctorHandler:
old_preview_url = entry["preview_url"].replace("\\", "/")
preview_ext = os.path.splitext(old_preview_url)[1]
if preview_ext:
entry["preview_url"] = (new_base_no_ext + preview_ext).replace(os.sep, "/")
entry["preview_url"] = os.path.join(
get_preview_dir(new_path),
candidate_base + preview_ext,
).replace(os.sep, "/")
await scanner.update_single_model_cache(
path, new_path, entry
)
+2 -1
View File
@@ -50,6 +50,7 @@ from ...services.errors import RateLimitError, ResourceNotFoundError
from ...utils.civitai_utils import resolve_license_payload
from ...utils.file_utils import calculate_sha256
from ...utils.metadata_manager import MetadataManager
from ...utils.sidecar_paths import get_metadata_path
from ...utils.url_utils import relative_root_prefix
LICENSE_FIELDS = (
@@ -676,7 +677,7 @@ class ModelManagementHandler:
status=400,
)
metadata_path = os.path.splitext(file_path)[0] + ".metadata.json"
metadata_path = get_metadata_path(file_path)
local_metadata = await self._metadata_sync.load_local_metadata(
metadata_path
)