Files
ComfyUI-Ethanfel-Prompt-Bui…/krea_normal_formatter.py
T

134 lines
4.6 KiB
Python

from __future__ import annotations
import re
from dataclasses import dataclass
from typing import Any, Callable
@dataclass(frozen=True)
class KreaNormalRowRequest:
row: dict[str, Any]
detail_level: str
style_mode: str
subject_type: str
primary: str
item: str
scene: str
pose: str
expression: str
composition: str
camera: str
camera_scene: str
style: str
@dataclass(frozen=True)
class KreaNormalRowPrompt:
prompt: str
method: str
def as_tuple(self) -> tuple[str, str]:
return self.prompt, self.method
@dataclass(frozen=True)
class KreaNormalRowDependencies:
clean: Callable[[Any], str]
row_value: Callable[[dict[str, Any], str, tuple[str, ...]], str]
age_subject: Callable[[dict[str, Any], str], str]
age_detail_phrase: Callable[[Any], str]
appearance_phrase: Callable[[dict[str, Any]], str]
with_indefinite_article: Callable[[str], str]
paragraph: Callable[[list[str]], str]
def _couple_clothing_phrase(item: str, clean: Callable[[Any], str]) -> str:
item = clean(item)
lower = item.lower()
partner_text = re.sub(r"\bPartner ([AB]) wears\b", r"Partner \1 wearing", item)
partner_text = re.sub(r"\bPartner ([AB]) has\b", r"Partner \1 with", partner_text)
if lower.startswith("partner a "):
return f"The outfits show {partner_text}"
if lower.startswith(("two ", "paired ", "coordinated ")):
return f"The outfits are {partner_text}"
return f"The couple wears {item}"
def format_normal_row_result(
request: KreaNormalRowRequest,
deps: KreaNormalRowDependencies,
) -> KreaNormalRowPrompt:
row = request.row
subject_type = request.subject_type
primary = request.primary
item = request.item
scene = request.scene
pose = request.pose
expression = request.expression
composition = request.composition
camera = request.camera
camera_scene = request.camera_scene
style = request.style
detail_level = request.detail_level
if primary in ("woman", "man") or subject_type in ("woman", "man", "single_any"):
subject = deps.age_subject(row, "adult woman")
appearance = deps.appearance_phrase(row)
parts = [
deps.with_indefinite_article(subject),
f"with {appearance}" if appearance else "",
f"wearing {item}" if item else "",
f"{pose}" if pose else "",
f"with {expression}" if expression else "",
f"in {scene}" if scene else "",
camera_scene,
f"framed as {composition}" if composition else "",
camera,
style if detail_level != "concise" else "",
]
return KreaNormalRowPrompt(
deps.paragraph([", ".join(part for part in parts[:6] if part), *parts[6:]]),
"metadata(single)",
)
if subject_type == "couple" or primary in ("two women", "two men", "a woman and a man"):
subject = deps.clean(row.get("subject_phrase") or primary or "adult couple")
if subject == "woman and man":
subject = "a woman and a man"
ages = deps.age_detail_phrase(deps.row_value(row, "age", ("Ages",)) or row.get("age_band"))
body = deps.row_value(row, "body", ("Body types",)) or deps.clean(row.get("body_type"))
parts = [
f"An adult couple: {subject}, all visibly adult",
f"Age detail: {ages}" if ages else "",
f"Body types: {body}" if body else "",
_couple_clothing_phrase(item, deps.clean) if item else "",
f"The pose is {pose}" if pose else "",
f"The setting is {scene}" if scene else "",
camera_scene,
f"Facial expressions are {expression}" if expression else "",
f"The image is framed as {composition}" if composition else "",
camera,
style if detail_level != "concise" else "",
]
return KreaNormalRowPrompt(deps.paragraph(parts), "metadata(couple)")
subject = deps.age_subject(row, primary or "adult scene")
parts = [
f"{subject}",
f"featuring {item}" if item else "",
f"in {scene}" if scene else "",
camera_scene,
f"with {expression}" if expression else "",
f"framed as {composition}" if composition else "",
camera,
style if detail_level != "concise" else "",
]
return KreaNormalRowPrompt(deps.paragraph(parts), "metadata(generic)")
def format_normal_row(
request: KreaNormalRowRequest,
deps: KreaNormalRowDependencies,
) -> tuple[str, str]:
return format_normal_row_result(request, deps).as_tuple()