Files
DemonGatanjieu-Anomalous_Mo…/api/__init__.py
T
DemonGatanjieuandClaude Opus 5.5 302fe7e6e8 Keep gallery results as a workflow, a combo or prompts
Every PNG in the gallery has a star that asks what to keep: the whole
workflow as a Workflow Recipe, its main model, LoRAs and positive prompt
as a combo (models looked up on this computer, missing ones left out), or
its prompts as a saved prompt. What is kept remembers its image, so
GET /anomalous/kept_images fills the star and the menu opens what was
kept. The image workbench's Keep opens the same menu instead of its name
and tags form. Things are named after the prompt's first tags.

The Material Library's Recent shelf and its route are gone: the gallery
lists the same images. Gallery cards moved to ui_gallery_card.js, and
deleting asks in the usual dialog. Two missing locale keys are fixed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:32:51 +08:00

122 lines
8.1 KiB
Python

from . import (
activity_log, audio_catalog, folder_types, gallery_routes, materials, media_routes, model_catalog,
model_media, model_metadata, model_resolution, model_type_listing, kept_images, node_material, recipe_packages, recipes, scan_report, scan_summary,
translation_routes, version_manager,
)
from .scanner import *
from .config import *
from .notebooks import *
from .parameters import *
from aiohttp import web
EXTENSION_STATIC_PREFIX = '/extensions/Anomalous_Model_Browser/'
@web.middleware
async def no_cache_extension_middleware(request, handler):
"""Make browsers revalidate this plugin's JS/CSS so a normal refresh picks up updates.
`no-cache` still allows 304 responses via ETag/Last-Modified. This replaces
per-import `?v=` query strings, which load a second module instance whenever
two files import the same module with different URLs.
"""
response = await handler(request)
if request.path.startswith(EXTENSION_STATIC_PREFIX):
response.headers['Cache-Control'] = 'no-cache'
return response
def setup_routes(app):
if hasattr(app, 'middlewares') and no_cache_extension_middleware not in app.middlewares:
app.middlewares.append(no_cache_extension_middleware)
app.router.add_get('/anomalous/folders', model_catalog.api_get_folders)
app.router.add_get('/anomalous/all_folder_types', folder_types.api_get_all_folder_types)
app.router.add_get('/anomalous/models', model_catalog.api_get_models)
app.router.add_get('/anomalous/type_models', model_type_listing.api_get_type_models)
app.router.add_get('/anomalous/all_scan_models', model_catalog.api_get_all_scan_models)
app.router.add_get('/anomalous/batch_select', model_catalog.api_batch_select)
app.router.add_get('/anomalous/image', media_routes.api_serve_image)
app.router.add_get('/anomalous/card_cache', media_routes.api_card_cache)
app.router.add_post('/anomalous/card_cache/clear', media_routes.api_clear_card_cache)
app.router.add_post('/anomalous/scan', api_scan_folder)
app.router.add_get('/anomalous/scan_status', api_scan_status)
app.router.add_get('/anomalous/find_model', model_catalog.api_find_model)
app.router.add_get('/anomalous/config', api_get_config)
app.router.add_post('/anomalous/save_config', api_save_config)
app.router.add_post('/anomalous/delete_model', model_metadata.api_delete_model)
app.router.add_get('/anomalous/compatible_models', model_catalog.api_compatible_models)
app.router.add_get('/anomalous/notebooks', api_get_notebooks)
app.router.add_post('/anomalous/save_notebook', api_save_notebook)
app.router.add_post('/anomalous/delete_notebook', api_delete_notebook)
# Parameter Routes
app.router.add_get('/anomalous/parameters', api_get_parameters)
app.router.add_get('/anomalous/parameters/by_node_type', api_get_parameters_by_type)
app.router.add_post('/anomalous/save_parameter', api_save_parameter)
app.router.add_post('/anomalous/rename_parameter', api_rename_parameter)
app.router.add_post('/anomalous/delete_parameter', api_delete_parameter)
app.router.add_get('/anomalous/parameter_gallery', api_get_parameter_gallery)
# Recipe Routes
app.router.add_get('/anomalous/recipes', recipes.api_get_recipes)
app.router.add_get('/anomalous/recipe_full', recipes.api_get_recipe_full)
app.router.add_get('/anomalous/recipe_asset', recipes.api_get_recipe_asset)
app.router.add_get('/anomalous/recipe_gallery', recipes.api_get_recipe_gallery)
app.router.add_get('/anomalous/recipe_parameter_gallery', recipes.api_get_recipe_parameter_gallery)
app.router.add_get('/anomalous/recipe_gallery_compare', recipes.api_get_recipe_gallery_compare)
app.router.add_post('/anomalous/save_recipe', recipes.api_save_recipe)
app.router.add_post('/anomalous/update_recipe', recipes.api_update_recipe)
app.router.add_post('/anomalous/set_recipe_gallery_cover', recipes.api_set_recipe_gallery_cover)
app.router.add_post('/anomalous/delete_recipe', recipes.api_delete_recipe)
app.router.add_get('/anomalous/recipe_history', recipes.api_get_recipe_history)
app.router.add_get('/anomalous/recipe_version', recipes.api_get_recipe_version)
app.router.add_post('/anomalous/restore_recipe_version', recipes.api_restore_recipe_version)
app.router.add_post('/anomalous/refresh_recipe_identity', recipes.api_refresh_recipe_identity)
app.router.add_post('/anomalous/export_recipe_package', recipe_packages.api_export_recipe_package)
app.router.add_post('/anomalous/import_recipe_package_inspect', recipe_packages.api_import_recipe_package_inspect)
app.router.add_post('/anomalous/import_recipe_package_commit', recipe_packages.api_import_recipe_package_commit)
# Curated Material Library Routes
app.router.add_get('/anomalous/materials', materials.api_get_materials)
app.router.add_get('/anomalous/material_full', materials.api_get_material_full)
app.router.add_get('/anomalous/material_asset', materials.api_get_material_asset)
app.router.add_get('/anomalous/materials/by_node_type', materials.api_get_materials_by_node_type)
app.router.add_post('/anomalous/inspect_image_material', materials.api_inspect_image_material)
app.router.add_post('/anomalous/save_image_material', materials.api_save_image_material)
app.router.add_post('/anomalous/save_parameter_material', materials.api_save_parameter_material)
app.router.add_post('/anomalous/save_prompt_plan', materials.api_save_prompt_plan)
app.router.add_post('/anomalous/save_node_material', node_material.api_save_node_material)
app.router.add_post('/anomalous/delete_material', materials.api_delete_material)
app.router.add_post('/anomalous/update_material', materials.api_update_material)
app.router.add_post('/anomalous/mark_material_moved', materials.api_mark_material_moved)
app.router.add_post('/anomalous/translate', translation_routes.api_translate)
app.router.add_get('/anomalous/base_models', model_catalog.api_base_models)
app.router.add_get('/anomalous/gallery_images', gallery_routes.api_get_gallery_images)
app.router.add_post('/anomalous/delete_gallery_image', gallery_routes.api_delete_gallery_image)
app.router.add_get('/anomalous/output_thumbnail', gallery_routes.api_output_thumbnail)
app.router.add_get('/anomalous/kept_images', kept_images.api_kept_images)
app.router.add_get('/anomalous/resolve_hash', model_resolution.api_resolve_hash)
app.router.add_post('/anomalous/resolve_hash_batch', model_resolution.api_resolve_hash_batch)
app.router.add_get('/anomalous/all_hashes', model_resolution.api_get_all_hashes)
app.router.add_post('/anomalous/scan_all', api_scan_all)
app.router.add_get('/anomalous/global_scan_status', api_global_scan_status)
app.router.add_post('/anomalous/clear_cache', media_routes.api_clear_cache)
app.router.add_post('/anomalous/update_metadata', model_metadata.api_update_metadata)
app.router.add_post('/anomalous/set_custom_cover', model_media.api_set_custom_cover)
app.router.add_post('/anomalous/upload_custom_cover', model_media.api_upload_custom_cover)
app.router.add_get('/anomalous/model_images', media_routes.api_get_model_images)
app.router.add_post('/anomalous/resolve_paths_to_previews', model_catalog.api_resolve_paths_to_previews)
app.router.add_get('/anomalous/scan_summary', scan_summary.api_scan_summary)
app.router.add_get('/anomalous/last_scan', scan_report.api_last_scan)
app.router.add_get('/anomalous/scan_model', scan_report.api_scan_model)
# Audio & Voice Studio Routes
app.router.add_get('/anomalous/audio_stream', audio_catalog.api_serve_audio)
app.router.add_get('/anomalous/audio_gallery', audio_catalog.api_get_audio_gallery)
app.router.add_post('/anomalous/delete_audio_gallery', audio_catalog.api_delete_audio_gallery)
app.router.add_get('/anomalous/audio_previews', audio_catalog.api_get_audio_previews)
app.router.add_post('/anomalous/save_audio_preview', audio_catalog.api_save_audio_preview)
version_manager.register_routes(app)
activity_log.register_routes(app)