mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-22 05:32:12 -03:00
- Updated all relevant routes in `stats_routes.py` and `update_routes.py` to include the new '/api/lm/' prefix for consistency. - Modified API endpoint configurations in `apiConfig.js` to reflect the new structure, ensuring all CRUD and bulk operations are correctly routed. - Adjusted fetch calls in various components and managers to utilize the updated API paths, including recipe, model, and example image operations. - Ensured all instances of the old API paths were replaced with the new '/api/lm/' prefix across the codebase for uniformity and to prevent broken links.
210 lines
7.6 KiB
JavaScript
210 lines
7.6 KiB
JavaScript
import { showToast } from '../../utils/uiHelpers.js';
|
|
import { translate } from '../../utils/i18nHelpers.js';
|
|
|
|
export class ImageProcessor {
|
|
constructor(importManager) {
|
|
this.importManager = importManager;
|
|
}
|
|
|
|
handleFileUpload(event) {
|
|
const file = event.target.files[0];
|
|
const errorElement = document.getElementById('uploadError');
|
|
|
|
if (!file) return;
|
|
|
|
// Validate file type
|
|
if (!file.type.match('image.*')) {
|
|
errorElement.textContent = translate('recipes.controls.import.errors.selectImageFile', {}, 'Please select an image file');
|
|
return;
|
|
}
|
|
|
|
// Reset error
|
|
errorElement.textContent = '';
|
|
this.importManager.recipeImage = file;
|
|
|
|
// Auto-proceed to next step if file is selected
|
|
this.importManager.uploadAndAnalyzeImage();
|
|
}
|
|
|
|
async handleUrlInput() {
|
|
const urlInput = document.getElementById('imageUrlInput');
|
|
const errorElement = document.getElementById('importUrlError');
|
|
const input = urlInput.value.trim();
|
|
|
|
// Validate input
|
|
if (!input) {
|
|
errorElement.textContent = translate('recipes.controls.import.errors.enterUrlOrPath', {}, 'Please enter a URL or file path');
|
|
return;
|
|
}
|
|
|
|
// Reset error
|
|
errorElement.textContent = '';
|
|
|
|
// Show loading indicator
|
|
this.importManager.loadingManager.showSimpleLoading(translate('recipes.controls.import.processingInput', {}, 'Processing input...'));
|
|
|
|
try {
|
|
// Check if it's a URL or a local file path
|
|
if (input.startsWith('http://') || input.startsWith('https://')) {
|
|
// Handle as URL
|
|
await this.analyzeImageFromUrl(input);
|
|
} else {
|
|
// Handle as local file path
|
|
await this.analyzeImageFromLocalPath(input);
|
|
}
|
|
} catch (error) {
|
|
errorElement.textContent = error.message || 'Failed to process input';
|
|
} finally {
|
|
this.importManager.loadingManager.hide();
|
|
}
|
|
}
|
|
|
|
async analyzeImageFromUrl(url) {
|
|
try {
|
|
// Call the API with URL data
|
|
const response = await fetch('/api/lm/recipes/analyze-image', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({ url: url })
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const errorData = await response.json();
|
|
throw new Error(errorData.error || 'Failed to analyze image from URL');
|
|
}
|
|
|
|
// Get recipe data from response
|
|
this.importManager.recipeData = await response.json();
|
|
|
|
// Check if we have an error message
|
|
if (this.importManager.recipeData.error) {
|
|
throw new Error(this.importManager.recipeData.error);
|
|
}
|
|
|
|
// Check if we have valid recipe data
|
|
if (!this.importManager.recipeData ||
|
|
!this.importManager.recipeData.loras ||
|
|
this.importManager.recipeData.loras.length === 0) {
|
|
throw new Error('No LoRA information found in this image');
|
|
}
|
|
|
|
// Find missing LoRAs
|
|
this.importManager.missingLoras = this.importManager.recipeData.loras.filter(
|
|
lora => !lora.existsLocally
|
|
);
|
|
|
|
// Reset import as new flag
|
|
this.importManager.importAsNew = false;
|
|
|
|
// Proceed to recipe details step
|
|
this.importManager.showRecipeDetailsStep();
|
|
|
|
} catch (error) {
|
|
console.error('Error analyzing URL:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async analyzeImageFromLocalPath(path) {
|
|
try {
|
|
// Call the API with local path data
|
|
const response = await fetch('/api/lm/recipes/analyze-local-image', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({ path: path })
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const errorData = await response.json();
|
|
throw new Error(errorData.error || 'Failed to load image from local path');
|
|
}
|
|
|
|
// Get recipe data from response
|
|
this.importManager.recipeData = await response.json();
|
|
|
|
// Check if we have an error message
|
|
if (this.importManager.recipeData.error) {
|
|
throw new Error(this.importManager.recipeData.error);
|
|
}
|
|
|
|
// Check if we have valid recipe data
|
|
if (!this.importManager.recipeData ||
|
|
!this.importManager.recipeData.loras ||
|
|
this.importManager.recipeData.loras.length === 0) {
|
|
throw new Error('No LoRA information found in this image');
|
|
}
|
|
|
|
// Find missing LoRAs
|
|
this.importManager.missingLoras = this.importManager.recipeData.loras.filter(
|
|
lora => !lora.existsLocally
|
|
);
|
|
|
|
// Reset import as new flag
|
|
this.importManager.importAsNew = false;
|
|
|
|
// Proceed to recipe details step
|
|
this.importManager.showRecipeDetailsStep();
|
|
|
|
} catch (error) {
|
|
console.error('Error analyzing local path:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async uploadAndAnalyzeImage() {
|
|
if (!this.importManager.recipeImage) {
|
|
showToast('toast.recipes.selectImageFirst', {}, 'error');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
this.importManager.loadingManager.showSimpleLoading(translate('recipes.controls.import.analyzingMetadata', {}, 'Analyzing image metadata...'));
|
|
|
|
// Create form data for upload
|
|
const formData = new FormData();
|
|
formData.append('image', this.importManager.recipeImage);
|
|
|
|
// Upload image for analysis
|
|
const response = await fetch('/api/lm/recipes/analyze-image', {
|
|
method: 'POST',
|
|
body: formData
|
|
});
|
|
|
|
// Get recipe data from response
|
|
this.importManager.recipeData = await response.json();
|
|
|
|
// Check if we have an error message
|
|
if (this.importManager.recipeData.error) {
|
|
throw new Error(this.importManager.recipeData.error);
|
|
}
|
|
|
|
// Check if we have valid recipe data
|
|
if (!this.importManager.recipeData ||
|
|
!this.importManager.recipeData.loras ||
|
|
this.importManager.recipeData.loras.length === 0) {
|
|
throw new Error('No LoRA information found in this image');
|
|
}
|
|
|
|
// Find missing LoRAs
|
|
this.importManager.missingLoras = this.importManager.recipeData.loras.filter(
|
|
lora => !lora.existsLocally
|
|
);
|
|
|
|
// Reset import as new flag
|
|
this.importManager.importAsNew = false;
|
|
|
|
// Proceed to recipe details step
|
|
this.importManager.showRecipeDetailsStep();
|
|
|
|
} catch (error) {
|
|
document.getElementById('uploadError').textContent = error.message;
|
|
} finally {
|
|
this.importManager.loadingManager.hide();
|
|
}
|
|
}
|
|
}
|