refactor(main): set_tag_fandom is pure fandom_id update
No rename, no retroactive-backfill-in-second-txn. display_name @property reflects the change instantly. The auto-apply side effect (attach fandom tag to images with the character) is preserved but simplified. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+19
-48
@@ -1038,60 +1038,35 @@ def get_tag(tag_id):
|
||||
def set_tag_fandom(tag_id):
|
||||
"""
|
||||
Set or clear a character tag's fandom association.
|
||||
Updates the tag name to include/remove the (Fandom) suffix.
|
||||
|
||||
Form params:
|
||||
fandom_id: ID of an existing fandom tag (optional, clears if absent)
|
||||
fandom_name: Name to find/create a fandom tag (used if fandom_id not given)
|
||||
fandom_id: ID of an existing fandom tag (preferred).
|
||||
fandom_name: Name to find/create a fandom tag (used if fandom_id
|
||||
not given). If both omitted, the fandom is cleared.
|
||||
"""
|
||||
tag = Tag.query.get_or_404(tag_id)
|
||||
|
||||
if tag.kind != "character":
|
||||
return jsonify(ok=False, error="Only character tags can have fandoms"), 400
|
||||
|
||||
fandom_id = request.form.get("fandom_id", type=int)
|
||||
fandom_name = (request.form.get("fandom_name") or "").strip()
|
||||
|
||||
# Get the character's base name (strip existing fandom suffix) and normalize it.
|
||||
char_part = tag.name.split(":", 1)[1] if ":" in tag.name else tag.name
|
||||
char_base, _ = _parse_character_fandom(char_part)
|
||||
char_base = normalize_display_name(char_base)
|
||||
|
||||
if fandom_id:
|
||||
fandom_tag = Tag.query.get(fandom_id)
|
||||
if not fandom_tag or fandom_tag.kind != "fandom":
|
||||
fandom_tag = Tag.query.filter_by(id=fandom_id, kind="fandom").first()
|
||||
if fandom_tag is None:
|
||||
return jsonify(ok=False, error="Invalid fandom tag"), 400
|
||||
fandom_display = fandom_tag.name.split(":", 1)[1] if ":" in fandom_tag.name else fandom_tag.name
|
||||
elif fandom_name:
|
||||
# _ensure_fandom_tag normalizes internally.
|
||||
fandom_tag = _ensure_fandom_tag(fandom_name)
|
||||
fandom_display = fandom_tag.name.split(":", 1)[1]
|
||||
else:
|
||||
# Clear fandom
|
||||
tag.fandom_id = None
|
||||
tag.name = f"character:{char_base}"
|
||||
db.session.commit()
|
||||
return jsonify(ok=True, tag={
|
||||
"id": tag.id,
|
||||
"name": tag.name,
|
||||
"kind": tag.kind,
|
||||
"fandom_id": None,
|
||||
"fandom_name": None
|
||||
})
|
||||
|
||||
# Check for name conflict before renaming
|
||||
new_name = f"character:{char_base} ({fandom_display})"
|
||||
conflict = Tag.query.filter(Tag.name == new_name, Tag.id != tag_id).first()
|
||||
if conflict:
|
||||
return jsonify(ok=False, error=f"A tag named '{new_name}' already exists"), 409
|
||||
|
||||
tag.fandom_id = fandom_tag.id
|
||||
tag.name = new_name
|
||||
elif fandom_name:
|
||||
fandom_tag = _ensure_fandom_tag(fandom_name)
|
||||
tag.fandom_id = fandom_tag.id
|
||||
else:
|
||||
tag.fandom_id = None
|
||||
fandom_tag = None
|
||||
|
||||
db.session.commit()
|
||||
|
||||
# Retroactive backfill: every image already tagged with this character should
|
||||
# also have the fandom tag attached. Runs in a second transaction so a failed
|
||||
# backfill doesn't roll back the rename.
|
||||
# Auto-apply the fandom tag to images already tagged with this character.
|
||||
if fandom_tag is not None:
|
||||
try:
|
||||
db.session.execute(
|
||||
text("""
|
||||
@@ -1099,29 +1074,25 @@ def set_tag_fandom(tag_id):
|
||||
SELECT it.image_id, :fandom_id
|
||||
FROM image_tags it
|
||||
WHERE it.tag_id = :char_id
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM image_tags it2
|
||||
WHERE it2.image_id = it.image_id
|
||||
AND it2.tag_id = :fandom_id
|
||||
)
|
||||
ON CONFLICT DO NOTHING
|
||||
"""),
|
||||
{'char_id': tag.id, 'fandom_id': fandom_tag.id},
|
||||
{"char_id": tag.id, "fandom_id": fandom_tag.id},
|
||||
)
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
# Rename already committed; log and continue. Sweep button recovers.
|
||||
current_app.logger.warning(
|
||||
"set_tag_fandom backfill failed for tag %s -> fandom %s: %s",
|
||||
"set_tag_fandom auto-apply failed for tag %s -> fandom %s: %s",
|
||||
tag.id, fandom_tag.id, e,
|
||||
)
|
||||
|
||||
return jsonify(ok=True, tag={
|
||||
"id": tag.id,
|
||||
"name": tag.name,
|
||||
"display_name": tag.display_name,
|
||||
"kind": tag.kind,
|
||||
"fandom_id": tag.fandom_id,
|
||||
"fandom_name": fandom_display
|
||||
"fandom_name": fandom_tag.name if fandom_tag else None,
|
||||
})
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user