285 lines
9.8 KiB
Python
285 lines
9.8 KiB
Python
"""
|
|
S4 Custom Any To String Node
|
|
Author: S4MUEL
|
|
GitHub: https://github.com/S4MUEL-404/ComfyUI-PromptsO
|
|
|
|
Convert any input type to string with advanced formatting options.
|
|
"""
|
|
|
|
import re
|
|
from ..s4_logger import S4APILogger, log_processing_step
|
|
|
|
|
|
class S4AnyToString:
|
|
"""
|
|
Convert any input type to string with formatting and cleaning options.
|
|
"""
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {},
|
|
"optional": {
|
|
"string_input": (
|
|
"STRING",
|
|
{
|
|
"forceInput": True,
|
|
"tooltip": "String input to convert"
|
|
}
|
|
),
|
|
"int_input": (
|
|
"INT",
|
|
{
|
|
"forceInput": True,
|
|
"tooltip": "Integer input to convert"
|
|
}
|
|
),
|
|
"float_input": (
|
|
"FLOAT",
|
|
{
|
|
"forceInput": True,
|
|
"tooltip": "Float input to convert"
|
|
}
|
|
),
|
|
"remove_whitespace": (
|
|
["None", "All", "Leading/Trailing", "Extra Spaces"],
|
|
{
|
|
"default": "None",
|
|
"tooltip": "Remove whitespace from output"
|
|
}
|
|
),
|
|
"remove_special_chars": (
|
|
"BOOLEAN",
|
|
{
|
|
"default": False,
|
|
"tooltip": "Remove special characters (keep only alphanumeric and spaces)"
|
|
}
|
|
),
|
|
"lowercase": (
|
|
"BOOLEAN",
|
|
{
|
|
"default": False,
|
|
"tooltip": "Convert output to lowercase"
|
|
}
|
|
),
|
|
"uppercase": (
|
|
"BOOLEAN",
|
|
{
|
|
"default": False,
|
|
"tooltip": "Convert output to uppercase"
|
|
}
|
|
),
|
|
"prefix": (
|
|
"STRING",
|
|
{
|
|
"default": "",
|
|
"multiline": False,
|
|
"tooltip": "Text to add at the beginning"
|
|
}
|
|
),
|
|
"suffix": (
|
|
"STRING",
|
|
{
|
|
"default": "",
|
|
"multiline": False,
|
|
"tooltip": "Text to add at the end"
|
|
}
|
|
),
|
|
"expression": (
|
|
"STRING",
|
|
{
|
|
"default": "",
|
|
"multiline": True,
|
|
"tooltip": "Python expression to evaluate (use 'value' as the input variable)"
|
|
}
|
|
),
|
|
}
|
|
}
|
|
|
|
RETURN_TYPES = ("STRING",)
|
|
RETURN_NAMES = ("text",)
|
|
FUNCTION = "convert_to_string"
|
|
CATEGORY = "💀PromptsO"
|
|
DESCRIPTION = "Convert any input type to string with advanced formatting and cleaning options."
|
|
|
|
def convert_any_to_string(self, input_value) -> str:
|
|
"""Convert any type to string representation"""
|
|
if input_value is None:
|
|
return ""
|
|
|
|
# Handle different types
|
|
if isinstance(input_value, str):
|
|
return input_value
|
|
elif isinstance(input_value, (int, float, bool)):
|
|
return str(input_value)
|
|
elif isinstance(input_value, (list, tuple)):
|
|
# Convert list/tuple to comma-separated string
|
|
return ", ".join(str(item) for item in input_value)
|
|
elif isinstance(input_value, dict):
|
|
# Convert dict to key=value pairs
|
|
return ", ".join(f"{k}={v}" for k, v in input_value.items())
|
|
elif hasattr(input_value, '__str__'):
|
|
return str(input_value)
|
|
else:
|
|
# Fallback for any other type
|
|
return repr(input_value)
|
|
|
|
def apply_whitespace_removal(self, text: str, mode: str) -> str:
|
|
"""Apply whitespace removal based on mode"""
|
|
if mode == "None":
|
|
return text
|
|
elif mode == "All":
|
|
return re.sub(r'\s+', '', text)
|
|
elif mode == "Leading/Trailing":
|
|
return text.strip()
|
|
elif mode == "Extra Spaces":
|
|
# Replace multiple spaces with single space
|
|
text = re.sub(r' +', ' ', text)
|
|
# Replace multiple newlines with single newline
|
|
text = re.sub(r'\n+', '\n', text)
|
|
return text.strip()
|
|
return text
|
|
|
|
def apply_special_char_removal(self, text: str) -> str:
|
|
"""Remove special characters, keep only alphanumeric and spaces"""
|
|
return re.sub(r'[^a-zA-Z0-9\s]', '', text)
|
|
|
|
def apply_expression(self, text: str, expression: str) -> str:
|
|
"""Apply Python expression to the text"""
|
|
if not expression or not expression.strip():
|
|
return text
|
|
|
|
try:
|
|
# Create a safe evaluation context
|
|
safe_globals = {
|
|
'__builtins__': {},
|
|
'len': len,
|
|
'str': str,
|
|
'int': int,
|
|
'float': float,
|
|
'bool': bool,
|
|
'list': list,
|
|
'dict': dict,
|
|
'tuple': tuple,
|
|
'max': max,
|
|
'min': min,
|
|
'sum': sum,
|
|
'abs': abs,
|
|
'round': round,
|
|
}
|
|
|
|
# Make the value available as 'value' in the expression
|
|
local_vars = {'value': text}
|
|
|
|
# Evaluate the expression
|
|
result = eval(expression.strip(), safe_globals, local_vars)
|
|
|
|
# Convert result back to string
|
|
return str(result)
|
|
|
|
except Exception as e:
|
|
error_msg = f"Expression evaluation error: {str(e)}"
|
|
S4APILogger.error("AnyToString", error_msg)
|
|
raise ValueError(error_msg)
|
|
|
|
def convert_to_string(
|
|
self,
|
|
string_input=None,
|
|
int_input=None,
|
|
float_input=None,
|
|
remove_whitespace="None",
|
|
remove_special_chars=False,
|
|
lowercase=False,
|
|
uppercase=False,
|
|
prefix="",
|
|
suffix="",
|
|
expression="",
|
|
):
|
|
"""Convert input to string with formatting options"""
|
|
|
|
log_processing_step("AnyToString", "Starting conversion")
|
|
|
|
# Determine which input is provided
|
|
input_value = None
|
|
input_type = "unknown"
|
|
|
|
if string_input is not None:
|
|
input_value = string_input
|
|
input_type = "STRING"
|
|
elif int_input is not None:
|
|
input_value = int_input
|
|
input_type = "INT"
|
|
elif float_input is not None:
|
|
input_value = float_input
|
|
input_type = "FLOAT"
|
|
|
|
# Handle empty input
|
|
if input_value is None:
|
|
S4APILogger.warning("AnyToString", "No input provided, returning empty string")
|
|
return ("",)
|
|
|
|
S4APILogger.debug("AnyToString", f"Input type: {input_type}")
|
|
|
|
# Convert to string
|
|
result = self.convert_any_to_string(input_value)
|
|
original_length = len(result)
|
|
|
|
S4APILogger.debug("AnyToString", f"Initial conversion: {original_length} chars")
|
|
|
|
# Apply expression first if provided
|
|
if expression and expression.strip():
|
|
try:
|
|
result = self.apply_expression(result, expression)
|
|
S4APILogger.debug("AnyToString", f"Expression applied: '{expression[:50]}...'")
|
|
except ValueError:
|
|
# Error already logged, re-raise
|
|
raise
|
|
|
|
# Apply case transformations
|
|
if lowercase and uppercase:
|
|
S4APILogger.warning("AnyToString", "Both lowercase and uppercase enabled, applying lowercase only")
|
|
result = result.lower()
|
|
elif lowercase:
|
|
result = result.lower()
|
|
S4APILogger.debug("AnyToString", "Applied lowercase transformation")
|
|
elif uppercase:
|
|
result = result.upper()
|
|
S4APILogger.debug("AnyToString", "Applied uppercase transformation")
|
|
|
|
# Remove special characters
|
|
if remove_special_chars:
|
|
before_length = len(result)
|
|
result = self.apply_special_char_removal(result)
|
|
removed_count = before_length - len(result)
|
|
if removed_count > 0:
|
|
S4APILogger.debug("AnyToString", f"Removed {removed_count} special characters")
|
|
|
|
# Apply whitespace removal
|
|
if remove_whitespace != "None":
|
|
before_length = len(result)
|
|
result = self.apply_whitespace_removal(result, remove_whitespace)
|
|
removed_count = before_length - len(result)
|
|
if removed_count > 0:
|
|
S4APILogger.debug("AnyToString", f"Whitespace mode '{remove_whitespace}': removed {removed_count} chars")
|
|
|
|
# Add prefix and suffix
|
|
if prefix:
|
|
result = prefix + result
|
|
S4APILogger.debug("AnyToString", f"Added prefix: '{prefix}'")
|
|
if suffix:
|
|
result = result + suffix
|
|
S4APILogger.debug("AnyToString", f"Added suffix: '{suffix}'")
|
|
|
|
# Log results
|
|
result_info = f"Type: {input_type}, Length: {original_length} → {len(result)} chars"
|
|
preview = result[:100] + "..." if len(result) > 100 else result
|
|
result_info += f", Preview: {preview}"
|
|
|
|
S4APILogger.success("AnyToString", f"Conversion completed - {result_info}")
|
|
|
|
return (result,)
|
|
|
|
@classmethod
|
|
def IS_CHANGED(cls, **kwargs):
|
|
return float("NaN")
|