From 76ee9a7d43ed41b3f90c36ed145dc65f1ef133b4 Mon Sep 17 00:00:00 2001 From: sn0w12 Date: Mon, 19 Feb 2024 17:11:49 +0100 Subject: [PATCH] Update readme, changed characters, made load character remove file extension for comparison --- README.md | 11 +++++++---- __init__.py | 3 --- characters.json | 30 +++++++++++++++--------------- src/load_lora_character.py | 6 +++--- src/split_string.py | 25 ------------------------- 5 files changed, 25 insertions(+), 50 deletions(-) delete mode 100644 src/split_string.py diff --git a/README.md b/README.md index b93bee1..f06fc68 100644 --- a/README.md +++ b/README.md @@ -109,14 +109,17 @@ Many of the nodes require these paths to be in your extra_model_paths.yaml (with > ![Example](./imgs/lora_paths_example.png) > -## Split String -> Splits a string into 4 parts. +## Load Lora Character +> Finds and applies the closest matching Lora model to a character based on name similarity. >
> ℹ️ See More Information > -> - Splits a string into 4 parts, not very useful. +> - The process begins by cleaning the input character string for comparison. It then searches a JSON file for a matching character name. If a match is found, it proceeds to select the appropriate folder based on the `xl` boolean flag. +> - To find the closest Lora model, it calculates the Levenshtein distance between the character name (in full and in parts) and the filenames of available Lora models. This ensures a case-insensitive match with the best possible model. +> - If no lora is found it just returns the input model and the workflow can continue. > -> ![Split String](./imgs/split_string.png) +> +> ![Load Lora Character](./imgs/load_lora_character.png) >
# Example Workflows \ No newline at end of file diff --git a/__init__.py b/__init__.py index 4cf2d6f..8e27475 100644 --- a/__init__.py +++ b/__init__.py @@ -1,5 +1,4 @@ from .src.find_resolution import FindResolutionNode -from .src.split_string import SplitStringNode from .src.lora_selector import LoraSelectorNode from .src.lora_tester_xl import LoraTestXLNode from .src.lora_tester import LoraTestNode @@ -18,7 +17,6 @@ from .src.load_lora_concept import LoadLoraConceptNode NODE_CLASS_MAPPINGS = { "Find SDXL Resolution": FindResolutionNode, - "Split String": SplitStringNode, "Lora Selector": LoraSelectorNode, "Lora Tester XL": LoraTestXLNode, "Lora Tester": LoraTestNode, @@ -38,7 +36,6 @@ NODE_CLASS_MAPPINGS = { NODE_DISPLAY_NAME_MAPPINGS = { "Find SDXL Resolution": "Find SDXL Resolution", - "Split String": "Split string into 4", "Lora Selector": "Lora Selector", "Lora Tester XL": "Lora Tester XL", "Lora Tester": "Lora Tester", diff --git a/characters.json b/characters.json index 906a068..7a3dd1f 100644 --- a/characters.json +++ b/characters.json @@ -1,6 +1,6 @@ [ { - "name": "Darkness", + "name": "Darkness (Konosuba)", "associated_string": "darkness \\(konosuba\\), kono subarashii sekai ni shukufuku wo!", "prompt": "blonde hair, blue eyes, x hair ornament, large breasts, hair between eyes, hair ornament, long hair, " }, @@ -20,7 +20,7 @@ "prompt": "pink hair, blue eyes, breasts, cube hair ornament, hair between eyes, hair ornament, large breasts, long hair, " }, { - "name": "Aqua", + "name": "Aqua (Konosuba)", "associated_string": "aqua \\(konosuba\\), kono subarashii sekai ni shukufuku wo!", "prompt": "blue eyes, blue hair, hair ornament, long hair, large breasts, " }, @@ -50,12 +50,12 @@ "prompt": "blonde hair, choker, ear piercing, bangs, jewelry, large breasts, earrings, very long hair, red eyes, swept bangs" }, { - "name": "Lucy", + "name": "Lucy (Cyberpunk)", "associated_string": "lucy \\(cyberpunk\\), cyberpunk \\(series\\), cyberpunk edgerunners", "prompt": "breasts, eyeliner, makeup, medium breasts, multicolored eyes, multicolored hair, parted bangs, red eyeliner, short hair, white hair" }, { - "name": "Rebecca", + "name": "Rebecca (Cyberpunk)", "associated_string": "rebecca \\(cyberpunk\\), cyberpunk \\(series\\), cyberpunk edgerunners", "prompt": "artificial eye, breasts, colored sclera, colored skin, green eyes, green hair, leg tattoo, long hair, mechanical eye, medium breasts, neck tattoo, parted bangs, red sclera, stomach tattoo, tattoo, white skin" }, @@ -90,7 +90,7 @@ "prompt": "ahoge, hair between eyes, large breasts, long hair, red eyes, red hair" }, { - "name": "Karin", + "name": "Karin (Blue Archive)", "associated_string": "karin \\(blue archive\\), blue archive", "prompt": "black hair, dark-skinned female, hair between eyes, halo, large breasts, long hair, purple hair, purple halo, very long hair, yellow eyes" }, @@ -100,12 +100,12 @@ "prompt": "animal ears, floppy ears, fox ears, hair between eyes, large breasts, long hair, pink hair, purple eyes, very long hair" }, { - "name": "Lisa", + "name": "Lisa (Genshin Impact)", "associated_string": "lisa \\(genshin impact\\), genshin impact", "prompt": "light brown hair, green eyes, hair between eyes, hair ornament, large breasts" }, { - "name": "Mona", + "name": "Mona (Genshin Impact)", "associated_string": "mona \\(genshin impact\\), genshin impact", "prompt": "aqua eyes, black ribbon, hair ribbon, long hair, purple hair, ribbon, twintails" }, @@ -130,12 +130,12 @@ "prompt": "ahoge, blue hair, large breasts, long hair, multicolored hair, purple eyes, two-tone hair, virtual youtuber, white hair, animal ears, facial mark, orca girl" }, { - "name": "Hasumi", + "name": "Hasumi (Blue Archive)", "associated_string": "hasumi \\(blue archive\\), blue archive", "prompt": "black hair, large breasts, long hair, ponytail, red eyes, very long hair, feathered wings, red halo" }, { - "name": "Asuna (sao)", + "name": "Asuna (Sao)", "associated_string": "asuna \\(sao\\), sword art online", "prompt": "braid, brown eyes, brown hair, french braid, large breasts, long hair, short ponytail, very long hair" }, @@ -145,12 +145,12 @@ "prompt": "colored inner hair, hair between eyes, large breasts, multicolored hair, pink hair, purple eyes, purple hair" }, { - "name": "Albedo (overlord)", + "name": "Albedo (Overlord)", "associated_string": "albedo \\(overlord\\), overlord \\(maruyama\\)", "prompt": "ahoge, black hair, hair between eyes, large breasts, long hair, very long hair, yellow eyes, slit pupils, horns, feathered wings, low wings" }, { - "name": "Asuka (evangelion)", + "name": "Asuka (Evangelion)", "associated_string": "souryuu asuka langley, neon genesis evangelion", "prompt": "aged up, blue eyes, brown hair, hair between eyes, long hair, medium breasts" }, @@ -160,7 +160,7 @@ "prompt": "eyeshadow, hair ornament, large breasts, makeup, red eyes, red eyeshadow, short hair, white hair" }, { - "name": "Owari (azur lane)", + "name": "Owari (Azur Lane)", "associated_string": "owari \\(azur lane\\), owari \\(shimmering forsythia\\) (azur lane), azur lane", "prompt": "asymmetrical bangs, blonde hair, braid, brown eyes, dark-skinned female, dark skin, large breasts, long bangs, long hair, low twin braids, twin braids, very long hair" }, @@ -175,12 +175,12 @@ "prompt": "black hair, blunt bangs, hair ornament, large breasts, long hair, purple eyes" }, { - "name": "Laruna (granblue fantasy)", + "name": "Laruna (Granblue Fantasy)", "associated_string": "laruna \\(granblue fantasy\\), granblue fantasy", "prompt": "blue eyes, braid, hair ornament, large breasts, light purple hair, long hair, single braid, low tied hair, draph, mature female, horns" }, { - "name": "Implacable (azur lane)", + "name": "Implacable (Azur Lane)", "associated_string": "implacable \\(azur lane\\), azur lane", "prompt": "blonde hair, hair between eyes, large breasts, long hair, red eyes, very long hair, white horns, fake horns" }, @@ -200,7 +200,7 @@ "prompt": "blonde hair, forehead mark, large breasts, long hair, parted bangs, brown eyes, mature female, hair intakes" }, { - "name": "Asuna (blue archive)", + "name": "Asuna (Blue Archive)", "associated_string": "asuna \\(blue archive\\), asuna \\(bunny\\) (blue archive), blue archive", "prompt": "blue eyes, blue ribbon, hair ribbon, large breasts, light brown hair, very long hair, ribbon" } diff --git a/src/load_lora_character.py b/src/load_lora_character.py index 947b700..11e841c 100644 --- a/src/load_lora_character.py +++ b/src/load_lora_character.py @@ -84,9 +84,9 @@ class LoadLoraCharacterNode: lowest_distance = float('inf') for filename in lora_filenames: - # Convert filename to lowercase for case-insensitive comparison. - filename_lower = filename.lower() - + # Convert filename to lowercase for case-insensitive comparison and remove file extension. + filename_lower = os.path.splitext(filename.lower())[0] + if any(part in filename_lower for part in character_name_parts): # Calculate the Levenshtein distance for the full character name as one of the metrics. full_name_distance = self.levenshtein_distance(character_name_lower, filename_lower) diff --git a/src/split_string.py b/src/split_string.py deleted file mode 100644 index d743eea..0000000 --- a/src/split_string.py +++ /dev/null @@ -1,25 +0,0 @@ -class SplitStringNode: - @classmethod - def INPUT_TYPES(cls): - return { - "required": { - "text": ("STRING", {"default": ""}), - "separator": ("STRING", {"default": ";"}), - }, - } - - RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING",) - RETURN_NAMES = ("STRING_A", "STRING_B", "STRING_C", "STRING_D",) - FUNCTION = "split_string" - CATEGORY = "sn0w" - - def split_string(self, text, separator): - # Split the text by the separator - parts = text.split(separator) - - # Ensure there are exactly four parts - # If not enough parts, extend with empty strings - parts.extend([""] * (4 - len(parts))) - - # Return the first four parts - return tuple(parts[:4])