From 635515c0cc05ad1c392ffeb4cb95cd2c18f19bb5 Mon Sep 17 00:00:00 2001 From: cluny85 Date: Fri, 16 May 2025 15:24:51 +0200 Subject: [PATCH] first commit --- .github/ISSUE_TEMPLATE.md | 26 +++++ .github/workflows/publish.yml | 44 ++++++++ .gitignore | 102 ++++++++++++++++++ .pre-commit-config.yaml | 10 ++ LICENSE | 21 ++++ README.md | 43 ++++++++ comfyui_scripting_tools.json | 8 ++ comfyui_scripting_tools/__init__.py | 4 + .../enhanced_uuid_generator.py | 50 +++++++++ .../uuid_generator_node.py | 70 ++++++++++++ requirements.txt | 1 + 11 files changed, 379 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/workflows/publish.yml create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 comfyui_scripting_tools.json create mode 100644 comfyui_scripting_tools/__init__.py create mode 100644 comfyui_scripting_tools/enhanced_uuid_generator.py create mode 100644 comfyui_scripting_tools/uuid_generator_node.py create mode 100644 requirements.txt diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..13bb6e6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,26 @@ +--- +name: General Issue +about: Create a general issue for ComfyUI-scripting-tools +--- + +**Describe the issue** +A clear and concise description of what the issue is. + +**To Reproduce** +Steps to reproduce the behavior: +1. ... +2. ... + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots (if applicable)** +Add screenshots to help explain your problem. + +**Environment (please complete the following information):** +- OS: [e.g. Windows, Linux] +- ComfyUI version: [e.g. 1.8.0] +- Extension version: [e.g. 1.0.0] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..ce1e912 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,44 @@ +name: Publish ComfyUI Scripting Tools + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build-and-check: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Install dependencies + run: | + pip install -r requirements.txt || true + - name: Lint Python files + run: | + pip install flake8 + flake8 comfyui_scripting_tools --max-line-length=120 + - name: Check metadata file + run: | + test -f comfyui_scripting_tools.json + - name: Show publish instructions + run: | + echo "To publish this package, follow the instructions at https://registry.comfy.org/docs/publish-extension/" + + publish: + name: "📦 Publish Custom Node" + needs: build-and-check + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Publish to ComfyUI Registry + uses: Comfy-Org/publish-node-action@main + with: + personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..922987e --- /dev/null +++ b/.gitignore @@ -0,0 +1,102 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# OSX useful to ignore +*.DS_Store +.AppleDouble +.LSOverride + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +venv/ +.venv/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# IntelliJ Idea +.idea +*.iml +*.ipr +*.iws + +# PyBuilder +target/ + +# Cookiecutter +output/ +python_boilerplate/ +cookiecutter-pypackage-env/ + +# vscode settings +.history/ +*.code-workspace +.vscode/ \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..0e54e61 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,10 @@ +repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.4.9 + hooks: + # Run the linter. + - id: ruff + args: [ --fix ] + # Run the formatter. + - id: ruff-format \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c122230 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Oscar Mesa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..4745bde --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# ComfyUI-scripting-tools + +## Description + +A set of utility nodes for ComfyUI focused on scripting. Includes an enhanced UUID generator node. + +### Node: Generate UUID (Enhanced) + +This node allows you to generate UUIDs of type v1, v3, v4, and v5. You can specify: +- The UUID version (v1, v3, v4, v5) +- Namespace type (DNS, URL, OID, X500, or a custom UUID for v3/v5) +- Name string for v3/v5 UUIDs +- Optional prefix and suffix for the output string +- A trigger input to force regeneration + +This is useful for generating unique identifiers in workflows, scripting, or for any automation that requires UUIDs with custom formatting. + +### Node: Generate UUID String + +This node generates a random UUID (version 4) and returns it as a string. You can optionally add a prefix and/or suffix to the generated UUID. The 'trigger' input can be used to force the node to re-execute and generate a new UUID. + +**Inputs:** +- `trigger` (optional): Integer value to force regeneration (changing this value will re-run the node) +- `prefix` (optional): String to prepend to the UUID +- `suffix` (optional): String to append to the UUID + +**Output:** +- `uuid_string`: The generated UUID string, with optional prefix and suffix + +This node is useful for generating unique identifiers in your ComfyUI workflows, especially when you need a simple, random UUID. + +### Installation + +1. Clone this repository into the `custom_nodes` folder of your ComfyUI installation. +2. Restart ComfyUI. + +### Usage + +- The node "Generate UUID (Enhanced)" lets you generate UUIDs with advanced options for scripting and automation. + +### License + +MIT \ No newline at end of file diff --git a/comfyui_scripting_tools.json b/comfyui_scripting_tools.json new file mode 100644 index 0000000..f39ba0c --- /dev/null +++ b/comfyui_scripting_tools.json @@ -0,0 +1,8 @@ +{ + "name": "ComfyUI-scripting-tools", + "author": "Oscar Mesa (cluny85)", + "description": "A set of scripting utility nodes for ComfyUI, including an enhanced UUID generator.", + "version": "1.0.0", + "license": "MIT", + "entry_point": "comfyui_scripting_tools" +} \ No newline at end of file diff --git a/comfyui_scripting_tools/__init__.py b/comfyui_scripting_tools/__init__.py new file mode 100644 index 0000000..4429e72 --- /dev/null +++ b/comfyui_scripting_tools/__init__.py @@ -0,0 +1,4 @@ +from .enhanced_uuid_generator import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS +from .uuid_generator_node import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS + +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] \ No newline at end of file diff --git a/comfyui_scripting_tools/enhanced_uuid_generator.py b/comfyui_scripting_tools/enhanced_uuid_generator.py new file mode 100644 index 0000000..9394403 --- /dev/null +++ b/comfyui_scripting_tools/enhanced_uuid_generator.py @@ -0,0 +1,50 @@ +import uuid + +class EnhancedUUIDGeneratorNode: + def get_namespace(self, namespace_type, custom_namespace_uuid_str): + if namespace_type == "DNS": + return uuid.NAMESPACE_DNS + elif namespace_type == "URL": + return uuid.NAMESPACE_URL + elif namespace_type == "OID": + return uuid.NAMESPACE_OID + elif namespace_type == "X500": + return uuid.NAMESPACE_X500 + elif namespace_type == "CUSTOM": + try: + return uuid.UUID(custom_namespace_uuid_str) + except ValueError: + raise ValueError("Invalid custom namespace UUID string.") + else: + raise ValueError("Invalid namespace type.") + + def generate_uuid_enhanced(self, uuid_type, namespace_type="DNS", custom_namespace_uuid="", + name_string="example.com", prefix="", suffix="", trigger=0): + if trigger == 0: + return None + + namespace = self.get_namespace(namespace_type, custom_namespace_uuid) + + if uuid_type == "UUID1": + generated_uuid = uuid.uuid1() + elif uuid_type == "UUID3": + generated_uuid = uuid.uuid3(namespace, name_string) + elif uuid_type == "UUID4": + generated_uuid = uuid.uuid4() + elif uuid_type == "UUID5": + generated_uuid = uuid.uuid5(namespace, name_string) + else: + raise ValueError("Invalid UUID type.") + + return f"{prefix}{generated_uuid}{suffix}" + +# --- Mapeo para que ComfyUI reconozca el nodo --- +NODE_CLASS_MAPPINGS = { + "EnhancedUUIDGeneratorNode": EnhancedUUIDGeneratorNode +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "EnhancedUUIDGeneratorNode": "Generate UUID (Enhanced)" +} + +print("--- Custom Node: Enhanced UUID Generator loaded ---") \ No newline at end of file diff --git a/comfyui_scripting_tools/uuid_generator_node.py b/comfyui_scripting_tools/uuid_generator_node.py new file mode 100644 index 0000000..a7ea458 --- /dev/null +++ b/comfyui_scripting_tools/uuid_generator_node.py @@ -0,0 +1,70 @@ +import uuid + +class UUIDGeneratorNode: + """ + A simple node to generate a v4 UUID and return it as a string. + """ + + # Define how the node will be displayed in ComfyUI's menu + NODE_NAME = "UUID Generator" # Internal name, used in NODE_CLASS_MAPPINGS + NODE_DISPLAY_NAME = "Generate UUID String" # Name the user sees + + # Define the input types the node accepts + @classmethod + def INPUT_TYPES(cls): + return { + "required": {}, # No required inputs to generate a random UUID + "optional": { + # The 'trigger' here doesn't affect the UUID (uuid4 is random) + # but allows the user to change a value to force + # re-execution of the node if needed. + "trigger": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), + "prefix": ("STRING", {"default": "", "multiline": False}), + "suffix": ("STRING", {"default": "", "multiline": False}), + } + } + + # Define the output types the node produces + RETURN_TYPES = ("STRING",) + # Optional: names for the outputs (if there's more than one, it's more useful) + RETURN_NAMES = ("uuid_string",) + + # Define the main function that will be executed + FUNCTION = "generate_uuid" + + # Define the category where the node will appear in ComfyUI's menu + CATEGORY = "utils/text" # You can change "utils/text" to your preference + + # Indicates if this node is a final output node (like SaveImage) + # In this case, it is not. + OUTPUT_NODE = False + + def generate_uuid(self, trigger=0, prefix="", suffix=""): + """ + Generates a v4 UUID and returns it as a string, optionally with a prefix and suffix. + The 'trigger' parameter is not used for UUID generation itself, + but changing it can force ComfyUI to re-run this node. + """ + # Generate a random v4 UUID + generated_uuid = str(uuid.uuid4()) + + # Concatenate with prefix and suffix if provided + result_string = f"{prefix}{generated_uuid}{suffix}" + + # ComfyUI nodes must return a tuple of results + return (result_string,) + +# --- Mappings for ComfyUI to recognize the node --- +# This dictionary maps an internal name (key) to the node class (value). +NODE_CLASS_MAPPINGS = { + "UUIDGeneratorNode": UUIDGeneratorNode # "UUIDGeneratorNode" is the name used in saved workflows (JSON) +} + +# This dictionary maps the internal name to a human-readable name for the UI. +# Optional, but recommended for clarity. +NODE_DISPLAY_NAME_MAPPINGS = { + "UUIDGeneratorNode": "Generate UUID String" +} + +# Message for the console when the script is loaded (optional) +print("--- Custom Node: UUID Generator loaded ---") \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..dbfebd3 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +# No external dependencies required \ No newline at end of file