Files
gmorks-ComfyUI-Animagine-Pr…/animagine_node.py
T
2025-01-29 20:57:12 -06:00

170 lines
6.0 KiB
Python

"""
Main node implementation for Animagine Prompt
"""
import os
from typing import Tuple, Dict, Any, List, Optional
import logging
from .csv_handler import CSVHandler
logger = logging.getLogger('AnimaginePrompt')
class AnimaginePromptNode:
"""
A ComfyUI node that helps structure prompts according to specific guidelines
"""
# Definición de tags predefinidas
QUALITY_TAGS_GOOD = ["masterpiece", "best quality"]
QUALITY_TAGS_BAD = ["low quality", "worst quality"]
SCORE_TAGS_GOOD = ["high score", "great score", "good score"]
SCORE_TAGS_BAD = ["average score", "bad score", "low score"]
RATING_TAGS = ["safe", "sensitive", "nsfw", "explicit"]
# Tags negativas por defecto según las guidelines
DEFAULT_NEGATIVE_TAGS = [
"low quality", "worst quality", "blurry", "bad anatomy",
"bad hands", "text", "error", "missing fingers",
"extra digit", "fewer digits", "cropped", "jpeg artifacts",
"signature", "watermark", "username", "artist name"
]
def __init__(self):
self.csv_handler = CSVHandler()
self.last_csv_path = None
@classmethod
def INPUT_TYPES(cls) -> Dict[str, Dict[str, Any]]:
return {
"required": {
"positive_prompt": ("STRING", {"multiline": True}),
"negative_prompt": ("STRING", {"multiline": True}),
# Good tags controls
"use_good_tags": ("BOOLEAN", {"default": True}),
"quality_good": (cls.QUALITY_TAGS_GOOD,),
"score_good": (cls.SCORE_TAGS_GOOD,),
# Bad tags controls
"use_bad_tags": ("BOOLEAN", {"default": False}),
"quality_bad": (cls.QUALITY_TAGS_BAD,),
"score_bad": (cls.SCORE_TAGS_BAD,),
# Year control
"use_year": ("BOOLEAN", {"default": False}),
"year": ("INT", {"default": 2024}),
# Rating control
"use_rating": ("BOOLEAN", {"default": False}),
"rating": (cls.RATING_TAGS,),
# CSV control
"use_csv": ("BOOLEAN", {"default": False}),
"csv_path": ("STRING", {"default": ""}),
"csv_index": ("INT", {"default": 0, "min": 0, "max": 9999})
}
}
RETURN_TYPES = ("STRING", "STRING")
RETURN_NAMES = ("final_positive_prompt", "final_negative_prompt")
FUNCTION = "generate_prompt"
CATEGORY = "prompt"
def _build_good_tags(self, quality_good: str, score_good: str) -> str:
"""Construye la sección de tags positivas"""
tags = []
if quality_good:
tags.append(quality_good)
if score_good:
tags.append(score_good)
return ", ".join(tags)
def _build_bad_tags(self, quality_bad: str, score_bad: str) -> str:
"""Construye la sección de tags negativas"""
tags = []
if quality_bad:
tags.append(quality_bad)
if score_bad:
tags.append(score_bad)
return ", ".join(tags)
def _get_csv_entry(self, csv_path: str, index: int) -> Optional[str]:
"""Obtiene y formatea una entrada del CSV"""
if self.last_csv_path != csv_path:
self.csv_handler.load_csv(csv_path)
self.last_csv_path = csv_path
entry = self.csv_handler.get_entry(index)
if entry:
return f"{entry['gender']}, {entry['character']}, {entry['copyright']}"
return None
def generate_prompt(
self,
positive_prompt: str,
negative_prompt: str,
use_good_tags: bool,
quality_good: str,
score_good: str,
use_bad_tags: bool,
quality_bad: str,
score_bad: str,
use_year: bool,
year: int,
use_rating: bool,
rating: str,
use_csv: bool,
csv_path: str,
csv_index: int
) -> Tuple[str, str]:
"""
Genera los prompts finales basados en los parámetros proporcionados
"""
try:
# Lista para construir el prompt positivo
positive_parts = []
# Agregar tags positivas si están activadas
if use_good_tags:
good_tags = self._build_good_tags(quality_good, score_good)
if good_tags:
positive_parts.append(good_tags)
# Agregar bad tags al prompt positivo si están activadas
if use_bad_tags:
bad_tags = self._build_bad_tags(quality_bad, score_bad)
if bad_tags:
positive_parts.append(bad_tags)
# Agregar entrada del CSV si está activado
if use_csv and csv_path:
csv_entry = self._get_csv_entry(csv_path, csv_index)
if csv_entry:
positive_parts.append(csv_entry)
# Agregar el prompt base del usuario
if positive_prompt:
positive_parts.append(positive_prompt)
# Agregar year tag si está activado
if use_year:
positive_parts.append(f"year {year}")
# Agregar rating si está activado
if use_rating:
positive_parts.append(rating)
# Construir el prompt negativo
negative_parts = []
# Agregar tags negativas por defecto
negative_parts.extend(self.DEFAULT_NEGATIVE_TAGS)
# Agregar el prompt negativo del usuario
if negative_prompt:
negative_parts.append(negative_prompt)
# Unir todas las partes
final_positive = ", ".join(part for part in positive_parts if part)
final_negative = ", ".join(part for part in negative_parts if part)
return final_positive, final_negative
except Exception as e:
logger.error(f"Error generating prompt: {str(e)}")
raise e