Add atomic writes, magic string constants, unit tests, type hints, and fix navigation
- save_json() now writes to a temp file then uses os.replace() for atomic writes - Replace hardcoded "batch_data", "history_tree", "prompt_history", "sequence_number" strings with constants (KEY_BATCH_DATA, etc.) across all modules - Add 29 unit tests for history_tree, utils, and json_loader - Add type hints to public functions in utils.py, json_loader.py, history_tree.py - Remove ALLOWED_BASE_DIR restriction that blocked navigating outside app CWD - Fix path text input not updating on navigation by using session state key - Add unpin button (❌) for removing pinned folders Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import streamlit as st
|
||||
import random
|
||||
from utils import DEFAULTS, save_json, get_file_mtime
|
||||
from utils import DEFAULTS, save_json, get_file_mtime, KEY_BATCH_DATA, KEY_PROMPT_HISTORY, KEY_SEQUENCE_NUMBER
|
||||
|
||||
def render_single_editor(data, file_path):
|
||||
is_batch_file = "batch_data" in data or isinstance(data, list)
|
||||
is_batch_file = KEY_BATCH_DATA in data or isinstance(data, list)
|
||||
|
||||
if is_batch_file:
|
||||
st.info("This is a batch file. Switch to the 'Batch Processor' tab.")
|
||||
@@ -63,7 +63,7 @@ def render_single_editor(data, file_path):
|
||||
# Explicitly track standard setting keys to exclude them from custom list
|
||||
standard_keys = {
|
||||
"general_prompt", "general_negative", "current_prompt", "negative", "prompt", "seed",
|
||||
"camera", "flf", "batch_data", "prompt_history", "sequence_number", "ui_reset_token",
|
||||
"camera", "flf", KEY_BATCH_DATA, KEY_PROMPT_HISTORY, KEY_SEQUENCE_NUMBER, "ui_reset_token",
|
||||
"model_name", "vae_name", "steps", "cfg", "denoise", "sampler_name", "scheduler"
|
||||
}
|
||||
standard_keys.update(lora_keys)
|
||||
@@ -169,8 +169,8 @@ def render_single_editor(data, file_path):
|
||||
archive_note = st.text_input("Archive Note")
|
||||
if st.button("📦 Snapshot to History", use_container_width=True):
|
||||
entry = {"note": archive_note if archive_note else "Snapshot", **current_state}
|
||||
if "prompt_history" not in data: data["prompt_history"] = []
|
||||
data["prompt_history"].insert(0, entry)
|
||||
if KEY_PROMPT_HISTORY not in data: data[KEY_PROMPT_HISTORY] = []
|
||||
data[KEY_PROMPT_HISTORY].insert(0, entry)
|
||||
data.update(entry)
|
||||
save_json(file_path, data)
|
||||
st.session_state.last_mtime = get_file_mtime(file_path)
|
||||
@@ -181,7 +181,7 @@ def render_single_editor(data, file_path):
|
||||
# --- FULL HISTORY PANEL ---
|
||||
st.markdown("---")
|
||||
st.subheader("History")
|
||||
history = data.get("prompt_history", [])
|
||||
history = data.get(KEY_PROMPT_HISTORY, [])
|
||||
|
||||
if not history:
|
||||
st.caption("No history yet.")
|
||||
|
||||
Reference in New Issue
Block a user