feat(relink): accept CivitArchive URLs when linking models

This commit is contained in:
Will Miao
2026-08-26 21:31:30 +08:00
parent 3025c64fea
commit 641a61f804
21 changed files with 756 additions and 121 deletions
+32 -7
View File
@@ -634,6 +634,16 @@ class ModelManagementHandler:
file_path = data.get("file_path")
model_id = data.get("model_id")
model_version_id = data.get("model_version_id")
source = data.get("source")
if source not in (None, "", "civarchive"):
return web.json_response(
{
"success": False,
"error": f"Unsupported relink source: {source}",
},
status=400,
)
if not file_path or model_id is None:
return web.json_response(
@@ -649,20 +659,33 @@ class ModelManagementHandler:
metadata_path
)
relink_kwargs = {
"file_path": file_path,
"metadata": local_metadata,
"model_id": int(model_id),
"model_version_id": int(model_version_id) if model_version_id else None,
}
if source == "civarchive":
relink_kwargs["provider_name"] = "civarchive_api"
updated_metadata = await self._metadata_sync.relink_metadata(
file_path=file_path,
metadata=local_metadata,
model_id=int(model_id),
model_version_id=int(model_version_id) if model_version_id else None,
**relink_kwargs
)
await self._service.scanner.update_single_model_cache(
file_path, file_path, updated_metadata
)
message = f"Model successfully re-linked to Civitai model {model_id}" + (
f" version {model_version_id}" if model_version_id else ""
)
if source == "civarchive":
message = (
f"Model successfully re-linked to CivArchive model {model_id}"
+ (f" version {model_version_id}" if model_version_id else "")
)
else:
message = (
f"Model successfully re-linked to Civitai model {model_id}"
+ (f" version {model_version_id}" if model_version_id else "")
)
return web.json_response(
{
"success": True,
@@ -670,6 +693,8 @@ class ModelManagementHandler:
"hash": updated_metadata.get("sha256", ""),
}
)
except ValueError as exc:
return web.json_response({"success": False, "error": str(exc)}, status=400)
except Exception as exc:
if is_expected_offline_error(str(exc)):
return web.json_response(
+26 -3
View File
@@ -419,14 +419,37 @@ class MetadataSyncService:
metadata: Dict[str, Any],
model_id: int,
model_version_id: Optional[int],
provider_name: Optional[str] = None,
) -> Dict[str, Any]:
"""Relink a local metadata record to a specific CivitAI model version."""
"""Relink a local metadata record to a specific CivitAI model version.
When ``provider_name`` is given, the named provider is resolved via the
metadata provider selector instead of the default fallback chain. A
missing/disabled provider surfaces a user-friendly error instead of the
raw selector exception.
"""
if provider_name:
try:
provider = await self._get_provider(provider_name)
except ValueError as exc:
logger.warning(
"Unable to resolve metadata provider %s: %s", provider_name, exc
)
raise ValueError(
"CivitArchive is not available or not enabled. "
"Enable the CivitArchive API in settings to relink via CivArchive."
) from exc
else:
provider = await self._get_default_provider()
provider = await self._get_default_provider()
civitai_metadata = await provider.get_model_version(model_id, model_version_id)
if not civitai_metadata:
provider_label = (
"CivitArchive" if provider_name == "civarchive_api" else "CivitAI"
)
raise ValueError(
f"Model version not found on CivitAI for ID: {model_id}"
f"Model version not found on {provider_label} for ID: {model_id}"
+ (f" with version: {model_version_id}" if model_version_id else "")
)