From dc715aa2733937890227b2bd31f14c1a9f21a9d1 Mon Sep 17 00:00:00 2001 From: Will Miao Date: Sat, 18 Jul 2026 18:28:32 +0800 Subject: [PATCH] fix(download): fallback to downloadUrl when all mirrors are deleted When Civitai returns 404 for /models/{id} (e.g. due to Civitai API bug where un-deleted models still get 404), the fallback to CivArchive provides metadata. However CivArchive may return mirrors with every entry marked deletedAt, while the file's downloadUrl is still valid. Before this fix, _build_download_urls_from_file_info used an if/else that skipped the downloadUrl fallback whenever the mirrors array was non-empty, even when all mirrors were filtered out. Now downloadUrl is always tried when no usable mirror remains. Also deduplicated the inline mirror-processing code at the second call site by replacing it with a call to the shared helper. --- py/services/download_manager.py | 34 +++++---------------------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/py/services/download_manager.py b/py/services/download_manager.py index 2888ad0e..da5c20e3 100644 --- a/py/services/download_manager.py +++ b/py/services/download_manager.py @@ -682,7 +682,10 @@ class DownloadManager: u for u in download_urls if not u.startswith(CIVITAI_DOWNLOAD_URL_PREFIXES) ] download_urls = non_civitai_urls + civitai_urls - else: + + # Fallback: when mirrors is empty or all mirrors have been deleted, + # use the file's downloadUrl directly (e.g. CivitAI download endpoint). + if not download_urls: download_url = file_info.get("downloadUrl") if download_url: download_urls.append(normalize_civitai_download_url(download_url)) @@ -1520,35 +1523,8 @@ class DownloadManager: if not file_info: return {"success": False, "error": "No suitable file found in metadata"} - mirrors = file_info.get("mirrors") or [] - download_urls = [] - if mirrors: - for mirror in mirrors: - if mirror.get("deletedAt") is None and mirror.get("url"): - download_urls.append( - normalize_civitai_download_url(mirror["url"]) - ) - # When source is 'civarchive', prioritize non-Civitai URLs - # This avoids failed downloads from deleted Civitai models - if source == "civarchive" and len(download_urls) > 1: - civitai_urls = [ - u - for u in download_urls - if u.startswith(CIVITAI_DOWNLOAD_URL_PREFIXES) - ] - non_civitai_urls = [ - u - for u in download_urls - if not u.startswith(CIVITAI_DOWNLOAD_URL_PREFIXES) - ] - download_urls = non_civitai_urls + civitai_urls - else: - download_url = file_info.get("downloadUrl") - if download_url: - download_urls.append( - normalize_civitai_download_url(download_url) - ) + download_urls = self._build_download_urls_from_file_info(file_info, source=source) if not download_urls: return {"success": False, "error": "No mirror URL found"}