mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-25 07:05:43 -03:00
feat: Add support for remote video analysis and preview for recipe imports. see #420
This commit is contained in:
@@ -12,21 +12,21 @@ export class DownloadManager {
|
||||
async saveRecipe() {
|
||||
// Check if we're in download-only mode (for existing recipe)
|
||||
const isDownloadOnly = !!this.importManager.recipeId;
|
||||
|
||||
|
||||
if (!isDownloadOnly && !this.importManager.recipeName) {
|
||||
showToast('toast.recipes.enterRecipeName', {}, 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
// Show progress indicator
|
||||
this.importManager.loadingManager.showSimpleLoading(isDownloadOnly ? translate('recipes.controls.import.downloadingLoras', {}, 'Downloading LoRAs...') : translate('recipes.controls.import.savingRecipe', {}, 'Saving recipe...'));
|
||||
|
||||
|
||||
// Only send the complete recipe to save if not in download-only mode
|
||||
if (!isDownloadOnly) {
|
||||
// Create FormData object for saving recipe
|
||||
const formData = new FormData();
|
||||
|
||||
|
||||
// Add image data - depends on import mode
|
||||
if (this.importManager.recipeImage) {
|
||||
// Direct upload
|
||||
@@ -45,10 +45,10 @@ export class DownloadManager {
|
||||
} else {
|
||||
throw new Error('No image data available');
|
||||
}
|
||||
|
||||
|
||||
formData.append('name', this.importManager.recipeName);
|
||||
formData.append('tags', JSON.stringify(this.importManager.recipeTags));
|
||||
|
||||
|
||||
// Prepare complete metadata including generation parameters
|
||||
const completeMetadata = {
|
||||
base_model: this.importManager.recipeData.base_model || "",
|
||||
@@ -65,7 +65,11 @@ export class DownloadManager {
|
||||
if (checkpointMetadata && typeof checkpointMetadata === 'object') {
|
||||
completeMetadata.checkpoint = checkpointMetadata;
|
||||
}
|
||||
|
||||
|
||||
if (this.importManager.recipeData && this.importManager.recipeData.extension) {
|
||||
formData.append('extension', this.importManager.recipeData.extension);
|
||||
}
|
||||
|
||||
// Add source_path to metadata to track where the recipe was imported from
|
||||
if (this.importManager.importMode === 'url') {
|
||||
const urlInput = document.getElementById('imageUrlInput');
|
||||
@@ -73,15 +77,15 @@ export class DownloadManager {
|
||||
completeMetadata.source_path = urlInput.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
formData.append('metadata', JSON.stringify(completeMetadata));
|
||||
|
||||
|
||||
// Send save request
|
||||
const response = await fetch('/api/lm/recipes/save', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (!result.success) {
|
||||
@@ -102,19 +106,19 @@ export class DownloadManager {
|
||||
|
||||
// Show success message
|
||||
if (isDownloadOnly) {
|
||||
if (failedDownloads === 0) {
|
||||
if (failedDownloads === 0) {
|
||||
showToast('toast.loras.downloadSuccessful', {}, 'success');
|
||||
}
|
||||
} else {
|
||||
showToast('toast.recipes.nameSaved', { name: this.importManager.recipeName }, 'success');
|
||||
}
|
||||
|
||||
|
||||
// Close modal
|
||||
modalManager.closeModal('importModal');
|
||||
|
||||
|
||||
// Refresh the recipe
|
||||
window.recipeManager.loadRecipes();
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
showToast('toast.recipes.processingError', { message: error.message }, 'error');
|
||||
@@ -129,49 +133,49 @@ export class DownloadManager {
|
||||
if (!loraRoot) {
|
||||
throw new Error(translate('recipes.controls.import.errors.selectLoraRoot', {}, 'Please select a LoRA root directory'));
|
||||
}
|
||||
|
||||
|
||||
// Build target path
|
||||
let targetPath = '';
|
||||
if (this.importManager.selectedFolder) {
|
||||
targetPath = this.importManager.selectedFolder;
|
||||
}
|
||||
|
||||
|
||||
// Generate a unique ID for this batch download
|
||||
const batchDownloadId = Date.now().toString();
|
||||
|
||||
|
||||
// Set up WebSocket for progress updates
|
||||
const wsProtocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
||||
const ws = new WebSocket(`${wsProtocol}${window.location.host}/ws/download-progress?id=${batchDownloadId}`);
|
||||
|
||||
|
||||
// Show enhanced loading with progress details for multiple items
|
||||
const updateProgress = this.importManager.loadingManager.showDownloadProgress(
|
||||
this.importManager.downloadableLoRAs.length
|
||||
);
|
||||
|
||||
|
||||
let completedDownloads = 0;
|
||||
let failedDownloads = 0;
|
||||
let accessFailures = 0;
|
||||
let currentLoraProgress = 0;
|
||||
|
||||
|
||||
// Set up progress tracking for current download
|
||||
ws.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
|
||||
|
||||
// Handle download ID confirmation
|
||||
if (data.type === 'download_id') {
|
||||
console.log(`Connected to batch download progress with ID: ${data.download_id}`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Process progress updates for our current active download
|
||||
if (data.status === 'progress' && data.download_id && data.download_id.startsWith(batchDownloadId)) {
|
||||
// Update current LoRA progress
|
||||
currentLoraProgress = data.progress;
|
||||
|
||||
|
||||
// Get current LoRA name
|
||||
const currentLora = this.importManager.downloadableLoRAs[completedDownloads + failedDownloads];
|
||||
const loraName = currentLora ? currentLora.name : '';
|
||||
|
||||
|
||||
// Update progress display
|
||||
const metrics = {
|
||||
bytesDownloaded: data.bytes_downloaded,
|
||||
@@ -180,7 +184,7 @@ export class DownloadManager {
|
||||
};
|
||||
|
||||
updateProgress(currentLoraProgress, completedDownloads, loraName, metrics);
|
||||
|
||||
|
||||
// Add more detailed status messages based on progress
|
||||
if (currentLoraProgress < 3) {
|
||||
this.importManager.loadingManager.setStatus(
|
||||
@@ -203,17 +207,17 @@ export class DownloadManager {
|
||||
};
|
||||
|
||||
const useDefaultPaths = getStorageItem('use_default_path_loras', false);
|
||||
|
||||
|
||||
for (let i = 0; i < this.importManager.downloadableLoRAs.length; i++) {
|
||||
const lora = this.importManager.downloadableLoRAs[i];
|
||||
|
||||
|
||||
// Reset current LoRA progress for new download
|
||||
currentLoraProgress = 0;
|
||||
|
||||
|
||||
// Initial status update for new LoRA
|
||||
this.importManager.loadingManager.setStatus(translate('recipes.controls.import.startingDownload', { current: i+1, total: this.importManager.downloadableLoRAs.length }, `Starting download for LoRA ${i+1}/${this.importManager.downloadableLoRAs.length}`));
|
||||
this.importManager.loadingManager.setStatus(translate('recipes.controls.import.startingDownload', { current: i + 1, total: this.importManager.downloadableLoRAs.length }, `Starting download for LoRA ${i + 1}/${this.importManager.downloadableLoRAs.length}`));
|
||||
updateProgress(0, completedDownloads, lora.name);
|
||||
|
||||
|
||||
try {
|
||||
// Download the LoRA with download ID
|
||||
const response = await getModelApiClient(MODEL_TYPES.LORA).downloadModel(
|
||||
@@ -224,7 +228,7 @@ export class DownloadManager {
|
||||
useDefaultPaths,
|
||||
batchDownloadId
|
||||
);
|
||||
|
||||
|
||||
if (!response.success) {
|
||||
console.error(`Failed to download LoRA ${lora.name}: ${response.error}`);
|
||||
|
||||
@@ -248,28 +252,28 @@ export class DownloadManager {
|
||||
// Continue with next download
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Close WebSocket
|
||||
ws.close();
|
||||
|
||||
|
||||
// Show appropriate completion message based on results
|
||||
if (failedDownloads === 0) {
|
||||
showToast('toast.loras.allDownloadSuccessful', { count: completedDownloads }, 'success');
|
||||
} else {
|
||||
if (accessFailures > 0) {
|
||||
showToast('toast.loras.downloadPartialWithAccess', {
|
||||
completed: completedDownloads,
|
||||
showToast('toast.loras.downloadPartialWithAccess', {
|
||||
completed: completedDownloads,
|
||||
total: this.importManager.downloadableLoRAs.length,
|
||||
accessFailures: accessFailures
|
||||
}, 'error');
|
||||
} else {
|
||||
showToast('toast.loras.downloadPartialSuccess', {
|
||||
completed: completedDownloads,
|
||||
total: this.importManager.downloadableLoRAs.length
|
||||
showToast('toast.loras.downloadPartialSuccess', {
|
||||
completed: completedDownloads,
|
||||
total: this.importManager.downloadableLoRAs.length
|
||||
}, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return failedDownloads;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user