From bdc86ddf1596338c6b010ce783dd3b295216e128 Mon Sep 17 00:00:00 2001 From: Will Miao <13051207myq@gmail.com> Date: Thu, 18 Sep 2025 14:50:40 +0800 Subject: [PATCH] Refactor API endpoints to use '/api/lm/' prefix - 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. --- py/routes/base_model_routes.py | 78 +++++++-------- py/routes/checkpoint_routes.py | 6 +- py/routes/embedding_routes.py | 2 +- py/routes/example_images_routes.py | 20 ++-- py/routes/lora_routes.py | 8 +- py/routes/misc_routes.py | 28 +++--- py/routes/recipe_routes.py | 36 +++---- py/routes/stats_routes.py | 12 +-- py/routes/update_routes.py | 6 +- static/js/api/apiConfig.js | 94 +++++++++---------- static/js/api/recipeApi.js | 8 +- .../ContextMenu/ModelContextMenuMixin.js | 4 +- .../ContextMenu/RecipeContextMenu.js | 12 +-- static/js/components/DuplicatesManager.js | 4 +- .../js/components/ModelDuplicatesManager.js | 10 +- static/js/components/RecipeCard.js | 6 +- static/js/components/RecipeModal.js | 8 +- static/js/components/alphabet/AlphabetBar.js | 2 +- static/js/components/initialization.js | 2 +- static/js/components/shared/ModelCard.js | 2 +- static/js/components/shared/ModelModal.js | 2 +- static/js/components/shared/RecipeTab.js | 4 +- static/js/components/shared/TriggerWords.js | 2 +- .../components/shared/showcase/MediaUtils.js | 2 +- .../shared/showcase/ShowcaseView.js | 6 +- static/js/managers/ExampleImagesManager.js | 12 +-- static/js/managers/FilterManager.js | 4 +- static/js/managers/SettingsManager.js | 12 +-- static/js/managers/UpdateService.js | 6 +- static/js/managers/import/DownloadManager.js | 2 +- static/js/managers/import/FolderBrowser.js | 4 +- static/js/managers/import/ImageProcessor.js | 6 +- static/js/statistics.js | 12 +-- static/js/utils/uiHelpers.js | 6 +- web/comfyui/autocomplete.js | 4 +- web/comfyui/loras_widget_components.js | 2 +- web/comfyui/loras_widget_events.js | 6 +- web/comfyui/loras_widget_utils.js | 2 +- web/comfyui/ui_utils.js | 2 +- web/comfyui/usage_stats.js | 6 +- 40 files changed, 225 insertions(+), 225 deletions(-) diff --git a/py/routes/base_model_routes.py b/py/routes/base_model_routes.py index 499d4617..2b2f7a7c 100644 --- a/py/routes/base_model_routes.py +++ b/py/routes/base_model_routes.py @@ -48,53 +48,53 @@ class BaseModelRoutes(ABC): prefix: URL prefix (e.g., 'loras', 'checkpoints') """ # Common model management routes - app.router.add_get(f'/api/{prefix}/list', self.get_models) - app.router.add_post(f'/api/{prefix}/delete', self.delete_model) - app.router.add_post(f'/api/{prefix}/exclude', self.exclude_model) - app.router.add_post(f'/api/{prefix}/fetch-civitai', self.fetch_civitai) - app.router.add_post(f'/api/{prefix}/fetch-all-civitai', self.fetch_all_civitai) - app.router.add_post(f'/api/{prefix}/relink-civitai', self.relink_civitai) - app.router.add_post(f'/api/{prefix}/replace-preview', self.replace_preview) - app.router.add_post(f'/api/{prefix}/save-metadata', self.save_metadata) - app.router.add_post(f'/api/{prefix}/add-tags', self.add_tags) - app.router.add_post(f'/api/{prefix}/rename', self.rename_model) - app.router.add_post(f'/api/{prefix}/bulk-delete', self.bulk_delete_models) - app.router.add_post(f'/api/{prefix}/verify-duplicates', self.verify_duplicates) - app.router.add_post(f'/api/{prefix}/move_model', self.move_model) - app.router.add_post(f'/api/{prefix}/move_models_bulk', self.move_models_bulk) - app.router.add_get(f'/api/{prefix}/auto-organize', self.auto_organize_models) - app.router.add_post(f'/api/{prefix}/auto-organize', self.auto_organize_models) - app.router.add_get(f'/api/{prefix}/auto-organize-progress', self.get_auto_organize_progress) + app.router.add_get(f'/api/lm/{prefix}/list', self.get_models) + app.router.add_post(f'/api/lm/{prefix}/delete', self.delete_model) + app.router.add_post(f'/api/lm/{prefix}/exclude', self.exclude_model) + app.router.add_post(f'/api/lm/{prefix}/fetch-civitai', self.fetch_civitai) + app.router.add_post(f'/api/lm/{prefix}/fetch-all-civitai', self.fetch_all_civitai) + app.router.add_post(f'/api/lm/{prefix}/relink-civitai', self.relink_civitai) + app.router.add_post(f'/api/lm/{prefix}/replace-preview', self.replace_preview) + app.router.add_post(f'/api/lm/{prefix}/save-metadata', self.save_metadata) + app.router.add_post(f'/api/lm/{prefix}/add-tags', self.add_tags) + app.router.add_post(f'/api/lm/{prefix}/rename', self.rename_model) + app.router.add_post(f'/api/lm/{prefix}/bulk-delete', self.bulk_delete_models) + app.router.add_post(f'/api/lm/{prefix}/verify-duplicates', self.verify_duplicates) + app.router.add_post(f'/api/lm/{prefix}/move_model', self.move_model) + app.router.add_post(f'/api/lm/{prefix}/move_models_bulk', self.move_models_bulk) + app.router.add_get(f'/api/lm/{prefix}/auto-organize', self.auto_organize_models) + app.router.add_post(f'/api/lm/{prefix}/auto-organize', self.auto_organize_models) + app.router.add_get(f'/api/lm/{prefix}/auto-organize-progress', self.get_auto_organize_progress) # Common query routes - app.router.add_get(f'/api/{prefix}/top-tags', self.get_top_tags) - app.router.add_get(f'/api/{prefix}/base-models', self.get_base_models) - app.router.add_get(f'/api/{prefix}/scan', self.scan_models) - app.router.add_get(f'/api/{prefix}/roots', self.get_model_roots) - app.router.add_get(f'/api/{prefix}/folders', self.get_folders) - app.router.add_get(f'/api/{prefix}/folder-tree', self.get_folder_tree) - app.router.add_get(f'/api/{prefix}/unified-folder-tree', self.get_unified_folder_tree) - app.router.add_get(f'/api/{prefix}/find-duplicates', self.find_duplicate_models) - app.router.add_get(f'/api/{prefix}/find-filename-conflicts', self.find_filename_conflicts) - app.router.add_get(f'/api/{prefix}/get-notes', self.get_model_notes) - app.router.add_get(f'/api/{prefix}/preview-url', self.get_model_preview_url) - app.router.add_get(f'/api/{prefix}/civitai-url', self.get_model_civitai_url) - app.router.add_get(f'/api/{prefix}/metadata', self.get_model_metadata) - app.router.add_get(f'/api/{prefix}/model-description', self.get_model_description) + app.router.add_get(f'/api/lm/{prefix}/top-tags', self.get_top_tags) + app.router.add_get(f'/api/lm/{prefix}/base-models', self.get_base_models) + app.router.add_get(f'/api/lm/{prefix}/scan', self.scan_models) + app.router.add_get(f'/api/lm/{prefix}/roots', self.get_model_roots) + app.router.add_get(f'/api/lm/{prefix}/folders', self.get_folders) + app.router.add_get(f'/api/lm/{prefix}/folder-tree', self.get_folder_tree) + app.router.add_get(f'/api/lm/{prefix}/unified-folder-tree', self.get_unified_folder_tree) + app.router.add_get(f'/api/lm/{prefix}/find-duplicates', self.find_duplicate_models) + app.router.add_get(f'/api/lm/{prefix}/find-filename-conflicts', self.find_filename_conflicts) + app.router.add_get(f'/api/lm/{prefix}/get-notes', self.get_model_notes) + app.router.add_get(f'/api/lm/{prefix}/preview-url', self.get_model_preview_url) + app.router.add_get(f'/api/lm/{prefix}/civitai-url', self.get_model_civitai_url) + app.router.add_get(f'/api/lm/{prefix}/metadata', self.get_model_metadata) + app.router.add_get(f'/api/lm/{prefix}/model-description', self.get_model_description) # Autocomplete route - app.router.add_get(f'/api/{prefix}/relative-paths', self.get_relative_paths) + app.router.add_get(f'/api/lm/{prefix}/relative-paths', self.get_relative_paths) # Common CivitAI integration - app.router.add_get(f'/api/{prefix}/civitai/versions/{{model_id}}', self.get_civitai_versions) - app.router.add_get(f'/api/{prefix}/civitai/model/version/{{modelVersionId}}', self.get_civitai_model_by_version) - app.router.add_get(f'/api/{prefix}/civitai/model/hash/{{hash}}', self.get_civitai_model_by_hash) + app.router.add_get(f'/api/lm/{prefix}/civitai/versions/{{model_id}}', self.get_civitai_versions) + app.router.add_get(f'/api/lm/{prefix}/civitai/model/version/{{modelVersionId}}', self.get_civitai_model_by_version) + app.router.add_get(f'/api/lm/{prefix}/civitai/model/hash/{{hash}}', self.get_civitai_model_by_hash) # Common Download management - app.router.add_post(f'/api/download-model', self.download_model) - app.router.add_get(f'/api/download-model-get', self.download_model_get) - app.router.add_get(f'/api/cancel-download-get', self.cancel_download_get) - app.router.add_get(f'/api/download-progress/{{download_id}}', self.get_download_progress) + app.router.add_post(f'/api/lm/download-model', self.download_model) + app.router.add_get(f'/api/lm/download-model-get', self.download_model_get) + app.router.add_get(f'/api/lm/cancel-download-get', self.cancel_download_get) + app.router.add_get(f'/api/lm/download-progress/{{download_id}}', self.get_download_progress) # Add generic page route app.router.add_get(f'/{prefix}', self.handle_models_page) diff --git a/py/routes/checkpoint_routes.py b/py/routes/checkpoint_routes.py index 712eaafc..95c747e5 100644 --- a/py/routes/checkpoint_routes.py +++ b/py/routes/checkpoint_routes.py @@ -37,11 +37,11 @@ class CheckpointRoutes(BaseModelRoutes): def setup_specific_routes(self, app: web.Application, prefix: str): """Setup Checkpoint-specific routes""" # Checkpoint info by name - app.router.add_get(f'/api/{prefix}/info/{{name}}', self.get_checkpoint_info) + app.router.add_get(f'/api/lm/{prefix}/info/{{name}}', self.get_checkpoint_info) # Checkpoint roots and Unet roots - app.router.add_get(f'/api/{prefix}/checkpoints_roots', self.get_checkpoints_roots) - app.router.add_get(f'/api/{prefix}/unet_roots', self.get_unet_roots) + app.router.add_get(f'/api/lm/{prefix}/checkpoints_roots', self.get_checkpoints_roots) + app.router.add_get(f'/api/lm/{prefix}/unet_roots', self.get_unet_roots) def _validate_civitai_model_type(self, model_type: str) -> bool: """Validate CivitAI model type for Checkpoint""" diff --git a/py/routes/embedding_routes.py b/py/routes/embedding_routes.py index eefa8bdd..29b2f9fd 100644 --- a/py/routes/embedding_routes.py +++ b/py/routes/embedding_routes.py @@ -36,7 +36,7 @@ class EmbeddingRoutes(BaseModelRoutes): def setup_specific_routes(self, app: web.Application, prefix: str): """Setup Embedding-specific routes""" # Embedding info by name - app.router.add_get(f'/api/{prefix}/info/{{name}}', self.get_embedding_info) + app.router.add_get(f'/api/lm/{prefix}/info/{{name}}', self.get_embedding_info) def _validate_civitai_model_type(self, model_type: str) -> bool: """Validate CivitAI model type for Embedding""" diff --git a/py/routes/example_images_routes.py b/py/routes/example_images_routes.py index 9f20b470..07cb0e71 100644 --- a/py/routes/example_images_routes.py +++ b/py/routes/example_images_routes.py @@ -12,16 +12,16 @@ class ExampleImagesRoutes: @staticmethod def setup_routes(app): """Register example images routes""" - app.router.add_post('/api/download-example-images', ExampleImagesRoutes.download_example_images) - app.router.add_post('/api/import-example-images', ExampleImagesRoutes.import_example_images) - app.router.add_get('/api/example-images-status', ExampleImagesRoutes.get_example_images_status) - app.router.add_post('/api/pause-example-images', ExampleImagesRoutes.pause_example_images) - app.router.add_post('/api/resume-example-images', ExampleImagesRoutes.resume_example_images) - app.router.add_post('/api/open-example-images-folder', ExampleImagesRoutes.open_example_images_folder) - app.router.add_get('/api/example-image-files', ExampleImagesRoutes.get_example_image_files) - app.router.add_get('/api/has-example-images', ExampleImagesRoutes.has_example_images) - app.router.add_post('/api/delete-example-image', ExampleImagesRoutes.delete_example_image) - app.router.add_post('/api/force-download-example-images', ExampleImagesRoutes.force_download_example_images) + app.router.add_post('/api/lm/download-example-images', ExampleImagesRoutes.download_example_images) + app.router.add_post('/api/lm/import-example-images', ExampleImagesRoutes.import_example_images) + app.router.add_get('/api/lm/example-images-status', ExampleImagesRoutes.get_example_images_status) + app.router.add_post('/api/lm/pause-example-images', ExampleImagesRoutes.pause_example_images) + app.router.add_post('/api/lm/resume-example-images', ExampleImagesRoutes.resume_example_images) + app.router.add_post('/api/lm/open-example-images-folder', ExampleImagesRoutes.open_example_images_folder) + app.router.add_get('/api/lm/example-image-files', ExampleImagesRoutes.get_example_image_files) + app.router.add_get('/api/lm/has-example-images', ExampleImagesRoutes.has_example_images) + app.router.add_post('/api/lm/delete-example-image', ExampleImagesRoutes.delete_example_image) + app.router.add_post('/api/lm/force-download-example-images', ExampleImagesRoutes.force_download_example_images) @staticmethod async def download_example_images(request): diff --git a/py/routes/lora_routes.py b/py/routes/lora_routes.py index d70a2801..0ddb41ab 100644 --- a/py/routes/lora_routes.py +++ b/py/routes/lora_routes.py @@ -40,12 +40,12 @@ class LoraRoutes(BaseModelRoutes): def setup_specific_routes(self, app: web.Application, prefix: str): """Setup LoRA-specific routes""" # LoRA-specific query routes - app.router.add_get(f'/api/{prefix}/letter-counts', self.get_letter_counts) - app.router.add_get(f'/api/{prefix}/get-trigger-words', self.get_lora_trigger_words) - app.router.add_get(f'/api/{prefix}/usage-tips-by-path', self.get_lora_usage_tips_by_path) + app.router.add_get(f'/api/lm/{prefix}/letter-counts', self.get_letter_counts) + app.router.add_get(f'/api/lm/{prefix}/get-trigger-words', self.get_lora_trigger_words) + app.router.add_get(f'/api/lm/{prefix}/usage-tips-by-path', self.get_lora_usage_tips_by_path) # ComfyUI integration - app.router.add_post(f'/api/{prefix}/get_trigger_words', self.get_trigger_words) + app.router.add_post(f'/api/lm/{prefix}/get_trigger_words', self.get_trigger_words) def _parse_specific_params(self, request: web.Request) -> Dict: """Parse LoRA-specific parameters""" diff --git a/py/routes/misc_routes.py b/py/routes/misc_routes.py index 5cae7002..90b7d578 100644 --- a/py/routes/misc_routes.py +++ b/py/routes/misc_routes.py @@ -91,37 +91,37 @@ class MiscRoutes: app.router.add_get('/api/lm/settings', MiscRoutes.get_settings) app.router.add_post('/api/lm/settings', MiscRoutes.update_settings) - app.router.add_get('/api/health-check', lambda request: web.json_response({'status': 'ok'})) + app.router.add_get('/api/lm/health-check', lambda request: web.json_response({'status': 'ok'})) - app.router.add_post('/api/open-file-location', MiscRoutes.open_file_location) + app.router.add_post('/api/lm/open-file-location', MiscRoutes.open_file_location) # Usage stats routes - app.router.add_post('/api/update-usage-stats', MiscRoutes.update_usage_stats) - app.router.add_get('/api/get-usage-stats', MiscRoutes.get_usage_stats) + app.router.add_post('/api/lm/update-usage-stats', MiscRoutes.update_usage_stats) + app.router.add_get('/api/lm/get-usage-stats', MiscRoutes.get_usage_stats) # Lora code update endpoint - app.router.add_post('/api/update-lora-code', MiscRoutes.update_lora_code) + app.router.add_post('/api/lm/update-lora-code', MiscRoutes.update_lora_code) # Add new route for getting trained words - app.router.add_get('/api/trained-words', MiscRoutes.get_trained_words) + app.router.add_get('/api/lm/trained-words', MiscRoutes.get_trained_words) # Add new route for getting model example files - app.router.add_get('/api/model-example-files', MiscRoutes.get_model_example_files) + app.router.add_get('/api/lm/model-example-files', MiscRoutes.get_model_example_files) # Node registry endpoints - app.router.add_post('/api/register-nodes', MiscRoutes.register_nodes) - app.router.add_get('/api/get-registry', MiscRoutes.get_registry) + app.router.add_post('/api/lm/register-nodes', MiscRoutes.register_nodes) + app.router.add_get('/api/lm/get-registry', MiscRoutes.get_registry) # Add new route for checking if a model exists in the library - app.router.add_get('/api/check-model-exists', MiscRoutes.check_model_exists) + app.router.add_get('/api/lm/check-model-exists', MiscRoutes.check_model_exists) # Add routes for metadata archive database management - app.router.add_post('/api/download-metadata-archive', MiscRoutes.download_metadata_archive) - app.router.add_post('/api/remove-metadata-archive', MiscRoutes.remove_metadata_archive) - app.router.add_get('/api/metadata-archive-status', MiscRoutes.get_metadata_archive_status) + app.router.add_post('/api/lm/download-metadata-archive', MiscRoutes.download_metadata_archive) + app.router.add_post('/api/lm/remove-metadata-archive', MiscRoutes.remove_metadata_archive) + app.router.add_get('/api/lm/metadata-archive-status', MiscRoutes.get_metadata_archive_status) # Add route for checking model versions in library - app.router.add_get('/api/model-versions-status', MiscRoutes.get_model_versions_status) + app.router.add_get('/api/lm/model-versions-status', MiscRoutes.get_model_versions_status) @staticmethod async def get_settings(request): diff --git a/py/routes/recipe_routes.py b/py/routes/recipe_routes.py index 003d869a..0c8843b4 100644 --- a/py/routes/recipe_routes.py +++ b/py/routes/recipe_routes.py @@ -61,46 +61,46 @@ class RecipeRoutes: routes = cls() app.router.add_get('/loras/recipes', routes.handle_recipes_page) - app.router.add_get('/api/recipes', routes.get_recipes) - app.router.add_get('/api/recipe/{recipe_id}', routes.get_recipe_detail) - app.router.add_post('/api/recipes/analyze-image', routes.analyze_recipe_image) - app.router.add_post('/api/recipes/analyze-local-image', routes.analyze_local_image) - app.router.add_post('/api/recipes/save', routes.save_recipe) - app.router.add_delete('/api/recipe/{recipe_id}', routes.delete_recipe) + app.router.add_get('/api/lm/recipes', routes.get_recipes) + app.router.add_get('/api/lm/recipe/{recipe_id}', routes.get_recipe_detail) + app.router.add_post('/api/lm/recipes/analyze-image', routes.analyze_recipe_image) + app.router.add_post('/api/lm/recipes/analyze-local-image', routes.analyze_local_image) + app.router.add_post('/api/lm/recipes/save', routes.save_recipe) + app.router.add_delete('/api/lm/recipe/{recipe_id}', routes.delete_recipe) # Add new filter-related endpoints - app.router.add_get('/api/recipes/top-tags', routes.get_top_tags) - app.router.add_get('/api/recipes/base-models', routes.get_base_models) + app.router.add_get('/api/lm/recipes/top-tags', routes.get_top_tags) + app.router.add_get('/api/lm/recipes/base-models', routes.get_base_models) # Add new sharing endpoints - app.router.add_get('/api/recipe/{recipe_id}/share', routes.share_recipe) - app.router.add_get('/api/recipe/{recipe_id}/share/download', routes.download_shared_recipe) + app.router.add_get('/api/lm/recipe/{recipe_id}/share', routes.share_recipe) + app.router.add_get('/api/lm/recipe/{recipe_id}/share/download', routes.download_shared_recipe) # Add new endpoint for getting recipe syntax - app.router.add_get('/api/recipe/{recipe_id}/syntax', routes.get_recipe_syntax) + app.router.add_get('/api/lm/recipe/{recipe_id}/syntax', routes.get_recipe_syntax) # Add new endpoint for updating recipe metadata (name, tags and source_path) - app.router.add_put('/api/recipe/{recipe_id}/update', routes.update_recipe) + app.router.add_put('/api/lm/recipe/{recipe_id}/update', routes.update_recipe) # Add new endpoint for reconnecting deleted LoRAs - app.router.add_post('/api/recipe/lora/reconnect', routes.reconnect_lora) + app.router.add_post('/api/lm/recipe/lora/reconnect', routes.reconnect_lora) # Add new endpoint for finding duplicate recipes - app.router.add_get('/api/recipes/find-duplicates', routes.find_duplicates) + app.router.add_get('/api/lm/recipes/find-duplicates', routes.find_duplicates) # Add new endpoint for bulk deletion of recipes - app.router.add_post('/api/recipes/bulk-delete', routes.bulk_delete) + app.router.add_post('/api/lm/recipes/bulk-delete', routes.bulk_delete) # Start cache initialization app.on_startup.append(routes._init_cache) - app.router.add_post('/api/recipes/save-from-widget', routes.save_recipe_from_widget) + app.router.add_post('/api/lm/recipes/save-from-widget', routes.save_recipe_from_widget) # Add route to get recipes for a specific Lora - app.router.add_get('/api/recipes/for-lora', routes.get_recipes_for_lora) + app.router.add_get('/api/lm/recipes/for-lora', routes.get_recipes_for_lora) # Add new endpoint for scanning and rebuilding the recipe cache - app.router.add_get('/api/recipes/scan', routes.scan_recipes) + app.router.add_get('/api/lm/recipes/scan', routes.scan_recipes) async def _init_cache(self, app): """Initialize cache on startup""" diff --git a/py/routes/stats_routes.py b/py/routes/stats_routes.py index b61762d1..f8c0aaa4 100644 --- a/py/routes/stats_routes.py +++ b/py/routes/stats_routes.py @@ -507,12 +507,12 @@ class StatsRoutes: app.router.add_get('/statistics', self.handle_stats_page) # Register API routes - app.router.add_get('/api/stats/collection-overview', self.get_collection_overview) - app.router.add_get('/api/stats/usage-analytics', self.get_usage_analytics) - app.router.add_get('/api/stats/base-model-distribution', self.get_base_model_distribution) - app.router.add_get('/api/stats/tag-analytics', self.get_tag_analytics) - app.router.add_get('/api/stats/storage-analytics', self.get_storage_analytics) - app.router.add_get('/api/stats/insights', self.get_insights) + app.router.add_get('/api/lm/stats/collection-overview', self.get_collection_overview) + app.router.add_get('/api/lm/stats/usage-analytics', self.get_usage_analytics) + app.router.add_get('/api/lm/stats/base-model-distribution', self.get_base_model_distribution) + app.router.add_get('/api/lm/stats/tag-analytics', self.get_tag_analytics) + app.router.add_get('/api/lm/stats/storage-analytics', self.get_storage_analytics) + app.router.add_get('/api/lm/stats/insights', self.get_insights) async def _on_startup(self, app): """Initialize services when the app starts""" diff --git a/py/routes/update_routes.py b/py/routes/update_routes.py index bf77baaf..2febfba3 100644 --- a/py/routes/update_routes.py +++ b/py/routes/update_routes.py @@ -17,9 +17,9 @@ class UpdateRoutes: @staticmethod def setup_routes(app): """Register update check routes""" - app.router.add_get('/api/check-updates', UpdateRoutes.check_updates) - app.router.add_get('/api/version-info', UpdateRoutes.get_version_info) - app.router.add_post('/api/perform-update', UpdateRoutes.perform_update) + app.router.add_get('/api/lm/check-updates', UpdateRoutes.check_updates) + app.router.add_get('/api/lm/version-info', UpdateRoutes.get_version_info) + app.router.add_post('/api/lm/perform-update', UpdateRoutes.perform_update) @staticmethod async def check_updates(request): diff --git a/static/js/api/apiConfig.js b/static/js/api/apiConfig.js index 33622dc5..aa168413 100644 --- a/static/js/api/apiConfig.js +++ b/static/js/api/apiConfig.js @@ -55,48 +55,48 @@ export function getApiEndpoints(modelType) { return { // Base CRUD operations - list: `/api/${modelType}/list`, - delete: `/api/${modelType}/delete`, - exclude: `/api/${modelType}/exclude`, - rename: `/api/${modelType}/rename`, - save: `/api/${modelType}/save-metadata`, + list: `/api/lm/${modelType}/list`, + delete: `/api/lm/${modelType}/delete`, + exclude: `/api/lm/${modelType}/exclude`, + rename: `/api/lm/${modelType}/rename`, + save: `/api/lm/${modelType}/save-metadata`, // Bulk operations - bulkDelete: `/api/${modelType}/bulk-delete`, + bulkDelete: `/api/lm/${modelType}/bulk-delete`, // Tag operations - addTags: `/api/${modelType}/add-tags`, + addTags: `/api/lm/${modelType}/add-tags`, // Move operations (now common for all model types that support move) - moveModel: `/api/${modelType}/move_model`, - moveBulk: `/api/${modelType}/move_models_bulk`, + moveModel: `/api/lm/${modelType}/move_model`, + moveBulk: `/api/lm/${modelType}/move_models_bulk`, // CivitAI integration - fetchCivitai: `/api/${modelType}/fetch-civitai`, - fetchAllCivitai: `/api/${modelType}/fetch-all-civitai`, - relinkCivitai: `/api/${modelType}/relink-civitai`, - civitaiVersions: `/api/${modelType}/civitai/versions`, + fetchCivitai: `/api/lm/${modelType}/fetch-civitai`, + fetchAllCivitai: `/api/lm/${modelType}/fetch-all-civitai`, + relinkCivitai: `/api/lm/${modelType}/relink-civitai`, + civitaiVersions: `/api/lm/${modelType}/civitai/versions`, // Preview management - replacePreview: `/api/${modelType}/replace-preview`, + replacePreview: `/api/lm/${modelType}/replace-preview`, // Query operations - scan: `/api/${modelType}/scan`, - topTags: `/api/${modelType}/top-tags`, - baseModels: `/api/${modelType}/base-models`, - roots: `/api/${modelType}/roots`, - folders: `/api/${modelType}/folders`, - folderTree: `/api/${modelType}/folder-tree`, - unifiedFolderTree: `/api/${modelType}/unified-folder-tree`, - duplicates: `/api/${modelType}/find-duplicates`, - conflicts: `/api/${modelType}/find-filename-conflicts`, - verify: `/api/${modelType}/verify-duplicates`, - metadata: `/api/${modelType}/metadata`, - modelDescription: `/api/${modelType}/model-description`, + scan: `/api/lm/${modelType}/scan`, + topTags: `/api/lm/${modelType}/top-tags`, + baseModels: `/api/lm/${modelType}/base-models`, + roots: `/api/lm/${modelType}/roots`, + folders: `/api/lm/${modelType}/folders`, + folderTree: `/api/lm/${modelType}/folder-tree`, + unifiedFolderTree: `/api/lm/${modelType}/unified-folder-tree`, + duplicates: `/api/lm/${modelType}/find-duplicates`, + conflicts: `/api/lm/${modelType}/find-filename-conflicts`, + verify: `/api/lm/${modelType}/verify-duplicates`, + metadata: `/api/lm/${modelType}/metadata`, + modelDescription: `/api/lm/${modelType}/model-description`, // Auto-organize operations - autoOrganize: `/api/${modelType}/auto-organize`, - autoOrganizeProgress: `/api/${modelType}/auto-organize-progress`, + autoOrganize: `/api/lm/${modelType}/auto-organize`, + autoOrganizeProgress: `/api/lm/${modelType}/auto-organize-progress`, // Model-specific endpoints (will be merged with specific configs) specific: {} @@ -108,24 +108,24 @@ export function getApiEndpoints(modelType) { */ export const MODEL_SPECIFIC_ENDPOINTS = { [MODEL_TYPES.LORA]: { - letterCounts: `/api/${MODEL_TYPES.LORA}/letter-counts`, - notes: `/api/${MODEL_TYPES.LORA}/get-notes`, - triggerWords: `/api/${MODEL_TYPES.LORA}/get-trigger-words`, - previewUrl: `/api/${MODEL_TYPES.LORA}/preview-url`, - civitaiUrl: `/api/${MODEL_TYPES.LORA}/civitai-url`, - metadata: `/api/${MODEL_TYPES.LORA}/metadata`, - getTriggerWordsPost: `/api/${MODEL_TYPES.LORA}/get_trigger_words`, - civitaiModelByVersion: `/api/${MODEL_TYPES.LORA}/civitai/model/version`, - civitaiModelByHash: `/api/${MODEL_TYPES.LORA}/civitai/model/hash`, + letterCounts: `/api/lm/${MODEL_TYPES.LORA}/letter-counts`, + notes: `/api/lm/${MODEL_TYPES.LORA}/get-notes`, + triggerWords: `/api/lm/${MODEL_TYPES.LORA}/get-trigger-words`, + previewUrl: `/api/lm/${MODEL_TYPES.LORA}/preview-url`, + civitaiUrl: `/api/lm/${MODEL_TYPES.LORA}/civitai-url`, + metadata: `/api/lm/${MODEL_TYPES.LORA}/metadata`, + getTriggerWordsPost: `/api/lm/${MODEL_TYPES.LORA}/get_trigger_words`, + civitaiModelByVersion: `/api/lm/${MODEL_TYPES.LORA}/civitai/model/version`, + civitaiModelByHash: `/api/lm/${MODEL_TYPES.LORA}/civitai/model/hash`, }, [MODEL_TYPES.CHECKPOINT]: { - info: `/api/${MODEL_TYPES.CHECKPOINT}/info`, - checkpoints_roots: `/api/${MODEL_TYPES.CHECKPOINT}/checkpoints_roots`, - unet_roots: `/api/${MODEL_TYPES.CHECKPOINT}/unet_roots`, - metadata: `/api/${MODEL_TYPES.CHECKPOINT}/metadata`, + info: `/api/lm/${MODEL_TYPES.CHECKPOINT}/info`, + checkpoints_roots: `/api/lm/${MODEL_TYPES.CHECKPOINT}/checkpoints_roots`, + unet_roots: `/api/lm/${MODEL_TYPES.CHECKPOINT}/unet_roots`, + metadata: `/api/lm/${MODEL_TYPES.CHECKPOINT}/metadata`, }, [MODEL_TYPES.EMBEDDING]: { - metadata: `/api/${MODEL_TYPES.EMBEDDING}/metadata`, + metadata: `/api/lm/${MODEL_TYPES.EMBEDDING}/metadata`, } }; @@ -173,11 +173,11 @@ export function getCurrentModelType(explicitType = null) { // Download API endpoints (shared across all model types) export const DOWNLOAD_ENDPOINTS = { - download: '/api/download-model', - downloadGet: '/api/download-model-get', - cancelGet: '/api/cancel-download-get', - progress: '/api/download-progress', - exampleImages: '/api/force-download-example-images' // New endpoint for downloading example images + download: '/api/lm/download-model', + downloadGet: '/api/lm/download-model-get', + cancelGet: '/api/lm/cancel-download-get', + progress: '/api/lm/download-progress', + exampleImages: '/api/lm/force-download-example-images' // New endpoint for downloading example images }; // WebSocket endpoints diff --git a/static/js/api/recipeApi.js b/static/js/api/recipeApi.js index fec0d02f..3b912905 100644 --- a/static/js/api/recipeApi.js +++ b/static/js/api/recipeApi.js @@ -21,7 +21,7 @@ export async function fetchRecipesPage(page = 1, pageSize = 100) { // If we have a specific recipe ID to load if (pageState.customFilter?.active && pageState.customFilter?.recipeId) { // Special case: load specific recipe - const response = await fetch(`/api/recipe/${pageState.customFilter.recipeId}`); + const response = await fetch(`/api/lm/recipe/${pageState.customFilter.recipeId}`); if (!response.ok) { throw new Error(`Failed to load recipe: ${response.statusText}`); @@ -72,7 +72,7 @@ export async function fetchRecipesPage(page = 1, pageSize = 100) { } // Fetch recipes - const response = await fetch(`/api/recipes?${params.toString()}`); + const response = await fetch(`/api/lm/recipes?${params.toString()}`); if (!response.ok) { throw new Error(`Failed to load recipes: ${response.statusText}`); @@ -207,7 +207,7 @@ export async function refreshRecipes() { state.loadingManager.showSimpleLoading('Refreshing recipes...'); // Call the API endpoint to rebuild the recipe cache - const response = await fetch('/api/recipes/scan'); + const response = await fetch('/api/lm/recipes/scan'); if (!response.ok) { const data = await response.json(); @@ -274,7 +274,7 @@ export async function updateRecipeMetadata(filePath, updates) { const basename = filePath.split('/').pop().split('\\').pop(); const recipeId = basename.substring(0, basename.lastIndexOf('.')); - const response = await fetch(`/api/recipe/${recipeId}/update`, { + const response = await fetch(`/api/lm/recipe/${recipeId}/update`, { method: 'PUT', headers: { 'Content-Type': 'application/json', diff --git a/static/js/components/ContextMenu/ModelContextMenuMixin.js b/static/js/components/ContextMenu/ModelContextMenuMixin.js index cd376dd1..3c461a9a 100644 --- a/static/js/components/ContextMenu/ModelContextMenuMixin.js +++ b/static/js/components/ContextMenu/ModelContextMenuMixin.js @@ -125,8 +125,8 @@ export const ModelContextMenuMixin = { state.loadingManager.showSimpleLoading('Re-linking to Civitai...'); const endpoint = this.modelType === 'checkpoint' ? - '/api/checkpoints/relink-civitai' : - '/api/loras/relink-civitai'; + '/api/lm/checkpoints/relink-civitai' : + '/api/lm/loras/relink-civitai'; const response = await fetch(endpoint, { method: 'POST', diff --git a/static/js/components/ContextMenu/RecipeContextMenu.js b/static/js/components/ContextMenu/RecipeContextMenu.js index 351263c7..bb8b8e69 100644 --- a/static/js/components/ContextMenu/RecipeContextMenu.js +++ b/static/js/components/ContextMenu/RecipeContextMenu.js @@ -103,7 +103,7 @@ export class RecipeContextMenu extends BaseContextMenu { return; } - fetch(`/api/recipe/${recipeId}/syntax`) + fetch(`/api/lm/recipe/${recipeId}/syntax`) .then(response => response.json()) .then(data => { if (data.success && data.syntax) { @@ -126,7 +126,7 @@ export class RecipeContextMenu extends BaseContextMenu { return; } - fetch(`/api/recipe/${recipeId}/syntax`) + fetch(`/api/lm/recipe/${recipeId}/syntax`) .then(response => response.json()) .then(data => { if (data.success && data.syntax) { @@ -149,7 +149,7 @@ export class RecipeContextMenu extends BaseContextMenu { } // First get the recipe details to access its LoRAs - fetch(`/api/recipe/${recipeId}`) + fetch(`/api/lm/recipe/${recipeId}`) .then(response => response.json()) .then(recipe => { // Clear any previous filters first @@ -189,7 +189,7 @@ export class RecipeContextMenu extends BaseContextMenu { try { // First get the recipe details - const response = await fetch(`/api/recipe/${recipeId}`); + const response = await fetch(`/api/lm/recipe/${recipeId}`); const recipe = await response.json(); // Get missing LoRAs @@ -209,9 +209,9 @@ export class RecipeContextMenu extends BaseContextMenu { // Determine which endpoint to use based on available data if (lora.modelVersionId) { - endpoint = `/api/loras/civitai/model/version/${lora.modelVersionId}`; + endpoint = `/api/lm/loras/civitai/model/version/${lora.modelVersionId}`; } else if (lora.hash) { - endpoint = `/api/loras/civitai/model/hash/${lora.hash}`; + endpoint = `/api/lm/loras/civitai/model/hash/${lora.hash}`; } else { console.error("Missing both hash and modelVersionId for lora:", lora); return null; diff --git a/static/js/components/DuplicatesManager.js b/static/js/components/DuplicatesManager.js index f49a2d02..a2360c06 100644 --- a/static/js/components/DuplicatesManager.js +++ b/static/js/components/DuplicatesManager.js @@ -13,7 +13,7 @@ export class DuplicatesManager { async findDuplicates() { try { - const response = await fetch('/api/recipes/find-duplicates'); + const response = await fetch('/api/lm/recipes/find-duplicates'); if (!response.ok) { throw new Error('Failed to find duplicates'); } @@ -354,7 +354,7 @@ export class DuplicatesManager { const recipeIds = Array.from(this.selectedForDeletion); // Call API to bulk delete - const response = await fetch('/api/recipes/bulk-delete', { + const response = await fetch('/api/lm/recipes/bulk-delete', { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/static/js/components/ModelDuplicatesManager.js b/static/js/components/ModelDuplicatesManager.js index c8879ce9..33df3779 100644 --- a/static/js/components/ModelDuplicatesManager.js +++ b/static/js/components/ModelDuplicatesManager.js @@ -48,7 +48,7 @@ export class ModelDuplicatesManager { // Method to check for duplicates count using existing endpoint async checkDuplicatesCount() { try { - const endpoint = `/api/${this.modelType}/find-duplicates`; + const endpoint = `/api/lm/${this.modelType}/find-duplicates`; const response = await fetch(endpoint); if (!response.ok) { @@ -104,7 +104,7 @@ export class ModelDuplicatesManager { async findDuplicates() { try { // Determine API endpoint based on model type - const endpoint = `/api/${this.modelType}/find-duplicates`; + const endpoint = `/api/lm/${this.modelType}/find-duplicates`; const response = await fetch(endpoint); if (!response.ok) { @@ -623,7 +623,7 @@ export class ModelDuplicatesManager { const filePaths = Array.from(this.selectedForDeletion); // Call API to bulk delete - const response = await fetch(`/api/${this.modelType}/bulk-delete`, { + const response = await fetch(`/api/lm/${this.modelType}/bulk-delete`, { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -648,7 +648,7 @@ export class ModelDuplicatesManager { // Check if there are still duplicates try { - const endpoint = `/api/${this.modelType}/find-duplicates`; + const endpoint = `/api/lm/${this.modelType}/find-duplicates`; const dupResponse = await fetch(endpoint); if (!dupResponse.ok) { @@ -756,7 +756,7 @@ export class ModelDuplicatesManager { const filePaths = group.models.map(model => model.file_path); // Make API request to verify hashes - const response = await fetch(`/api/${this.modelType}/verify-duplicates`, { + const response = await fetch(`/api/lm/${this.modelType}/verify-duplicates`, { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/static/js/components/RecipeCard.js b/static/js/components/RecipeCard.js index 0eaa68ad..c496a928 100644 --- a/static/js/components/RecipeCard.js +++ b/static/js/components/RecipeCard.js @@ -203,7 +203,7 @@ class RecipeCard { return; } - fetch(`/api/recipe/${recipeId}/syntax`) + fetch(`/api/lm/recipe/${recipeId}/syntax`) .then(response => response.json()) .then(data => { if (data.success && data.syntax) { @@ -299,7 +299,7 @@ class RecipeCard { deleteBtn.disabled = true; // Call API to delete the recipe - fetch(`/api/recipe/${recipeId}`, { + fetch(`/api/lm/recipe/${recipeId}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json' @@ -341,7 +341,7 @@ class RecipeCard { showToast('toast.recipes.preparingForSharing', {}, 'info'); // Call the API to process the image with metadata - fetch(`/api/recipe/${recipeId}/share`) + fetch(`/api/lm/recipe/${recipeId}/share`) .then(response => { if (!response.ok) { throw new Error('Failed to prepare recipe for sharing'); diff --git a/static/js/components/RecipeModal.js b/static/js/components/RecipeModal.js index ffbfa2aa..68d61eb9 100644 --- a/static/js/components/RecipeModal.js +++ b/static/js/components/RecipeModal.js @@ -784,7 +784,7 @@ class RecipeModal { try { // Fetch recipe syntax from backend - const response = await fetch(`/api/recipe/${this.recipeId}/syntax`); + const response = await fetch(`/api/lm/recipe/${this.recipeId}/syntax`); if (!response.ok) { throw new Error(`Failed to get recipe syntax: ${response.statusText}`); @@ -830,9 +830,9 @@ class RecipeModal { // Determine which endpoint to use based on available data if (lora.modelVersionId) { - endpoint = `/api/loras/civitai/model/version/${lora.modelVersionId}`; + endpoint = `/api/lm/loras/civitai/model/version/${lora.modelVersionId}`; } else if (lora.hash) { - endpoint = `/api/loras/civitai/model/hash/${lora.hash}`; + endpoint = `/api/lm/loras/civitai/model/hash/${lora.hash}`; } else { console.error("Missing both hash and modelVersionId for lora:", lora); return null; @@ -1003,7 +1003,7 @@ class RecipeModal { state.loadingManager.showSimpleLoading('Reconnecting LoRA...'); // Call API to reconnect the LoRA - const response = await fetch('/api/recipe/lora/reconnect', { + const response = await fetch('/api/lm/recipe/lora/reconnect', { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/static/js/components/alphabet/AlphabetBar.js b/static/js/components/alphabet/AlphabetBar.js index 82113758..2d358156 100644 --- a/static/js/components/alphabet/AlphabetBar.js +++ b/static/js/components/alphabet/AlphabetBar.js @@ -46,7 +46,7 @@ export class AlphabetBar { */ async fetchLetterCounts() { try { - const response = await fetch('/api/loras/letter-counts'); + const response = await fetch('/api/lm/loras/letter-counts'); if (!response.ok) { throw new Error(`Failed to fetch letter counts: ${response.statusText}`); diff --git a/static/js/components/initialization.js b/static/js/components/initialization.js index e7b6818f..9a547a86 100644 --- a/static/js/components/initialization.js +++ b/static/js/components/initialization.js @@ -169,7 +169,7 @@ class InitializationManager { */ pollProgress() { const checkProgress = () => { - fetch('/api/init-status') + fetch('/api/lm/init-status') .then(response => response.json()) .then(data => { this.handleProgressUpdate(data); diff --git a/static/js/components/shared/ModelCard.js b/static/js/components/shared/ModelCard.js index aa3208a0..c17b60fd 100644 --- a/static/js/components/shared/ModelCard.js +++ b/static/js/components/shared/ModelCard.js @@ -186,7 +186,7 @@ async function handleExampleImagesAccess(card, modelType) { const modelHash = card.dataset.sha256; try { - const response = await fetch(`/api/has-example-images?model_hash=${modelHash}`); + const response = await fetch(`/api/lm/has-example-images?model_hash=${modelHash}`); const data = await response.json(); if (data.has_images) { diff --git a/static/js/components/shared/ModelModal.js b/static/js/components/shared/ModelModal.js index 2a1f525b..081b0a46 100644 --- a/static/js/components/shared/ModelModal.js +++ b/static/js/components/shared/ModelModal.js @@ -460,7 +460,7 @@ async function saveNotes(filePath) { */ async function openFileLocation(filePath) { try { - const resp = await fetch('/api/open-file-location', { + const resp = await fetch('/api/lm/open-file-location', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ 'file_path': filePath }) diff --git a/static/js/components/shared/RecipeTab.js b/static/js/components/shared/RecipeTab.js index 78c4e9cc..ffa439c9 100644 --- a/static/js/components/shared/RecipeTab.js +++ b/static/js/components/shared/RecipeTab.js @@ -22,7 +22,7 @@ export function loadRecipesForLora(loraName, sha256) { `; // Fetch recipes that use this Lora by hash - fetch(`/api/recipes/for-lora?hash=${encodeURIComponent(sha256.toLowerCase())}`) + fetch(`/api/lm/recipes/for-lora?hash=${encodeURIComponent(sha256.toLowerCase())}`) .then(response => response.json()) .then(data => { if (!data.success) { @@ -166,7 +166,7 @@ function copyRecipeSyntax(recipeId) { return; } - fetch(`/api/recipe/${recipeId}/syntax`) + fetch(`/api/lm/recipe/${recipeId}/syntax`) .then(response => response.json()) .then(data => { if (data.success && data.syntax) { diff --git a/static/js/components/shared/TriggerWords.js b/static/js/components/shared/TriggerWords.js index 28d1f173..564f5230 100644 --- a/static/js/components/shared/TriggerWords.js +++ b/static/js/components/shared/TriggerWords.js @@ -14,7 +14,7 @@ import { getModelApiClient } from '../../api/modelApiFactory.js'; */ async function fetchTrainedWords(filePath) { try { - const response = await fetch(`/api/trained-words?file_path=${encodeURIComponent(filePath)}`); + const response = await fetch(`/api/lm/trained-words?file_path=${encodeURIComponent(filePath)}`); const data = await response.json(); if (data.success) { diff --git a/static/js/components/shared/showcase/MediaUtils.js b/static/js/components/shared/showcase/MediaUtils.js index 0da17c53..7a56f5ab 100644 --- a/static/js/components/shared/showcase/MediaUtils.js +++ b/static/js/components/shared/showcase/MediaUtils.js @@ -408,7 +408,7 @@ export function initMediaControlHandlers(container) { try { // Call the API to delete the custom example - const response = await fetch('/api/delete-example-image', { + const response = await fetch('/api/lm/delete-example-image', { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/static/js/components/shared/showcase/ShowcaseView.js b/static/js/components/shared/showcase/ShowcaseView.js index b4b96b0f..257753fd 100644 --- a/static/js/components/shared/showcase/ShowcaseView.js +++ b/static/js/components/shared/showcase/ShowcaseView.js @@ -29,7 +29,7 @@ export async function loadExampleImages(images, modelHash) { let localFiles = []; try { - const endpoint = '/api/example-image-files'; + const endpoint = '/api/lm/example-image-files'; const params = `model_hash=${modelHash}`; const response = await fetch(`${endpoint}?${params}`); @@ -374,7 +374,7 @@ async function handleImportFiles(files, modelHash, importContainer) { }); // Call API to import files - const response = await fetch('/api/import-example-images', { + const response = await fetch('/api/lm/import-example-images', { method: 'POST', body: formData }); @@ -386,7 +386,7 @@ async function handleImportFiles(files, modelHash, importContainer) { } // Get updated local files - const updatedFilesResponse = await fetch(`/api/example-image-files?model_hash=${modelHash}`); + const updatedFilesResponse = await fetch(`/api/lm/example-image-files?model_hash=${modelHash}`); const updatedFilesResult = await updatedFilesResponse.json(); if (!updatedFilesResult.success) { diff --git a/static/js/managers/ExampleImagesManager.js b/static/js/managers/ExampleImagesManager.js index 38150749..7cb6d2ac 100644 --- a/static/js/managers/ExampleImagesManager.js +++ b/static/js/managers/ExampleImagesManager.js @@ -172,7 +172,7 @@ export class ExampleImagesManager { async checkDownloadStatus() { try { - const response = await fetch('/api/example-images-status'); + const response = await fetch('/api/lm/example-images-status'); const data = await response.json(); if (data.success) { @@ -236,7 +236,7 @@ export class ExampleImagesManager { const optimize = state.global.settings.optimizeExampleImages; - const response = await fetch('/api/download-example-images', { + const response = await fetch('/api/lm/download-example-images', { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -278,7 +278,7 @@ export class ExampleImagesManager { } try { - const response = await fetch('/api/pause-example-images', { + const response = await fetch('/api/lm/pause-example-images', { method: 'POST' }); @@ -314,7 +314,7 @@ export class ExampleImagesManager { } try { - const response = await fetch('/api/resume-example-images', { + const response = await fetch('/api/lm/resume-example-images', { method: 'POST' }); @@ -358,7 +358,7 @@ export class ExampleImagesManager { async updateProgress() { try { - const response = await fetch('/api/example-images-status'); + const response = await fetch('/api/lm/example-images-status'); const data = await response.json(); if (data.success) { @@ -727,7 +727,7 @@ export class ExampleImagesManager { const outputDir = document.getElementById('exampleImagesPath').value; const optimize = state.global.settings.optimizeExampleImages; - const response = await fetch('/api/download-example-images', { + const response = await fetch('/api/lm/download-example-images', { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/static/js/managers/FilterManager.js b/static/js/managers/FilterManager.js index 12c35c0d..adac4ede 100644 --- a/static/js/managers/FilterManager.js +++ b/static/js/managers/FilterManager.js @@ -66,7 +66,7 @@ export class FilterManager { tagsContainer.innerHTML = '
'; // Determine the API endpoint based on the page type - const tagsEndpoint = `/api/${this.currentPage}/top-tags?limit=20`; + const tagsEndpoint = `/api/lm/${this.currentPage}/top-tags?limit=20`; const response = await fetch(tagsEndpoint); if (!response.ok) throw new Error('Failed to fetch tags'); @@ -134,7 +134,7 @@ export class FilterManager { if (!baseModelTagsContainer) return; // Set the API endpoint based on current page - const apiEndpoint = `/api/${this.currentPage}/base-models`; + const apiEndpoint = `/api/lm/${this.currentPage}/base-models`; // Fetch base models fetch(apiEndpoint) diff --git a/static/js/managers/SettingsManager.js b/static/js/managers/SettingsManager.js index 33040aac..9de7a7dc 100644 --- a/static/js/managers/SettingsManager.js +++ b/static/js/managers/SettingsManager.js @@ -429,7 +429,7 @@ export class SettingsManager { if (!defaultLoraRootSelect) return; // Fetch lora roots - const response = await fetch('/api/loras/roots'); + const response = await fetch('/api/lm/loras/roots'); if (!response.ok) { throw new Error('Failed to fetch LoRA roots'); } @@ -468,7 +468,7 @@ export class SettingsManager { if (!defaultCheckpointRootSelect) return; // Fetch checkpoint roots - const response = await fetch('/api/checkpoints/roots'); + const response = await fetch('/api/lm/checkpoints/roots'); if (!response.ok) { throw new Error('Failed to fetch checkpoint roots'); } @@ -507,7 +507,7 @@ export class SettingsManager { if (!defaultEmbeddingRootSelect) return; // Fetch embedding roots - const response = await fetch('/api/embeddings/roots'); + const response = await fetch('/api/lm/embeddings/roots'); if (!response.ok) { throw new Error('Failed to fetch embedding roots'); } @@ -1023,7 +1023,7 @@ export class SettingsManager { async updateMetadataArchiveStatus() { try { - const response = await fetch('/api/metadata-archive-status'); + const response = await fetch('/api/lm/metadata-archive-status'); const data = await response.json(); const statusContainer = document.getElementById('metadataArchiveStatus'); @@ -1152,7 +1152,7 @@ export class SettingsManager { // Wait for WebSocket to be ready await wsReady; - const response = await fetch(`/api/download-metadata-archive?download_id=${encodeURIComponent(actualDownloadId)}`, { + const response = await fetch(`/api/lm/download-metadata-archive?download_id=${encodeURIComponent(actualDownloadId)}`, { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -1215,7 +1215,7 @@ export class SettingsManager { removeBtn.textContent = translate('settings.metadataArchive.removingButton'); } - const response = await fetch('/api/remove-metadata-archive', { + const response = await fetch('/api/lm/remove-metadata-archive', { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/static/js/managers/UpdateService.js b/static/js/managers/UpdateService.js index 5beb0f94..b1d29960 100644 --- a/static/js/managers/UpdateService.js +++ b/static/js/managers/UpdateService.js @@ -97,7 +97,7 @@ export class UpdateService { try { // Call backend API to check for updates with nightly flag - const response = await fetch(`/api/check-updates?nightly=${this.nightlyMode}`); + const response = await fetch(`/api/lm/check-updates?nightly=${this.nightlyMode}`); const data = await response.json(); if (data.success) { @@ -280,7 +280,7 @@ export class UpdateService { // Update progress this.updateProgress(10, translate('update.updateProgress.preparing')); - const response = await fetch('/api/perform-update', { + const response = await fetch('/api/lm/perform-update', { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -444,7 +444,7 @@ export class UpdateService { async checkVersionInfo() { try { // Call API to get current version info - const response = await fetch('/api/version-info'); + const response = await fetch('/api/lm/version-info'); const data = await response.json(); if (data.success) { diff --git a/static/js/managers/import/DownloadManager.js b/static/js/managers/import/DownloadManager.js index ffbefb20..c71e9e31 100644 --- a/static/js/managers/import/DownloadManager.js +++ b/static/js/managers/import/DownloadManager.js @@ -68,7 +68,7 @@ export class DownloadManager { formData.append('metadata', JSON.stringify(completeMetadata)); // Send save request - const response = await fetch('/api/recipes/save', { + const response = await fetch('/api/lm/recipes/save', { method: 'POST', body: formData }); diff --git a/static/js/managers/import/FolderBrowser.js b/static/js/managers/import/FolderBrowser.js index 32f39b80..43cfbada 100644 --- a/static/js/managers/import/FolderBrowser.js +++ b/static/js/managers/import/FolderBrowser.js @@ -100,7 +100,7 @@ export class FolderBrowser { } // Fetch LoRA roots - const rootsResponse = await fetch('/api/loras/roots'); + const rootsResponse = await fetch('/api/lm/loras/roots'); if (!rootsResponse.ok) { throw new Error(`Failed to fetch LoRA roots: ${rootsResponse.status}`); } @@ -120,7 +120,7 @@ export class FolderBrowser { } // Fetch folders - const foldersResponse = await fetch('/api/loras/folders'); + const foldersResponse = await fetch('/api/lm/loras/folders'); if (!foldersResponse.ok) { throw new Error(`Failed to fetch folders: ${foldersResponse.status}`); } diff --git a/static/js/managers/import/ImageProcessor.js b/static/js/managers/import/ImageProcessor.js index 37f4b7ef..66ca0dc2 100644 --- a/static/js/managers/import/ImageProcessor.js +++ b/static/js/managers/import/ImageProcessor.js @@ -62,7 +62,7 @@ export class ImageProcessor { async analyzeImageFromUrl(url) { try { // Call the API with URL data - const response = await fetch('/api/recipes/analyze-image', { + const response = await fetch('/api/lm/recipes/analyze-image', { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -110,7 +110,7 @@ export class ImageProcessor { async analyzeImageFromLocalPath(path) { try { // Call the API with local path data - const response = await fetch('/api/recipes/analyze-local-image', { + const response = await fetch('/api/lm/recipes/analyze-local-image', { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -169,7 +169,7 @@ export class ImageProcessor { formData.append('image', this.importManager.recipeImage); // Upload image for analysis - const response = await fetch('/api/recipes/analyze-image', { + const response = await fetch('/api/lm/recipes/analyze-image', { method: 'POST', body: formData }); diff --git a/static/js/statistics.js b/static/js/statistics.js index 4b79934b..930199aa 100644 --- a/static/js/statistics.js +++ b/static/js/statistics.js @@ -65,12 +65,12 @@ class StatisticsManager { storageAnalytics, insights ] = await Promise.all([ - this.fetchData('/api/stats/collection-overview'), - this.fetchData('/api/stats/usage-analytics'), - this.fetchData('/api/stats/base-model-distribution'), - this.fetchData('/api/stats/tag-analytics'), - this.fetchData('/api/stats/storage-analytics'), - this.fetchData('/api/stats/insights') + this.fetchData('/api/lm/stats/collection-overview'), + this.fetchData('/api/lm/stats/usage-analytics'), + this.fetchData('/api/lm/stats/base-model-distribution'), + this.fetchData('/api/lm/stats/tag-analytics'), + this.fetchData('/api/lm/stats/storage-analytics'), + this.fetchData('/api/lm/stats/insights') ]); this.data = { diff --git a/static/js/utils/uiHelpers.js b/static/js/utils/uiHelpers.js index 2281ecf7..f4e4091a 100644 --- a/static/js/utils/uiHelpers.js +++ b/static/js/utils/uiHelpers.js @@ -370,7 +370,7 @@ export function copyLoraSyntax(card) { export async function sendLoraToWorkflow(loraSyntax, replaceMode = false, syntaxType = 'lora') { try { // Get registry information from the new endpoint - const registryResponse = await fetch('/api/get-registry'); + const registryResponse = await fetch('/api/lm/get-registry'); const registryData = await registryResponse.json(); if (!registryData.success) { @@ -417,7 +417,7 @@ export async function sendLoraToWorkflow(loraSyntax, replaceMode = false, syntax async function sendToSpecificNode(nodeIds, loraSyntax, replaceMode, syntaxType) { try { // Call the backend API to update the lora code - const response = await fetch('/api/update-lora-code', { + const response = await fetch('/api/lm/update-lora-code', { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -676,7 +676,7 @@ initializeMouseTracking(); */ export async function openExampleImagesFolder(modelHash) { try { - const response = await fetch('/api/open-example-images-folder', { + const response = await fetch('/api/lm/open-example-images-folder', { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/web/comfyui/autocomplete.js b/web/comfyui/autocomplete.js index 6e4e8e03..202026ad 100644 --- a/web/comfyui/autocomplete.js +++ b/web/comfyui/autocomplete.js @@ -156,7 +156,7 @@ class AutoComplete { async search(term = '') { try { this.currentSearchTerm = term; - const response = await api.fetchApi(`/${this.modelType}/relative-paths?search=${encodeURIComponent(term)}&limit=${this.options.maxItems}`); + const response = await api.fetchApi(`/lm/${this.modelType}/relative-paths?search=${encodeURIComponent(term)}&limit=${this.options.maxItems}`); const data = await response.json(); if (data.success && data.relative_paths && data.relative_paths.length > 0) { @@ -383,7 +383,7 @@ class AutoComplete { // Get usage tips and extract strength let strength = 1.0; // Default strength try { - const response = await api.fetchApi(`/loras/usage-tips-by-path?relative_path=${encodeURIComponent(relativePath)}`); + const response = await api.fetchApi(`/lm/loras/usage-tips-by-path?relative_path=${encodeURIComponent(relativePath)}`); if (response.ok) { const data = await response.json(); if (data.success && data.usage_tips) { diff --git a/web/comfyui/loras_widget_components.js b/web/comfyui/loras_widget_components.js index fcde1972..fc40dce3 100644 --- a/web/comfyui/loras_widget_components.js +++ b/web/comfyui/loras_widget_components.js @@ -269,7 +269,7 @@ export class PreviewTooltip { this.currentLora = loraName; // Get preview URL - const response = await api.fetchApi(`/loras/preview-url?name=${encodeURIComponent(loraName)}`, { + const response = await api.fetchApi(`/lm/loras/preview-url?name=${encodeURIComponent(loraName)}`, { method: 'GET' }); diff --git a/web/comfyui/loras_widget_events.js b/web/comfyui/loras_widget_events.js index fa0d5633..85564891 100644 --- a/web/comfyui/loras_widget_events.js +++ b/web/comfyui/loras_widget_events.js @@ -491,7 +491,7 @@ export function createContextMenu(x, y, loraName, widget, previewTooltip, render try { // Get Civitai URL from API - const response = await api.fetchApi(`/loras/civitai-url?name=${encodeURIComponent(loraName)}`, { + const response = await api.fetchApi(`/lm/loras/civitai-url?name=${encodeURIComponent(loraName)}`, { method: 'GET' }); @@ -547,7 +547,7 @@ export function createContextMenu(x, y, loraName, widget, previewTooltip, render try { // Get notes from API - const response = await api.fetchApi(`/loras/get-notes?name=${encodeURIComponent(loraName)}`, { + const response = await api.fetchApi(`/lm/loras/get-notes?name=${encodeURIComponent(loraName)}`, { method: 'GET' }); @@ -584,7 +584,7 @@ export function createContextMenu(x, y, loraName, widget, previewTooltip, render try { // Get trigger words from API - const response = await api.fetchApi(`/loras/get-trigger-words?name=${encodeURIComponent(loraName)}`, { + const response = await api.fetchApi(`/lm/loras/get-trigger-words?name=${encodeURIComponent(loraName)}`, { method: 'GET' }); diff --git a/web/comfyui/loras_widget_utils.js b/web/comfyui/loras_widget_utils.js index 1b4193b3..85913c72 100644 --- a/web/comfyui/loras_widget_utils.js +++ b/web/comfyui/loras_widget_utils.js @@ -70,7 +70,7 @@ export async function saveRecipeDirectly() { } // Send the request to the backend API - const response = await fetch('/api/recipes/save-from-widget', { + const response = await fetch('/api/lm/recipes/save-from-widget', { method: 'POST' }); diff --git a/web/comfyui/ui_utils.js b/web/comfyui/ui_utils.js index 524940c8..4996c67a 100644 --- a/web/comfyui/ui_utils.js +++ b/web/comfyui/ui_utils.js @@ -107,7 +107,7 @@ const initializeWidgets = () => { // Fetch version info from the API const fetchVersionInfo = async () => { try { - const response = await fetch('/api/version-info'); + const response = await fetch('/api/lm/version-info'); const data = await response.json(); if (data.success) { diff --git a/web/comfyui/usage_stats.js b/web/comfyui/usage_stats.js index b0844114..b89eaf46 100644 --- a/web/comfyui/usage_stats.js +++ b/web/comfyui/usage_stats.js @@ -38,7 +38,7 @@ app.registerExtension({ async updateUsageStats(promptId) { try { // Call backend endpoint with the prompt_id - const response = await fetch(`/api/update-usage-stats`, { + const response = await fetch(`/api/lm/update-usage-stats`, { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -79,7 +79,7 @@ app.registerExtension({ } } - const response = await fetch('/api/register-nodes', { + const response = await fetch('/api/lm/register-nodes', { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -158,7 +158,7 @@ app.registerExtension({ try { // Search for current relative path - const response = await api.fetchApi(`/${modelType}/relative-paths?search=${encodeURIComponent(fileName)}&limit=2`); + const response = await api.fetchApi(`/lm/${modelType}/relative-paths?search=${encodeURIComponent(fileName)}&limit=2`); const data = await response.json(); if (!data.success || !data.relative_paths || data.relative_paths.length === 0) {