feat(download): add support to download models from civarchive, fixes #381

This commit is contained in:
Will Miao
2025-10-13 19:27:56 +08:00
parent 60d23aa238
commit 27370df93a
3 changed files with 33 additions and 19 deletions

View File

@@ -213,12 +213,7 @@ class DownloadManager:
if await embedding_scanner.check_model_version_exists(model_version_id): if await embedding_scanner.check_model_version_exists(model_version_id):
return {'success': False, 'error': 'Model version already exists in embedding library'} return {'success': False, 'error': 'Model version already exists in embedding library'}
# Get metadata provider based on source parameter metadata_provider = await get_default_metadata_provider()
if source == 'civarchive':
from .metadata_service import get_metadata_provider
metadata_provider = await get_metadata_provider('civarchive')
else:
metadata_provider = await get_default_metadata_provider()
# Get version info based on the provided identifier # Get version info based on the provided identifier
version_info = await metadata_provider.get_model_version(model_id, model_version_id) version_info = await metadata_provider.get_model_version(model_id, model_version_id)

View File

@@ -569,9 +569,15 @@ export class BaseModelApiClient {
} }
} }
async fetchCivitaiVersions(modelId) { async fetchCivitaiVersions(modelId, source = null) {
try { try {
const response = await fetch(`${this.apiConfig.endpoints.civitaiVersions}/${modelId}`); let requestUrl = `${this.apiConfig.endpoints.civitaiVersions}/${modelId}`;
if (source) {
const params = new URLSearchParams({ source });
requestUrl = `${requestUrl}?${params.toString()}`;
}
const response = await fetch(requestUrl);
if (!response.ok) { if (!response.ok) {
const errorData = await response.json().catch(() => ({})); const errorData = await response.json().catch(() => ({}));
if (errorData && errorData.error && errorData.error.includes('Model type mismatch')) { if (errorData && errorData.error && errorData.error.includes('Model type mismatch')) {
@@ -639,7 +645,7 @@ export class BaseModelApiClient {
} }
} }
async downloadModel(modelId, versionId, modelRoot, relativePath, useDefaultPaths = false, downloadId) { async downloadModel(modelId, versionId, modelRoot, relativePath, useDefaultPaths = false, downloadId, source = null) {
try { try {
const response = await fetch(DOWNLOAD_ENDPOINTS.download, { const response = await fetch(DOWNLOAD_ENDPOINTS.download, {
method: 'POST', method: 'POST',
@@ -650,7 +656,8 @@ export class BaseModelApiClient {
model_root: modelRoot, model_root: modelRoot,
relative_path: relativePath, relative_path: relativePath,
use_default_paths: useDefaultPaths, use_default_paths: useDefaultPaths,
download_id: downloadId download_id: downloadId,
...(source ? { source } : {})
}) })
}); });

View File

@@ -14,6 +14,7 @@ export class DownloadManager {
this.modelInfo = null; this.modelInfo = null;
this.modelVersionId = null; this.modelVersionId = null;
this.modelId = null; this.modelId = null;
this.source = null;
this.initialized = false; this.initialized = false;
this.selectedFolder = ''; this.selectedFolder = '';
@@ -126,6 +127,7 @@ export class DownloadManager {
this.modelInfo = null; this.modelInfo = null;
this.modelId = null; this.modelId = null;
this.modelVersionId = null; this.modelVersionId = null;
this.source = null;
this.selectedFolder = ''; this.selectedFolder = '';
@@ -150,7 +152,7 @@ export class DownloadManager {
throw new Error(translate('modals.download.errors.invalidUrl')); throw new Error(translate('modals.download.errors.invalidUrl'));
} }
this.versions = await this.apiClient.fetchCivitaiVersions(this.modelId); this.versions = await this.apiClient.fetchCivitaiVersions(this.modelId, this.source);
if (!this.versions.length) { if (!this.versions.length) {
throw new Error(translate('modals.download.errors.noVersions')); throw new Error(translate('modals.download.errors.noVersions'));
@@ -170,13 +172,22 @@ export class DownloadManager {
} }
extractModelId(url) { extractModelId(url) {
const modelMatch = url.match(/civitai\.com\/models\/(\d+)/); const versionMatch = url.match(/modelVersionId=(\d+)/i);
const versionMatch = url.match(/modelVersionId=(\d+)/); this.modelVersionId = versionMatch ? versionMatch[1] : null;
if (modelMatch) { const civarchiveMatch = url.match(/https?:\/\/(?:www\.)?(?:civitaiarchive|civarchive)\.com\/models\/(\d+)/i);
this.modelVersionId = versionMatch ? versionMatch[1] : null; if (civarchiveMatch) {
return modelMatch[1]; this.source = 'civarchive';
return civarchiveMatch[1];
} }
const civitaiMatch = url.match(/https?:\/\/(?:www\.)?civitai\.com\/models\/(\d+)/i);
if (civitaiMatch) {
this.source = null;
return civitaiMatch[1];
}
this.source = null;
return null; return null;
} }
@@ -484,7 +495,8 @@ export class DownloadManager {
modelRoot, modelRoot,
targetFolder, targetFolder,
useDefaultPaths, useDefaultPaths,
downloadId downloadId,
this.source
); );
showToast('toast.loras.downloadCompleted', {}, 'success'); showToast('toast.loras.downloadCompleted', {}, 'success');