diff --git a/app/services/tag_suggestions.py b/app/services/tag_suggestions.py index 5e156a2..f57a42b 100644 --- a/app/services/tag_suggestions.py +++ b/app/services/tag_suggestions.py @@ -8,8 +8,6 @@ The result is grouped by category and annotated with whether each tag already exists in the Tag table (the modal dims disallowed auto-creations). """ from __future__ import annotations -import re -from typing import Iterable from sqlalchemy import select @@ -41,17 +39,14 @@ _WD14_CATEGORY_TO_KIND = { def _canonicalize_wd14_name(raw: str, category: str) -> str: """Rewrite a raw WD14 tag name to the canonical form ImageRepo persists. - - 'character' / 'copyright': title-case the display portion. - - everything else ('general', 'meta', unknown): underscore-to-space only, - preserving the user's casing for general topics. + - character / copyright: title-case each word. + - everything else: underscore-to-space, preserving user casing. """ from app.utils.tag_names import normalize_display_name, underscores_to_spaces kind = _WD14_CATEGORY_TO_KIND.get(category) - if ':' in raw: - prefix, rest = raw.split(':', 1) - transform = normalize_display_name if kind in ('character', 'fandom') else underscores_to_spaces - return f"{prefix}:{transform(rest)}" - return normalize_display_name(raw) if kind in ('character', 'fandom') else underscores_to_spaces(raw) + if kind in ('character', 'fandom'): + return normalize_display_name(raw) + return underscores_to_spaces(raw) # Config keys with safe defaults (used if the row is missing from tag_suggestion_config). @@ -107,19 +102,6 @@ def _existing_tag_names() -> set[str]: return {row[0] for row in db.session.query(Tag.name).all()} -# Matches `Name (Fandom)` — used to recognize that an applied character/copyright -# tag covers a bare WD14 suggestion like `Name`. -_FANDOM_SUFFIX_RE = re.compile(r'^(.+?) \([^()]+\)$') - - -def _fandom_suffix_prefixes(names: Iterable[str]) -> set[str]: - """Extract the `Name` portion from any `Name (Fandom)` entries in `names`.""" - out: set[str] = set() - for n in names: - m = _FANDOM_SUFFIX_RE.match(n) - if m: - out.add(m.group(1)) - return out def _wd14_suggestions(image_id: int, cfg: dict, already: set[str]) -> list[dict]: @@ -129,11 +111,6 @@ def _wd14_suggestions(image_id: int, cfg: dict, already: set[str]) -> list[dict] .filter_by(image_id=image_id, model_version=wd14_ver) .all() ) - # Bare names covered by an already-applied `Name (Fandom)` tag. WD14 emits - # bare names (e.g. "Ruby Rose") even when the curated tag is fandom-scoped - # ("Ruby Rose (RWBY)"); without this, the same character resurfaces as a - # duplicate suggestion and accepting it creates a second, fandom-less tag. - applied_fandom_prefixes = _fandom_suffix_prefixes(already) out: list[dict] = [] for p in preds: threshold = _category_threshold(p.tag_category, cfg) @@ -142,8 +119,6 @@ def _wd14_suggestions(image_id: int, cfg: dict, already: set[str]) -> list[dict] canonical = _canonicalize_wd14_name(p.tag_name, p.tag_category) if canonical in already: continue - if p.tag_category in ('character', 'copyright') and canonical in applied_fandom_prefixes: - continue out.append({ 'name': canonical, 'category': p.tag_category,