commit a3aaea3b3c05ab209b186d69ebdc673c29db2484 Author: jitcoder Date: Fri Dec 8 17:20:17 2023 +0500 initial commit diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..5abd77c --- /dev/null +++ b/__init__.py @@ -0,0 +1,3 @@ +from .lora_info import NODE_CLASS_MAPPINGS,WEB_DIRECTORY,NODE_DISPLAY_NAME_MAPPINGS + +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"] \ No newline at end of file diff --git a/js/index.js b/js/index.js new file mode 100644 index 0000000..eece2d2 --- /dev/null +++ b/js/index.js @@ -0,0 +1,28 @@ +import { app } from "../../../scripts/app.js"; +import { ComfyWidgets } from "../../scripts/widgets.js"; + +app.registerExtension({ + name: "LoraInfo", + async beforeRegisterNodeDef(nodeType, nodeData, app) { + if (nodeData.name === "LoraInfo") { + + const onNodeCreated = nodeType.prototype.onNodeCreated; + nodeType.prototype.onNodeCreated = function () { + onNodeCreated ? onNodeCreated.apply(this, []) : undefined; + + this.showValueWidget = ComfyWidgets["STRING"]( + this, + "output", + ["STRING", { multiline: true }], + app, + ).widget; + } + + const onExecuted = nodeType.prototype.onExecuted; + nodeType.prototype.onExecuted = function (message) { + onExecuted?.apply(this, [message]); + this.showValueWidget.value = message.text[0]; + } + } + }, +}); diff --git a/lora_info.py b/lora_info.py new file mode 100644 index 0000000..5f7ed95 --- /dev/null +++ b/lora_info.py @@ -0,0 +1,105 @@ +import folder_paths +import hashlib +import requests +import json + +def load_json_from_file(file_path): + try: + with open(file_path, 'r') as json_file: + data = json.load(json_file) + return data + except FileNotFoundError: + print(f"File not found: {file_path}") + return {} + except json.JSONDecodeError: + print(f"Error decoding JSON in file: {file_path}") + return {} + +def save_dict_to_json(data_dict, file_path): + try: + with open(file_path, 'w') as json_file: + json.dump(data_dict, json_file, indent=4) + print(f"Data saved to {file_path}") + except Exception as e: + print(f"Error saving JSON to file: {e}") + +def get_model_version_info(hash_value): + api_url = f"https://civitai.com/api/v1/model-versions/by-hash/{hash_value}" + response = requests.get(api_url) + + if response.status_code == 200: + return response.json() + else: + return None + +def calculate_sha256(file_path): + sha256_hash = hashlib.sha256() + with open(file_path, "rb") as f: + for chunk in iter(lambda: f.read(4096), b""): + sha256_hash.update(chunk) + return sha256_hash.hexdigest() + +class LoraInfo: + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(s): + LORA_LIST = sorted(folder_paths.get_filename_list("loras"), key=str.lower) + + return { + "required": { + "lora_name": (LORA_LIST, ) + }, + } + + RETURN_TYPES = () + FUNCTION = "lora_info" + OUTPUT_NODE = True + CATEGORY = "jitcoder" + + def lora_info(self, lora_name): + lora_tags = load_json_from_file('./custom_nodes/lora-info/db.json') + output = lora_tags.get(lora_name, None) if lora_tags is not None else None + + if output is None: + output = "" + lora_path = folder_paths.get_full_path("loras", lora_name) + LORAsha256 = calculate_sha256(lora_path) + model_info = get_model_version_info(LORAsha256) + trainedWords = model_info.get("trainedWords") + baseModel = model_info.get("baseModel") + images = model_info.get('images') + + if trainedWords: + output += "Triggers: " + ",".join(trainedWords) + output += "\n" + + if baseModel: + output += f"Base Model: {baseModel}\n" + if images: + output += "\nExamples:\n" + for image in images: + output += f"\nOutput: {image.get('url')}\n" + meta = image.get("meta") + if meta: + for key, value in meta.items(): + output += f"{key}: {value}\n" + output += '\n' + lora_tags[lora_name] = output + save_dict_to_json(lora_tags, './custom_nodes/lora-info/db.json') + return {"ui": {"text": (output,)}} + + +# A dictionary that contains all nodes you want to export with their names +# NOTE: names should be globally unique +NODE_CLASS_MAPPINGS = { + "LoraInfo": LoraInfo +} + +# A dictionary that contains the friendly/humanly readable titles for the nodes +NODE_DISPLAY_NAME_MAPPINGS = { + "LoraInfo": "Lora Info" +} + +WEB_DIRECTORY = "./js" \ No newline at end of file diff --git a/preview.png b/preview.png new file mode 100644 index 0000000..b6cfae0 Binary files /dev/null and b/preview.png differ diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..70eca00 --- /dev/null +++ b/readme.md @@ -0,0 +1,20 @@ +## Lora Info + +Shows Lora Base Model, Trigger Words and Examples + +Special thanks to `badjeff` for doing all the actual hard work (https://github.com/badjeff/comfyui_lora_tag_loader) + +![image](preview.png) + +## Installation + +Inside ComfyUI/custom-nodes + +```sh +git clone https://github.com/jitcoder/lora-info.git +``` + +Or download this repo as a zip and extract in the custom-nodes directory. + +Restart ComfyUI +