Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -119,7 +119,6 @@ EXTRA_CHOICES = [
|
|
| 119 |
"Include information on composition (rule of thirds, symmetry, leading lines, etc).",
|
| 120 |
"Specify the depth of field and whether the background is in focus or blurred.",
|
| 121 |
"If applicable, mention the likely use of artificial or natural lighting sources.",
|
| 122 |
-
"If it is a work of art, do not include the artist's name or the title of the work.",
|
| 123 |
"Identify the image orientation (portrait, landscape, or square) if obvious.",
|
| 124 |
]
|
| 125 |
NAME_OPTION = "If there is a person/character in the image you must refer to them as {name}."
|
|
@@ -281,11 +280,36 @@ def load_journal() -> dict:
|
|
| 281 |
# ────────────────────────────────────────────────────────
|
| 282 |
# Shape Aliases (compile/cache/apply)
|
| 283 |
# ────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 284 |
def get_shape_alias_rows_ui_defaults():
|
| 285 |
s = load_settings()
|
| 286 |
rows = [[it.get("shape",""), it.get("name","")] for it in s.get("shape_aliases", [])]
|
| 287 |
enabled = bool(s.get("shape_aliases_enabled", True))
|
| 288 |
-
# Always show at least one empty row
|
| 289 |
if not rows:
|
| 290 |
rows = [["", ""]]
|
| 291 |
return rows, enabled
|
|
@@ -307,14 +331,12 @@ def save_shape_alias_rows(enabled, df_rows):
|
|
| 307 |
save_settings(cfg)
|
| 308 |
_refresh_shape_aliases_cache()
|
| 309 |
|
| 310 |
-
# Normalize table after save (keep one empty row at the end)
|
| 311 |
normalized = [[it["shape"], it["name"]] for it in cleaned] + [["", ""]]
|
| 312 |
return (
|
| 313 |
"✅ Saved shape alias options.",
|
| 314 |
gr.update(value=normalized, row_count=(max(1, len(normalized)), "dynamic"))
|
| 315 |
)
|
| 316 |
|
| 317 |
-
|
| 318 |
# ────────────────────────────────────────────────────────
|
| 319 |
# Logo loader
|
| 320 |
# ────────────────────────────────────────────────────────
|
|
@@ -614,84 +636,55 @@ with gr.Blocks(css=BASE_CSS, title="CaptionForge") as demo:
|
|
| 614 |
chunk_size = gr.Slider(1, 50, settings.get("chunk_size", 10), step=1, label="Chunk size")
|
| 615 |
max_side = gr.Slider(256, MAX_SIDE_CAP, settings.get("max_side", min(896, MAX_SIDE_CAP)), step=32, label="Max side (resize)")
|
| 616 |
|
| 617 |
-
# Shape Aliases UI (Accordion)
|
| 618 |
-
with gr.
|
| 619 |
gr.Markdown(
|
| 620 |
"### 🔷 Shape Aliases\n"
|
| 621 |
-
"
|
| 622 |
"**How to use:**\n"
|
| 623 |
-
"1)
|
| 624 |
-
"2)
|
| 625 |
"3) Click **Save**.\n\n"
|
| 626 |
-
"
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
init_rows, init_enabled = get_shape_alias_rows_ui_defaults()
|
| 630 |
|
| 631 |
-
|
| 632 |
-
label="Enable shape alias replacements",
|
| 633 |
-
value=init_enabled,
|
| 634 |
-
info="Turn all replacements on/off without deleting your list."
|
| 635 |
-
)
|
| 636 |
|
| 637 |
-
|
| 638 |
-
|
| 639 |
-
|
| 640 |
-
|
| 641 |
-
row_count=(max(1, len(init_rows)), "dynamic"), # user can add rows
|
| 642 |
-
datatype=["str", "str"],
|
| 643 |
-
type="array", # <-- treat rows as lists (most reliable for editing)
|
| 644 |
-
interactive=True
|
| 645 |
-
)
|
| 646 |
|
| 647 |
-
|
| 648 |
-
|
| 649 |
-
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
|
| 653 |
-
|
| 654 |
-
|
| 655 |
-
def _add_row(cur):
|
| 656 |
-
cur = (cur or []) + [["", ""]]
|
| 657 |
-
# keep dynamic rows in sync
|
| 658 |
-
return gr.update(value=cur, row_count=(max(1, len(cur)), "dynamic"))
|
| 659 |
-
|
| 660 |
-
def _clear_rows():
|
| 661 |
-
return gr.update(value=[["", ""]], row_count=(1, "dynamic"))
|
| 662 |
-
|
| 663 |
-
add_row_btn.click(_add_row, inputs=[alias_table], outputs=[alias_table])
|
| 664 |
-
clear_btn.click(_clear_rows, inputs=None, outputs=[alias_table])
|
| 665 |
-
save_btn.click(save_shape_alias_rows, inputs=[enable_aliases, alias_table], outputs=[save_status, alias_table])
|
| 666 |
-
|
| 667 |
-
|
| 668 |
-
save_aliases_btn = gr.Button("Save aliases")
|
| 669 |
-
save_status = gr.Markdown()
|
| 670 |
-
|
| 671 |
-
# init values
|
| 672 |
-
init_rows = [[it.get("shape",""), it.get("name","")] for it in settings.get("shape_aliases", [])]
|
| 673 |
-
if not init_rows:
|
| 674 |
-
init_rows = [["diamond", "starkey-emblem"]]
|
| 675 |
-
enable_aliases.value = bool(settings.get("shape_aliases_enabled", True))
|
| 676 |
-
alias_table.value = init_rows
|
| 677 |
-
|
| 678 |
-
def set_shape_alias_rows(enabled, rows):
|
| 679 |
-
cfg = load_settings()
|
| 680 |
-
cfg["shape_aliases_enabled"] = bool(enabled)
|
| 681 |
-
cfg["shape_aliases"] = [
|
| 682 |
-
{"shape": (r[0] or "").strip(), "name": (r[1] or "").strip()}
|
| 683 |
-
for r in (rows or []) if r and (r[0] or "").strip() and (r[1] or "").strip()
|
| 684 |
-
]
|
| 685 |
-
save_settings(cfg)
|
| 686 |
-
_refresh_shape_aliases_cache()
|
| 687 |
-
return "Saved shape alias options."
|
| 688 |
-
|
| 689 |
-
save_aliases_btn.click(
|
| 690 |
-
set_shape_alias_rows,
|
| 691 |
-
inputs=[enable_aliases, alias_table],
|
| 692 |
-
outputs=[save_status]
|
| 693 |
)
|
| 694 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 695 |
# Auto-refresh instruction & persist key controls
|
| 696 |
def _refresh_instruction(styles, extra, name_value, trigv, begv, endv):
|
| 697 |
instr = final_instruction(styles or ["Character training (short)"], extra or [], name_value)
|
|
|
|
| 119 |
"Include information on composition (rule of thirds, symmetry, leading lines, etc).",
|
| 120 |
"Specify the depth of field and whether the background is in focus or blurred.",
|
| 121 |
"If applicable, mention the likely use of artificial or natural lighting sources.",
|
|
|
|
| 122 |
"Identify the image orientation (portrait, landscape, or square) if obvious.",
|
| 123 |
]
|
| 124 |
NAME_OPTION = "If there is a person/character in the image you must refer to them as {name}."
|
|
|
|
| 280 |
# ────────────────────────────────────────────────────────
|
| 281 |
# Shape Aliases (compile/cache/apply)
|
| 282 |
# ────────────────────────────────────────────────────────
|
| 283 |
+
def _compile_shape_aliases_from_file():
|
| 284 |
+
s = load_settings()
|
| 285 |
+
if not s.get("shape_aliases_enabled", True):
|
| 286 |
+
return []
|
| 287 |
+
compiled = []
|
| 288 |
+
for item in s.get("shape_aliases", []):
|
| 289 |
+
shape = (item.get("shape") or "").strip()
|
| 290 |
+
name = (item.get("name") or "").strip()
|
| 291 |
+
if not shape or not name:
|
| 292 |
+
continue
|
| 293 |
+
pat = rf"\b{re.escape(shape)}(?:-?shaped)?\b"
|
| 294 |
+
compiled.append((re.compile(pat, flags=re.I), name))
|
| 295 |
+
return compiled
|
| 296 |
+
|
| 297 |
+
_SHAPE_ALIASES = _compile_shape_aliases_from_file()
|
| 298 |
+
|
| 299 |
+
def _refresh_shape_aliases_cache():
|
| 300 |
+
global _SHAPE_ALIASES
|
| 301 |
+
_SHAPE_ALIASES = _compile_shape_aliases_from_file()
|
| 302 |
+
|
| 303 |
+
def apply_shape_aliases(caption: str) -> str:
|
| 304 |
+
for pat, name in _SHAPE_ALIASES:
|
| 305 |
+
caption = pat.sub(f"({name})", caption)
|
| 306 |
+
return caption
|
| 307 |
+
|
| 308 |
+
# Helpers for Shape Aliases UI
|
| 309 |
def get_shape_alias_rows_ui_defaults():
|
| 310 |
s = load_settings()
|
| 311 |
rows = [[it.get("shape",""), it.get("name","")] for it in s.get("shape_aliases", [])]
|
| 312 |
enabled = bool(s.get("shape_aliases_enabled", True))
|
|
|
|
| 313 |
if not rows:
|
| 314 |
rows = [["", ""]]
|
| 315 |
return rows, enabled
|
|
|
|
| 331 |
save_settings(cfg)
|
| 332 |
_refresh_shape_aliases_cache()
|
| 333 |
|
|
|
|
| 334 |
normalized = [[it["shape"], it["name"]] for it in cleaned] + [["", ""]]
|
| 335 |
return (
|
| 336 |
"✅ Saved shape alias options.",
|
| 337 |
gr.update(value=normalized, row_count=(max(1, len(normalized)), "dynamic"))
|
| 338 |
)
|
| 339 |
|
|
|
|
| 340 |
# ────────────────────────────────────────────────────────
|
| 341 |
# Logo loader
|
| 342 |
# ────────────────────────────────────────────────────────
|
|
|
|
| 636 |
chunk_size = gr.Slider(1, 50, settings.get("chunk_size", 10), step=1, label="Chunk size")
|
| 637 |
max_side = gr.Slider(256, MAX_SIDE_CAP, settings.get("max_side", min(896, MAX_SIDE_CAP)), step=32, label="Max side (resize)")
|
| 638 |
|
| 639 |
+
# === Shape Aliases UI (Accordion) ===
|
| 640 |
+
with gr.Accordion("Shape Aliases", open=False):
|
| 641 |
gr.Markdown(
|
| 642 |
"### 🔷 Shape Aliases\n"
|
| 643 |
+
"Replace literal **shape tokens** in captions with a preferred **name**.\n\n"
|
| 644 |
"**How to use:**\n"
|
| 645 |
+
"1) Left column: exact shape token (e.g., `diamond`, `heart`).\n"
|
| 646 |
+
"2) Right column: replacement name (e.g., `starkey-emblem`).\n"
|
| 647 |
"3) Click **Save**.\n\n"
|
| 648 |
+
"_Rows with blanks are ignored; add as many rows as you like._"
|
| 649 |
+
)
|
|
|
|
|
|
|
| 650 |
|
| 651 |
+
init_rows, init_enabled = get_shape_alias_rows_ui_defaults()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 652 |
|
| 653 |
+
enable_aliases = gr.Checkbox(
|
| 654 |
+
label="Enable shape alias replacements",
|
| 655 |
+
value=init_enabled,
|
| 656 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 657 |
|
| 658 |
+
alias_table = gr.Dataframe(
|
| 659 |
+
headers=["shape (literal token)", "name to insert"],
|
| 660 |
+
value=init_rows, # set value at creation time
|
| 661 |
+
col_count=(2, "fixed"), # exactly two columns
|
| 662 |
+
row_count=(max(1, len(init_rows)), "dynamic"), # user can add/remove rows
|
| 663 |
+
datatype=["str", "str"],
|
| 664 |
+
type="array", # treat rows as simple lists
|
| 665 |
+
interactive=True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 666 |
)
|
| 667 |
|
| 668 |
+
with gr.Row():
|
| 669 |
+
add_row_btn = gr.Button("+ Add row", variant="secondary")
|
| 670 |
+
clear_btn = gr.Button("Clear", variant="secondary")
|
| 671 |
+
save_btn = gr.Button("💾 Save", variant="primary")
|
| 672 |
+
|
| 673 |
+
save_status = gr.Markdown("")
|
| 674 |
+
|
| 675 |
+
# Button handlers
|
| 676 |
+
def _add_row(cur):
|
| 677 |
+
cur = (cur or []) + [["", ""]]
|
| 678 |
+
return gr.update(value=cur, row_count=(max(1, len(cur)), "dynamic"))
|
| 679 |
+
|
| 680 |
+
def _clear_rows():
|
| 681 |
+
return gr.update(value=[["", ""]], row_count=(1, "dynamic"))
|
| 682 |
+
|
| 683 |
+
add_row_btn.click(_add_row, inputs=[alias_table], outputs=[alias_table])
|
| 684 |
+
clear_btn.click(_clear_rows, outputs=[alias_table])
|
| 685 |
+
save_btn.click(save_shape_alias_rows, inputs=[enable_aliases, alias_table],
|
| 686 |
+
outputs=[save_status, alias_table])
|
| 687 |
+
|
| 688 |
# Auto-refresh instruction & persist key controls
|
| 689 |
def _refresh_instruction(styles, extra, name_value, trigv, begv, endv):
|
| 690 |
instr = final_instruction(styles or ["Character training (short)"], extra or [], name_value)
|