Extract Krea clothing cleanup

This commit is contained in:
2026-06-26 15:31:09 +02:00
parent 92469daf03
commit 031223255d
5 changed files with 115 additions and 66 deletions
+2 -58
View File
@@ -16,6 +16,7 @@ try:
natural_label_text as _natural_label_text,
prompt_cast_descriptors as _prompt_cast_descriptors,
)
from .krea_clothing import natural_clothing_state as _natural_clothing_state
from .prompt_hygiene import sanitize_negative_text, sanitize_prose_text
except ImportError: # Allows local smoke tests with `python -c`.
from hardcore_text_cleanup import (
@@ -29,6 +30,7 @@ except ImportError: # Allows local smoke tests with `python -c`.
natural_label_text as _natural_label_text,
prompt_cast_descriptors as _prompt_cast_descriptors,
)
from krea_clothing import natural_clothing_state as _natural_clothing_state
from prompt_hygiene import sanitize_negative_text, sanitize_prose_text
@@ -593,64 +595,6 @@ def _sanitize_scene_text_for_cast(text: Any, labels: list[str]) -> str:
return text
def _clothing_access_phrase(action_text: Any) -> str:
text = _clean(action_text).lower()
if any(term in text for term in ("cumshot", "ejaculat", "semen", "cum on", "cum across", "post-orgasm", "aftermath")):
return "leaving the body exposed for visible semen and aftermath"
if any(term in text for term in ("boobjob", "titjob", "breast sex", "handjob", "hand job", "footjob", "testicle", "balls", "penis licking", "non-penetrative")):
return "leaving the contact point unobstructed"
if any(term in text for term in ("oral", "blowjob", "fellatio", "mouth", "tongue")):
return "leaving the oral contact unobstructed"
if any(term in text for term in ("penetrat", "thrust", "penis entering", "vaginal", "anal")):
return "leaving the penetration point unobstructed"
return "leaving skin and body contact readable"
def _natural_clothing_state(text: Any, action_text: Any = "") -> str:
text = _clean(text)
if not text:
return ""
text = re.sub(r"^Clothing state:\s*", "", text, flags=re.IGNORECASE)
if re.search(r";\s*(?=(?:Woman|Man) [A-Z]\b)", text):
parts = [
_natural_clothing_state(part, action_text).rstrip(".")
for part in re.split(r";\s*(?=(?:Woman|Man) [A-Z]\b)", text)
if _clean(part)
]
return ". ".join(part for part in parts if part)
body_exposure = re.match(r"^Body exposure:\s*(.*?)\.?$", text, flags=re.IGNORECASE)
if body_exposure:
return _clean(body_exposure.group(1)).rstrip(".")
if re.search(r"\bfully nude\b|\bbody is fully exposed\b|\bno clothing covering\b", text, flags=re.IGNORECASE):
owner = "the woman"
owner_match = re.match(r"^\s*((?:Woman|Man) [A-Z])\b", text)
if owner_match:
owner = _natural_label_text(owner_match.group(1), ["Woman A", "Man A"]) or owner
return f"{owner.capitalize()}'s body is fully exposed, bare skin unobstructed"
match = re.match(
r"^(.*?)\b(?:softcore|teaser) outfit is (.*?)(?: for the (?:hardcore|sex) scene)?;\s*(?:softcore visual reference|teaser outfit detail):\s*(.*?)\.?$",
text,
flags=re.IGNORECASE,
)
if match:
owner = _natural_label_text(match.group(1).strip(" 's"), ["Woman A", "Man A"]).strip() or "the woman"
state = _clean(match.group(2)).lower()
outfit = _clean(match.group(3)).rstrip(".")
if "fully nude" in state or "fully exposed" in state or "no clothing covering" in state:
return f"{owner.capitalize()}'s body is fully exposed, bare skin unobstructed"
if "nude-adjacent" in state:
return f"{owner.capitalize()}'s body is partly exposed"
if "partially removed" in state or "pushed aside" in state:
return f"{owner.capitalize()}'s {outfit} is pushed aside or partly removed where needed, {_clothing_access_phrase(action_text)}"
if "keeps" in state:
return f"{owner.capitalize()} keeps the {outfit} on while {_clothing_access_phrase(action_text)}"
text = re.sub(r";\s*(?:softcore visual reference|teaser outfit detail):\s*", ". Visual clothing state: ", text, flags=re.IGNORECASE)
text = text.replace("softcore outfit", "outfit")
text = text.replace("teaser outfit", "outfit")
text = text.replace("hardcore scene", "sex scene")
return text
def _axis_values_text(axis_values: Any) -> str:
if not isinstance(axis_values, dict):
return ""