Compare commits

..
Author SHA1 Message Date
Dijkstra 2e889c7018 chore: detail the difference between tags and trigger words 2025-07-26 17:46:52 +02:00
Dijkstra 52157dff5a Merge pull request #39 from idrirap/dev/issue38
fix: no longer crash when internet is unavailable
2025-01-16 09:38:20 +01:00
Dijkstra 8c18075e9f chore: update node version 2025-01-16 09:37:53 +01:00
Dijkstra e0ec5dee30 fix: no longer crash when internet is unavailable 2025-01-16 09:35:17 +01:00
Dijkstra c09e56b21f Merge pull request #36 from idrirap/dev/issue33
Dev/issue33
2024-10-31 19:53:14 +01:00
Dijkstra 763152c041 chore: set clip strength to 0 when there is no CLIP. (just in case) 2024-10-31 19:51:46 +01:00
Dijkstra c85b302a61 chore: CLIP is not optional in the LoraLoaderVanilla and LoraLoaderAdvanced 2024-10-31 19:49:13 +01:00
Dijkstra 6484968fbe Merge pull request #35 from idrirap/dev/issue34
fix: sometimes the preview image extension is prefixed with '.preview'
2024-10-31 19:15:58 +01:00
Dijkstra 9a212d13e7 fix: sometimes the preview image extension is prefixed with '.preview' 2024-10-31 19:14:31 +01:00
Dijkstra b02bea5480 chore: bump version + added MIT license 2024-06-20 17:56:49 +02:00
Dijkstra 8c4b7941a6 chore: improved description 2024-06-20 17:50:07 +02:00
dijkstra 070751dbf1 Merge pull request #24 from idrirap/dev/add_registryId
feat: set publisherId
2024-06-20 17:35:06 +02:00
Dijkstra 41f6277830 feat: set publisherId 2024-06-20 17:34:27 +02:00
dijkstra 03ddfbfe66 Merge pull request #21 from haohaocreates/publish
Add Github Action for Publishing to Comfy Registry
2024-06-20 17:28:55 +02:00
dijkstra 885a1c8371 Merge pull request #22 from haohaocreates/pyproject
Add pyproject.toml for Custom Node Registry
2024-06-20 17:28:45 +02:00
haohaocreates 8656b2ebaf chore(pyproject): Add pyproject.toml for Custom Node Registry 2024-05-22 17:25:44 -04:00
haohaocreates c3759e7b30 chore(publish): Add Github Action for Publishing to Comfy Registry 2024-05-22 17:25:41 -04:00
Dijkstra 236e230515 doc: added trigger explanation 2024-04-09 22:35:48 +02:00
dijkstra 23ef04b1cb Merge pull request #20 from idrirap/update_readme
Update readme
2024-04-09 22:18:38 +02:00
Dijkstra a95cba4e3b doc: last fix 2024-04-09 22:18:14 +02:00
Dijkstra 40f09582e2 doc: added View info in readme 2024-04-09 22:17:08 +02:00
Dijkstra 6635d30566 doc: updated readme 2024-04-09 22:11:55 +02:00
dijkstra 5cf49c9565 Merge pull request #19 from idrirap/issue14
feat: added pyssss's lora view info
2024-04-09 21:24:05 +02:00
Dijkstra 1e8ed1e16f feat: added pyssss's lora view info 2024-04-09 21:09:44 +02:00
dijkstra 64113afd7f Merge pull request #18 from idrirap/issue16
feat: added lora name to output
2024-04-09 18:16:19 +02:00
Dijkstra 2bd6769b78 fix: now can use the output lora_name as an input for override_lora_name 2024-04-09 18:11:46 +02:00
Dijkstra 96a69f7cbe feat: added lora name to output 2024-04-09 17:05:22 +02:00
dijkstra 9d8b79844f Merge pull request #13 from idrirap/issue12
fix: broken preview when using both enable preview and override_lora_name
2024-03-14 23:26:17 +01:00
Dijkstra f3815b7ce4 fix: broken preview when using both enable preview and override_lora_name 2024-03-14 23:23:35 +01:00
dijkstra d5641ba745 Merge pull request #11 from deipfei/json-error-change
don't delete loras_tags.json on JSONDecodeError
2024-03-08 21:21:03 +01:00
Dustin Pfeiffer 5b5eaf3a81 don't delete loras_tags.json on JSONDecodeError 2024-02-23 15:28:01 -08:00
dijkstra 517b8a8a12 Merge pull request #9 from idrirap/issue8
feat: added tags only node. Added node to load lora names as string. …
2023-12-12 18:58:03 +01:00
15 changed files with 198 additions and 52 deletions
+21
View File
@@ -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 }}
+81 -22
View File
@@ -1,38 +1,92 @@
# ComfyUI-Lora-Auto-Trigger-Words # ComfyUI-Lora-Auto-Trigger-Words
This project is a fork of https://github.com/Extraltodeus/LoadLoraWithTags This project is a fork of https://github.com/Extraltodeus/LoadLoraWithTags
The aim of these custom nodes is to get an _easy_ access to the tags used to trigger a lora. The aim of these custom nodes is to get an _easy_ access to the **trigger words** (or **tags**) used to trigger a lora.
This project is compatible with Stacked Loras from https://github.com/LucianoCirino/efficiency-nodes-comfyui/releases
I talk about **lora**, but works with **lycoris** too. *Note that trigger words and tags are used interchangeably in this readme and means the same thing.*
This project is compatible with Stacked Loras from https://github.com/jags111/efficiency-nodes-comfyui
When I talk about **lora**, I also mean **lycoris** too.
## Install ## Install
Some of this project nodes depends on https://github.com/pythongosssss/ComfyUI-Custom-Scripts : Some of this project nodes depends on https://github.com/pythongosssss/ComfyUI-Custom-Scripts :
- LoraLoaderAdvanced - LoraLoaderAdvanced
- LoraLoaderStackedAdvanced - LoraLoaderStackedAdvanced
They get their vanilla equivalents. - `View info...`
They get their vanilla equivalents with less features
Overall, Custom-Scripts is recommended to be able to know the content of the tag lists with the node `showText` Overall, Custom-Scripts is recommended to be able to know the content of the tag lists with the node `showText`
## Features ## Features
### Main nodes ### Lora Trigger Words
Lora trigger words are imported from two sources :
- Civitai api (only for civitai models)
![image](./images/CivitaiTriggerWords.png)
- Model training metadata (when available)
#### Vanilla vs Advanced #### Vanilla vs Advanced
Vanilla refers to nodes that have no lora preview from the menu, nor the lora list. But the features provided are the same. > Vanilla refers to nodes that have no lora preview from the menu, nor the lora list. But the features provided are the same.
![image](./images/main.png) ![image](./images/main.png)
#### Nodes ### Nodes
- LoraLoader (Vanilla or Advanced) #### LoraLoader (Vanilla and Advanced)
- LoraLoaderStacked (Vanilla or Avanced). The stacked lora input is optional. ![image](./images/LoraLoader.png)
Allow to load a lora, either the normal way, or the efficiency-nodes way. INPUT
These loaders have two custom outputs: - `override_lora_name` (optional): Used to ignore the field `lora_name` and use the name passed. Should use [LoraListNames](#loralistnames) or the `lora_name` output.
- civitai_tags_list: a python list of the tags related to this lora on civitai
- meta_tags_list: a python list of the tags used for training the lora embeded in it (if any) FIELDS
This outputs needs to be filtered by two othere nodes: - `force_fetch`: Force the civitai fetching of data even if there is already something saved
- TagsFormater: Helper to show the available tag and their indexes - `enable_preview`: Toggle on/off the saved lora preview if any (only in advanced)
- tagsSelector: allow to filter tags and apply a weight to it. - `append_lora_if_empty`: Add the name of the lora to the list of tags if the list is empty
- TagSelector contains four parameters. First the selector (see Filtering next)
- The weight `(tag:weight)` OUTPUT
- The boolean `ensure_comma`. To properly append comma if a prefix or suffix is added. - `civitai_tags_list`: a python list of the tags related to this lora on civitai
- The boolean `append_loraname_if_empty` which will add the name of the lora in the list of outputs if they are empty. - `meta_tags_list`: a python list of the tags used for training the lora embeded in it (if any)
#### Filtering - `lora_name`: the name of the current selected lora
#### LoraLoaderStacked (Vanilla and Avanced).
![image](./images/LoraLoaderStacked.png)
INPUT
- `lora_stack` (optional): another stack of lora.
- `override_lora_name` (optional): Used to ignore the field `lora_name` and use the name passed. Should use [LoraListNames](#loralistnames) or the `lora_name` output.
FIELDS
- `force_fetch`: Force the civitai fetching of data even if there is already something saved
- `enable_preview`: Toggle on/off the saved lora preview if any (only in advanced)
- `append_lora_if_empty`: Add the name of the lora to the list of tags if the list is empty
OUTPUT
- `civitai_tags_list`: a python list of the tags related to this lora on civitai
- `meta_tags_list`: a python list of the tags used for training the lora embeded in it (if any)
- `lora_name`: the name of the current selected lora
#### LoraTagsOnly
![image](./images/LoraTagsOnly.png)
To get the tags without using the lora.
- `override_lora_name` (optional): Used to ignore the field `lora_name` and use the name passed. Should use [LoraListNames](#loralistnames) or the `lora_name` output.
OUTPUT
- `civitai_tags_list`: a python list of the tags related to this lora on civitai
- `meta_tags_list`: a python list of the tags used for training the lora embeded in it (if any)
- `lora_name`: the name of the current selected lora
#### TagsFormater
![image](./images/TagsFormater.png)
Helper to show the available tag and their indexes. Tags are sorted by training frequence. The more a tag was used, the higher in the list it is. Works for both `civitai_tags_list` and `meta_tags_list`
#### TagsSelector
![image](./images/TagsSelector.png)
Allow to filter tags and apply a weight to it.
TagSelector contains four parameters.
- `selector` (see the [Filtering](#filtering) section next)
- `weight`: to format the tag like `(tag:weight)`. Default set to 1 without the weight like `tag`.
- `ensure_comma`. To properly append comma if a prefix or suffix is added.
#### LoraListNames
![image](./images/LoraListNames.png)
List all the existing lora names. It is used as an input for `override_lora_name`
### Filtering
The format is simple. It's the same as python list index, but can select multiple index or ranges of indexes separated by comas. The format is simple. It's the same as python list index, but can select multiple index or ranges of indexes separated by comas.
`Ex: 0, 3, 5:8, -8:` `Ex: 0, 3, 5:8, -8:`
- Select a specific list of indexes: `0, 2, 3, 15`... - Select a specific list of indexes: `0, 2, 3, 15`...
@@ -42,6 +96,11 @@ The format is simple. It's the same as python list index, but can select multipl
- You can use negative indexes. Like `-1` to select the last tag - You can use negative indexes. Like `-1` to select the last tag
- By default `:` selects everything - By default `:` selects everything
### View Info
![image](./images/ViewInfo.png)
Pythongossss's [View Info...](https://github.com/pythongosssss/ComfyUI-Custom-Scripts?tab=readme-ov-file#checkpointloraembedding-info) feature from ComfyUI-Custom-Scripts
### Examples
#### Example of normal workflow #### Example of normal workflow
![image](./images/loaderAdvanced.png) ![image](./images/loaderAdvanced.png)
@@ -55,5 +114,5 @@ Lora Stack can also be chained together to load multiple loras into an efficient
### Side nodes I made and kept here ### Side nodes I made and kept here
- FusionText: takes two text input and join them together - FusionText: takes two text input and join them together
- Randomizer: takes two couples text+lorastack and return randomly one them - Randomizer: takes two couples text+lorastack and return randomly one of them
- TextInputBasic: just a text input with two additional input for text chaining - TextInputBasic: just a text input with two additional input for text chaining
+2 -1
View File
@@ -5,4 +5,5 @@ from .nodes_utils import NODE_CLASS_MAPPINGS as nu_NCM
NODE_CLASS_MAPPINGS = dict(na_NCM, **nu_NCM) NODE_CLASS_MAPPINGS = dict(na_NCM, **nu_NCM)
#NODE_DISPLAY_NAME_MAPPINGS = dict(na_NDNM, **nu_NDNM) #NODE_DISPLAY_NAME_MAPPINGS = dict(na_NDNM, **nu_NDNM)
__all__ = ["NODE_CLASS_MAPPINGS"]#, "NODE_DISPLAY_NAME_MAPPINGS"] WEB_DIRECTORY = "./web"
__all__ = ["NODE_CLASS_MAPPINGS", "WEB_DIRECTORY"]#, "NODE_DISPLAY_NAME_MAPPINGS"]
Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

+28 -21
View File
@@ -14,7 +14,6 @@ class LoraLoaderVanilla:
return { return {
"required": { "required": {
"model": ("MODEL",), "model": ("MODEL",),
"clip": ("CLIP", ),
"lora_name": (LORA_LIST, ), "lora_name": (LORA_LIST, ),
"strength_model": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}), "strength_model": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"strength_clip": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}), "strength_clip": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
@@ -22,16 +21,19 @@ class LoraLoaderVanilla:
"append_loraname_if_empty": ("BOOLEAN", {"default": False}), "append_loraname_if_empty": ("BOOLEAN", {"default": False}),
}, },
"optional": { "optional": {
"clip": ("CLIP", ),
"override_lora_name":("STRING", {"forceInput": True}), "override_lora_name":("STRING", {"forceInput": True}),
} }
} }
RETURN_TYPES = ("MODEL", "CLIP", "LIST", "LIST") RETURN_TYPES = ("MODEL", "CLIP", "LIST", "LIST", "STRING")
RETURN_NAMES = ("MODEL", "CLIP", "civitai_tags_list", "meta_tags_list") RETURN_NAMES = ("MODEL", "CLIP", "civitai_tags_list", "meta_tags_list", "lora_name")
FUNCTION = "load_lora" FUNCTION = "load_lora"
CATEGORY = "autotrigger" CATEGORY = "autotrigger"
def load_lora(self, model, clip, lora_name, strength_model, strength_clip, force_fetch, append_loraname_if_empty, override_lora_name=""): def load_lora(self, model, lora_name, strength_model, strength_clip, force_fetch, append_loraname_if_empty, clip=None, override_lora_name=""):
if clip is None:
strength_clip=0
if override_lora_name != "": if override_lora_name != "":
lora_name = override_lora_name lora_name = override_lora_name
meta_tags_list = sort_tags_by_frequency(get_metadata(lora_name, "loras")) meta_tags_list = sort_tags_by_frequency(get_metadata(lora_name, "loras"))
@@ -56,7 +58,7 @@ class LoraLoaderVanilla:
model_lora, clip_lora = load_lora_for_models(model, clip, lora, strength_model, strength_clip) model_lora, clip_lora = load_lora_for_models(model, clip, lora, strength_model, strength_clip)
return (model_lora, clip_lora, civitai_tags_list, meta_tags_list) return (model_lora, clip_lora, civitai_tags_list, meta_tags_list, lora_name)
class LoraLoaderStackedVanilla: class LoraLoaderStackedVanilla:
@classmethod @classmethod
@@ -75,8 +77,8 @@ class LoraLoaderStackedVanilla:
} }
} }
RETURN_TYPES = ("LIST", "LIST", "LORA_STACK",) RETURN_TYPES = ("LIST", "LIST", "LORA_STACK", "STRING")
RETURN_NAMES = ("civitai_tags_list", "meta_tags_list", "LORA_STACK",) RETURN_NAMES = ("civitai_tags_list", "meta_tags_list", "LORA_STACK", "lora_name")
FUNCTION = "set_stack" FUNCTION = "set_stack"
#OUTPUT_NODE = False #OUTPUT_NODE = False
CATEGORY = "autotrigger" CATEGORY = "autotrigger"
@@ -96,7 +98,7 @@ class LoraLoaderStackedVanilla:
if lora_stack is not None: if lora_stack is not None:
loras.extend(lora_stack) loras.extend(lora_stack)
return (civitai_tags_list, meta_tags_list, loras) return (civitai_tags_list, meta_tags_list, loras, lora_name)
class LoraLoaderAdvanced: class LoraLoaderAdvanced:
def __init__(self): def __init__(self):
@@ -109,7 +111,6 @@ class LoraLoaderAdvanced:
return { return {
"required": { "required": {
"model": ("MODEL",), "model": ("MODEL",),
"clip": ("CLIP", ),
"lora_name": (LORA_LIST, ), "lora_name": (LORA_LIST, ),
"strength_model": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}), "strength_model": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
"strength_clip": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}), "strength_clip": ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01}),
@@ -118,18 +119,23 @@ class LoraLoaderAdvanced:
"append_loraname_if_empty": ("BOOLEAN", {"default": False}), "append_loraname_if_empty": ("BOOLEAN", {"default": False}),
}, },
"optional": { "optional": {
"clip": ("CLIP", ),
"override_lora_name":("STRING", {"forceInput": True}), "override_lora_name":("STRING", {"forceInput": True}),
} }
} }
RETURN_TYPES = ("MODEL", "CLIP", "LIST", "LIST") RETURN_TYPES = ("MODEL", "CLIP", "LIST", "LIST", "STRING")
RETURN_NAMES = ("MODEL", "CLIP", "civitai_tags_list", "meta_tags_list") RETURN_NAMES = ("MODEL", "CLIP", "civitai_tags_list", "meta_tags_list", "lora_name")
FUNCTION = "load_lora" FUNCTION = "load_lora"
CATEGORY = "autotrigger" CATEGORY = "autotrigger"
def load_lora(self, model, clip, lora_name, strength_model, strength_clip, force_fetch, enable_preview, append_loraname_if_empty, override_lora_name=""): def load_lora(self, model, lora_name, strength_model, strength_clip, force_fetch, enable_preview, append_loraname_if_empty, clip=None, override_lora_name=""):
if clip is None:
strength_clip=0
if override_lora_name != "": if override_lora_name != "":
lora_name = {"content": override_lora_name, "image": ""} has_preview, prev = get_preview_path(override_lora_name, "loras")
prev = f"loras/{prev}" if has_preview else None
lora_name = {"content": override_lora_name, "image": prev, "type": "loras"}
meta_tags_list = sort_tags_by_frequency(get_metadata(lora_name["content"], "loras")) meta_tags_list = sort_tags_by_frequency(get_metadata(lora_name["content"], "loras"))
civitai_tags_list = load_and_save_tags(lora_name["content"], force_fetch) civitai_tags_list = load_and_save_tags(lora_name["content"], force_fetch)
@@ -160,10 +166,10 @@ class LoraLoaderAdvanced:
"subfolder": "lora_preview", "subfolder": "lora_preview",
"type": "temp" "type": "temp"
} }
return {"ui": {"images": [preview_output]}, "result": (model_lora, clip_lora, civitai_tags_list, meta_tags_list)} return {"ui": {"images": [preview_output]}, "result": (model_lora, clip_lora, civitai_tags_list, meta_tags_list, lora_name["content"])}
return (model_lora, clip_lora, civitai_tags_list, meta_tags_list) return (model_lora, clip_lora, civitai_tags_list, meta_tags_list, lora_name["content"])
class LoraLoaderStackedAdvanced: class LoraLoaderStackedAdvanced:
@classmethod @classmethod
@@ -184,15 +190,17 @@ class LoraLoaderStackedAdvanced:
} }
} }
RETURN_TYPES = ("LIST", "LIST", "LORA_STACK",) RETURN_TYPES = ("LIST", "LIST", "LORA_STACK", "STRING")
RETURN_NAMES = ("civitai_tags_list", "meta_tags_list", "LORA_STACK",) RETURN_NAMES = ("civitai_tags_list", "meta_tags_list", "LORA_STACK", "lora_name")
FUNCTION = "set_stack" FUNCTION = "set_stack"
#OUTPUT_NODE = False #OUTPUT_NODE = False
CATEGORY = "autotrigger" CATEGORY = "autotrigger"
def set_stack(self, lora_name, lora_weight, force_fetch, enable_preview, append_loraname_if_empty, lora_stack=None, override_lora_name=""): def set_stack(self, lora_name, lora_weight, force_fetch, enable_preview, append_loraname_if_empty, lora_stack=None, override_lora_name=""):
if override_lora_name != "": if override_lora_name != "":
lora_name = {"content": override_lora_name, "image": ""} has_preview, prev = get_preview_path(override_lora_name, "loras")
prev = f"loras/{prev}" if has_preview else None
lora_name = {"content": override_lora_name, "image": prev, "type": "loras"}
civitai_tags_list = load_and_save_tags(lora_name["content"], force_fetch) civitai_tags_list = load_and_save_tags(lora_name["content"], force_fetch)
@@ -214,9 +222,9 @@ class LoraLoaderStackedAdvanced:
"subfolder": "lora_preview", "subfolder": "lora_preview",
"type": "temp" "type": "temp"
} }
return {"ui": {"images": [preview_output]}, "result": (civitai_tags_list, meta_tags_list, loras)} return {"ui": {"images": [preview_output]}, "result": (civitai_tags_list, meta_tags_list, loras, lora_name["content"])}
return {"result": (civitai_tags_list, meta_tags_list, loras)} return {"result": (civitai_tags_list, meta_tags_list, loras, lora_name["content"])}
class LoraTagsOnly: class LoraTagsOnly:
@classmethod @classmethod
@@ -249,7 +257,6 @@ class LoraTagsOnly:
return (civitai_tags_list, meta_tags_list) return (civitai_tags_list, meta_tags_list)
# A dictionary that contains all nodes you want to export with their names # A dictionary that contains all nodes you want to export with their names
# NOTE: names should be globally unique # NOTE: names should be globally unique
NODE_CLASS_MAPPINGS = { NODE_CLASS_MAPPINGS = {
+14
View File
@@ -0,0 +1,14 @@
[project]
name = "comfyui-lora-auto-trigger-words"
description = "The aim of these custom nodes is to get an easy access to the tags used to trigger a lora / lycoris. Extract the tags from civitai or from the safetensors metadatas when available."
version = "1.0.4"
license = "MIT"
[project.urls]
Repository = "https://github.com/idrirap/ComfyUI-Lora-Auto-Trigger-Words"
# Used by Comfy Registry https://comfyregistry.org
[tool.comfy]
PublisherId = "dijkstra"
DisplayName = "ComfyUI-Lora-Auto-Trigger-Words"
Icon = ""
+16 -8
View File
@@ -15,11 +15,14 @@ def get_preview_path(name, type):
file_path_no_ext = os.path.splitext(file_path)[0] file_path_no_ext = os.path.splitext(file_path)[0]
item_image=None item_image=None
for ext in ["png", "jpg", "jpeg", "preview.png"]: for ext in ["png", "jpg", "jpeg", "gif"]:
has_image = os.path.isfile(file_path_no_ext + "." + ext) if item_image is not None:
if has_image:
item_image = f"{file_name}.{ext}"
break break
for ext2 in ["", ".preview"]:
has_image = os.path.isfile(file_path_no_ext + ext2 + "." + ext)
if has_image:
item_image = f"{file_name}{ext2}.{ext}"
break
return has_image, item_image return has_image, item_image
@@ -31,6 +34,8 @@ def copy_preview_to_temp(file_name):
lora_less = "/".join(file_name.split("/")[1:]) lora_less = "/".join(file_name.split("/")[1:])
file_path = folder_paths.get_full_path("loras", lora_less) file_path = folder_paths.get_full_path("loras", lora_less)
if file_path is None:
return None, None
temp_path = folder_paths.get_temp_directory() temp_path = folder_paths.get_temp_directory()
preview_path = os.path.join(temp_path, "lora_preview") preview_path = os.path.join(temp_path, "lora_preview")
@@ -66,7 +71,7 @@ def load_json_from_file(file_path):
return None return None
except json.JSONDecodeError: except json.JSONDecodeError:
print(f"Error decoding JSON in file: {file_path}") print(f"Error decoding JSON in file: {file_path}")
return None raise
def save_dict_to_json(data_dict, file_path): def save_dict_to_json(data_dict, file_path):
try: try:
@@ -78,8 +83,11 @@ def save_dict_to_json(data_dict, file_path):
def get_model_version_info(hash_value): def get_model_version_info(hash_value):
api_url = f"https://civitai.com/api/v1/model-versions/by-hash/{hash_value}" api_url = f"https://civitai.com/api/v1/model-versions/by-hash/{hash_value}"
response = requests.get(api_url) try:
response = requests.get(api_url)
except Exception as e:
print(f"[Lora-Auto-Trigger] {e}")
return None
if response.status_code == 200: if response.status_code == 200:
return response.json() return response.json()
else: else:
@@ -219,4 +227,4 @@ def append_lora_name_if_empty(tags_list, lora_path, enabled):
filename = os.path.basename(filename) filename = os.path.basename(filename)
tags_list.append(filename) tags_list.append(filename)
return tags_list return tags_list
+36
View File
@@ -0,0 +1,36 @@
import { app } from "../../../scripts/app.js";
import { LoraInfoDialog } from "../../ComfyUI-Custom-Scripts/js/modelInfo.js";
const infoHandlers = {
"LoraLoaderVanilla":true,
"LoraLoaderStackedVanilla":true,
"LoraLoaderAdvanced":true,
"LoraLoaderStackedAdvanced":true
}
app.registerExtension({
name: "autotrigger.LoraInfo",
beforeRegisterNodeDef(nodeType) {
if (! infoHandlers[nodeType.comfyClass]) {
return;
}
const getExtraMenuOptions = nodeType.prototype.getExtraMenuOptions;
nodeType.prototype.getExtraMenuOptions = function (_, options) {
let value = this.widgets[0].value;
if (!value) {
return;
}
if (value.content) {
value = value.content;
}
options.unshift({
content: "View info...",
callback: async () => {
new LoraInfoDialog(value).show("loras", value);
},
});
return getExtraMenuOptions?.apply(this, arguments);
};
}
});