diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..828f300 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,21 @@ +name: Publish to Comfy registry +on: + workflow_dispatch: + push: + branches: + - main + paths: + - "pyproject.toml" + +jobs: + publish-node: + name: Publish Custom Node to registry + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Publish Custom Node + uses: Comfy-Org/publish-node-action@main + with: + ## Add your own personal access token to your Github Repository secrets and reference it here. + personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index be2f233..fd5a6a2 100644 --- a/.gitignore +++ b/.gitignore @@ -153,3 +153,4 @@ cython_debug/ .idea /node_modules +/node.zip diff --git a/.others/pre-commit b/.others/pre-commit index e5b4a08..ca982f6 100644 --- a/.others/pre-commit +++ b/.others/pre-commit @@ -1,4 +1,5 @@ #!/bin/bash +# REMEMBER TO COPY THIS FILE INTO .git/hooks/pre-commit cd ../comfyUI/ComfyUI rm ./custom_nodes/ComfyUI-Crystools/web/*.js -f @@ -29,4 +30,4 @@ else exit 1 fi -git add __init__.py core/version.py web/*.js +git add version pyproject.toml __init__.py core/version.py web/*.js diff --git a/.others/version.py b/.others/version.py index 50922f6..ac4beff 100644 --- a/.others/version.py +++ b/.others/version.py @@ -38,3 +38,23 @@ print(f"> File2 {file2}") with open(file2, "w") as f2: f2.writelines([f"version = \"{version}\"\n"]) + +# modify pyproject.toml file with @version +file3 = os.path.join(os.path.dirname(__file__), "../pyproject.toml") +print(f"> File3: {file3}") + +file3VersionFound = False +# lines = None +with open(file3, "r") as f: + lines = f.readlines() + for line in lines: + + if "version = " in line: + file3VersionFound = True + lines[lines.index(line)] = f"version = \"{version}\"\n" + +if not file3VersionFound: + raise RuntimeError(f"Version label not found in file: {file3}") + +with open(file3, "w") as f3: + f3.writelines(lines) diff --git a/__init__.py b/__init__.py index 55bde3b..16b2116 100644 --- a/__init__.py +++ b/__init__.py @@ -2,7 +2,7 @@ @author: Crystian @title: Crystools @nickname: Crystools -@version: 1.12.0 +@version: 1.13.1 @project: "https://github.com/crystian/ComfyUI-Crystools", @description: Plugins for multiples uses, mainly for debugging, you need them! IG: https://www.instagram.com/crystian.ia """ diff --git a/core/version.py b/core/version.py index 6f73501..c3c8e28 100644 --- a/core/version.py +++ b/core/version.py @@ -1 +1 @@ -version = "1.12.0" +version = "1.13.1" diff --git a/docs/screwdriver.png b/docs/screwdriver.png new file mode 100644 index 0000000..61a0574 Binary files /dev/null and b/docs/screwdriver.png differ diff --git a/general/gpu.py b/general/gpu.py index d9eacfb..d0c497f 100644 --- a/general/gpu.py +++ b/general/gpu.py @@ -2,7 +2,6 @@ import torch import pynvml import pyamdgpuinfo import comfy.model_management - from ..core import logger # could not put amdsmi in requirements.txt, user need to install it manually @@ -218,7 +217,20 @@ class CGPUInfo: def deviceGetName(self, deviceHandle, deviceIndex): if self.pynvmlLoaded: - return pynvml.nvmlDeviceGetName(deviceHandle) + gpuName = 'Unknown GPU' + + try: + gpuName = pynvml.nvmlDeviceGetName(deviceHandle) + try: + gpuName = gpuName.decode('utf-8', errors='ignore') + except AttributeError as e: + pass + + except UnicodeDecodeError as e: + gpuName = 'Unknown GPU (decoding error)' + print(f"UnicodeDecodeError: {e}") + + return gpuName # amdsmi give no specific device name for AMD non-enterprise cards (only "NAVI22"), get from torch while it might be wrong elif self.amdsmiLoaded: return torch.cuda.get_device_name(deviceIndex) diff --git a/nodes/image.py b/nodes/image.py index 8de2c8a..f61a611 100644 --- a/nodes/image.py +++ b/nodes/image.py @@ -2,6 +2,7 @@ import os import random import sys import json +import piexif import hashlib from datetime import datetime import torch @@ -262,7 +263,15 @@ class CImageLoadWithMetadata: def execute(self, image): image_path = folder_paths.get_annotated_filepath(image) + imgF = Image.open(image_path) img, prompt, metadata = buildMetadata(image_path) + if imgF.format == 'WEBP': + # Use piexif to extract EXIF data from WebP image + try: + exif_data = piexif.load(image_path) + prompt, metadata = self.process_exif_data(exif_data) + except ValueError: + prompt = {} img = ImageOps.exif_transpose(img) image = img.convert("RGB") @@ -276,6 +285,34 @@ class CImageLoadWithMetadata: return image, mask.unsqueeze(0), prompt, metadata + def process_exif_data(self, exif_data): + metadata = {} + # 检查 '0th' 键下的 271 值,提取 Prompt 信息 + if '0th' in exif_data and 271 in exif_data['0th']: + prompt_data = exif_data['0th'][271].decode('utf-8') + # 移除可能的前缀 'Prompt:' + prompt_data = prompt_data.replace('Prompt:', '', 1) + # 假设 prompt_data 是一个字符串,尝试将其转换为 JSON 对象 + try: + metadata['prompt'] = json.loads(prompt_data) + except json.JSONDecodeError: + metadata['prompt'] = prompt_data + + # 检查 '0th' 键下的 270 值,提取 Workflow 信息 + if '0th' in exif_data and 270 in exif_data['0th']: + workflow_data = exif_data['0th'][270].decode('utf-8') + # 移除可能的前缀 'Workflow:' + workflow_data = workflow_data.replace('Workflow:', '', 1) + try: + # 尝试将字节字符串转换为 JSON 对象 + metadata['workflow'] = json.loads(workflow_data) + except json.JSONDecodeError: + # 如果转换失败,则将原始字符串存储在 metadata 中 + metadata['workflow'] = workflow_data + + metadata.update(exif_data) + return metadata + @classmethod def IS_CHANGED(cls, image): image_path = folder_paths.get_annotated_filepath(image) @@ -354,7 +391,8 @@ class CImageSaveWithExtraMetadata(SaveImage): if metadata_extra is not None and metadata_extra != 'undefined': try: - metadata_extra = json.loads(f"{{{metadata_extra}}}") + # metadata_extra = json.loads(f"{{{metadata_extra}}}") // a fix? + metadata_extra = json.loads(metadata_extra) except Exception as e: logger.error(f"Error parsing metadata_extra (it will send as string), error: {e}") metadata_extra = {"extra": str(metadata_extra)} diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..1df4e39 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,14 @@ +[project] +name = "comfyui-crystools" +description = "With this suit, you can see the resources monitor, progress bar & time elapsed, metadata and compare between two images, compare between two JSONs, show any value to console/display, pipes, and more!\nThis provides better nodes to load/save images, previews, etc, and see \"hidden\" data without loading a new workflow." +version = "1.13.1" +license = "LICENSE" +dependencies = ["deepdiff", "torch", "numpy", "Pillow>=9.5.0", "pynvml", "py-cpuinfo"] + +[project.urls] +Repository = "https://github.com/crystian/ComfyUI-Crystools" + +[tool.comfy] +PublisherId = "crystian" +DisplayName = "ComfyUI-Crystools" +Icon = "https://raw.githubusercontent.com/crystian/ComfyUI-Crystools/main/docs/screwdriver.png" diff --git a/requirements.txt b/requirements.txt index 82bb7f7..6f2fd73 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ Pillow>=9.5.0 pynvml py-cpuinfo pyamdgpuinfo +piexif diff --git a/version b/version index 0eed1a2..b50dd27 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.12.0 +1.13.1