Code review fixes: wardrobe migration, response validation, path traversal guard, deduplication
- Migrate 11 character JSONs from old wardrobe keys to _BODY_GROUP_KEYS format - Add is_favourite/is_nsfw columns to Preset model - Add HTTP response validation and timeouts to ComfyUI client - Add path traversal protection on replace cover route - Deduplicate services/mcp.py (4 functions → 2 generic + 2 wrappers) - Extract apply_library_filters() and clean_html_text() shared helpers - Add named constants for 17 ComfyUI workflow node IDs - Fix bare except clauses in services/llm.py - Fix tags schema in ensure_default_outfit() (list → dict) - Convert f-string logging to lazy % formatting - Add 5-minute polling timeout to frontend waitForJob() - Improve migration error handling (non-duplicate errors log at WARNING) - Update CLAUDE.md to reflect all changes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import json
|
||||
import os
|
||||
import re
|
||||
import logging
|
||||
from utils import clean_html_text
|
||||
|
||||
from flask import render_template, request, redirect, url_for, flash, session
|
||||
from sqlalchemy.orm.attributes import flag_modified
|
||||
@@ -13,7 +14,7 @@ from services.prompts import build_prompt, _resolve_character, _ensure_character
|
||||
from services.sync import sync_looks
|
||||
from services.file_io import get_available_loras, _count_look_assignments
|
||||
from services.llm import load_prompt, call_llm
|
||||
from routes.shared import register_common_routes
|
||||
from routes.shared import register_common_routes, apply_library_filters
|
||||
|
||||
logger = logging.getLogger('gaze')
|
||||
|
||||
@@ -57,18 +58,9 @@ def register_routes(app):
|
||||
|
||||
@app.route('/looks')
|
||||
def looks_index():
|
||||
query = Look.query
|
||||
fav = request.args.get('favourite')
|
||||
nsfw = request.args.get('nsfw', 'all')
|
||||
if fav == 'on':
|
||||
query = query.filter_by(is_favourite=True)
|
||||
if nsfw == 'sfw':
|
||||
query = query.filter_by(is_nsfw=False)
|
||||
elif nsfw == 'nsfw':
|
||||
query = query.filter_by(is_nsfw=True)
|
||||
looks = query.order_by(Look.is_favourite.desc(), Look.name).all()
|
||||
looks, fav, nsfw = apply_library_filters(Look.query, Look)
|
||||
look_assignments = _count_look_assignments()
|
||||
return render_template('looks/index.html', looks=looks, look_assignments=look_assignments, favourite_filter=fav or '', nsfw_filter=nsfw)
|
||||
return render_template('looks/index.html', looks=looks, look_assignments=look_assignments, favourite_filter=fav, nsfw_filter=nsfw)
|
||||
|
||||
@app.route('/looks/rescan', methods=['POST'])
|
||||
def rescan_looks():
|
||||
@@ -320,7 +312,7 @@ Character ID: {character_slug}"""
|
||||
character_data['lora'] = lora_data
|
||||
|
||||
except Exception as e:
|
||||
logger.exception(f"LLM character generation error: {e}")
|
||||
logger.exception("LLM character generation error: %s", e)
|
||||
flash(f'Failed to generate character with AI: {e}', 'error')
|
||||
return redirect(url_for('look_detail', slug=slug))
|
||||
else:
|
||||
@@ -494,11 +486,7 @@ Character ID: {character_slug}"""
|
||||
try:
|
||||
with open(html_path, 'r', encoding='utf-8', errors='ignore') as hf:
|
||||
html_raw = hf.read()
|
||||
clean_html = re.sub(r'<script[^>]*>.*?</script>', '', html_raw, flags=re.DOTALL)
|
||||
clean_html = re.sub(r'<style[^>]*>.*?</style>', '', clean_html, flags=re.DOTALL)
|
||||
clean_html = re.sub(r'<img[^>]*>', '', clean_html)
|
||||
clean_html = re.sub(r'<[^>]+>', ' ', clean_html)
|
||||
html_content = ' '.join(clean_html.split())
|
||||
html_content = clean_html_text(html_raw)
|
||||
except Exception as e:
|
||||
logger.error("Error reading HTML %s: %s", html_filename, e)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user