Files
DemonGatanjieu-Anomalous_Mo…/api/kept_images.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

44 lines
2.0 KiB
Python

"""What each output image was kept as (GET /anomalous/kept_images), for the gallery's star:
the Workflow Recipe whose source image it is, the combo made from it (a notebook file with
`source_image`), the saved prompt taken from it (a prompt plan material whose source names
the image). Each is {filename, name}, or null when the image was not kept as that."""
import asyncio
from aiohttp import web
from .material_store import _list_materials, get_materials_dir
from .notebooks import _list_notebooks
from .recipe_store import _list_recipes, get_recipes_dir
KINDS = ("recipe", "combo", "prompt")
def _kept_images():
kept = {}
def mark(image, kind, filename, name):
if not isinstance(image, dict) or not isinstance(image.get("filename"), str) or not image["filename"]:
return
subfolder = image.get("subfolder") if isinstance(image.get("subfolder"), str) else ""
entry = kept.setdefault((subfolder, image["filename"]), dict.fromkeys(KINDS))
if entry[kind] is None:
entry[kind] = {"filename": filename, "name": str(name or "")}
for recipe in _list_recipes(get_recipes_dir()):
mark(recipe["data"].get("source_image"), "recipe", recipe["filename"], recipe["data"].get("name"))
for note in _list_notebooks():
mark(note["data"].get("source_image"), "combo", note["filename"], note["name"])
for material in _list_materials(get_materials_dir()):
if material.get("kind") == "prompt_plan":
mark(material.get("source_image"), "prompt", material["filename"], material.get("name"))
return [{"subfolder": subfolder, "filename": filename, **entry} for (subfolder, filename), entry in kept.items()]
async def api_kept_images(request):
try:
images = await asyncio.to_thread(_kept_images)
except (OSError, ValueError):
return web.json_response({"status": "error", "message": "Could not list kept images"}, status=500)
return web.json_response({"status": "success", "images": images})