Files
ComfyAssets-ComfyUI_PromptM…/tools/preview-prompt-timeline.py
Vito d4bb5c5ba9 feat(ui): add the tested opt-in Prompt Manager workspace shell (#198)
* docs(ui): prototype unified prompt management application

* docs(ui): add masonry and per-image tagging to application concept

* docs(ui): make gallery concept use continuous infinite scrolling

* feat(ui): introduce the tested application workspace shell

* fix(docs): preserve concept controls across cached navigation

* test(ci): emit Python tracebacks for native test crashes

* test(ui): cover workspace restoration across cached navigation
2026-10-17 10:36:30 -07:00

52 lines
2.1 KiB
Python

"""Serve only UI concepts and their pinned toolkit and viewer assets."""
import argparse
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from pathlib import Path
from urllib.parse import urlsplit
ROOT = Path(__file__).resolve().parents[1]
FILES = {
"/": ("docs/concepts/prompt-variant-timeline.html", "text/html; charset=utf-8"),
"/workspace/": ("docs/concepts/workspace/index.html", "text/html; charset=utf-8"),
"/workspace/style.css": ("docs/concepts/workspace/style.css", "text/css"),
"/workspace/app.js": ("docs/concepts/workspace/app.js", "text/javascript"),
"/vendor/viewer.js": ("web/lib/viewerjs/viewer.min.js", "text/javascript"),
"/vendor/viewer.css": ("web/lib/viewerjs/viewer.min.css", "text/css"),
"/toolkit/core.js": ("web/js/shared/toolkit/core.js", "text/javascript"),
"/toolkit/controls.css": ("web/js/shared/toolkit/controls.css", "text/css"),
}
class PreviewHandler(BaseHTTPRequestHandler):
def do_GET(self) -> None:
target = FILES.get(urlsplit(self.path).path)
if target is None:
self.send_error(404)
return
filename, mime = target
body = (ROOT / filename).read_bytes()
self.send_response(200)
self.send_header("Content-Type", mime)
self.send_header("Content-Length", str(len(body)))
self.send_header("Cache-Control", "no-store")
self.send_header("X-Content-Type-Options", "nosniff")
self.end_headers()
self.wfile.write(body)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--bind", default="127.0.0.1")
parser.add_argument("--port", type=int, default=8766)
args = parser.parse_args()
server = ThreadingHTTPServer((args.bind, args.port), PreviewHandler)
print(f"Timeline prototype: http://{args.bind}:{args.port}/", flush=True)
try:
server.serve_forever()
except KeyboardInterrupt:
# Ctrl+C exits normally; the finally block closes the listening socket.
pass
finally:
server.server_close()