diff --git a/characters.json b/characters.json index de9b55f..7c1744d 100644 --- a/characters.json +++ b/characters.json @@ -88,5 +88,60 @@ "name": "Eris Greyrat", "associated_string": "eris greyrat, mushoku tensei", "prompt": "ahoge, hair between eyes, large breasts, long hair, red eyes, red hair" + }, + { + "name": "Karin", + "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" + }, + { + "name": "Yae Miko", + "associated_string": "yae miko, genshin impact", + "prompt": "animal ears, floppy ears, fox ears, hair between eyes, large breasts, long hair, pink hair, purple eyes, very long hair" + }, + { + "name": "Lisa", + "associated_string": "lisa \\(genshin impact\\), genshin impact", + "prompt": "light brown hair, green eyes, hair between eyes, hair ornament, large breasts" + }, + { + "name": "Mona", + "associated_string": "mona \\(genshin impact\\), genshin impact", + "prompt": "aqua eyes, black ribbon, hair ribbon, long hair, purple hair, ribbon, twintails" + }, + { + "name": "Kujou Sara", + "associated_string": "kujou sara, genshin impact", + "prompt": "black hair, large breasts, short hair, swept bangs, yellow eyes, bird mask, mask on head" + }, + { + "name": "Noelle (Genshin Impact)", + "associated_string": "noelle \\(genshin impact\\), genshin impact", + "prompt": "blunt bangs, braid, braided bangs, brown eyes, grey hair, hair ornament, short hair, red rose" + }, + { + "name": "Yor Briar", + "associated_string": "yor briar, spy x family", + "prompt": "black hair, large breasts, long hair, red eyes, very long hair, white hairband" + }, + { + "name": "Shylily", + "associated_string": "shylily, shylily \\(bikini\\), indie virtual youtuber", + "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", + "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)", + "associated_string": "asuna \\(sao\\), sword art online", + "prompt": "braid, brown eyes, brown hair, french braid, large breasts, long hair, short ponytail, very long hair" + }, + { + "name": "Kafka", + "associated_string": "kafka \\(honkai: star rail\\), honkai \\(series\\), honkai: star rail", + "prompt": "colored inner hair, hair between eyes, large breasts, multicolored hair, pink hair, purple eyes, purple hair" } ] diff --git a/src/load_lora_character.py b/src/load_lora_character.py index 7666da9..207272d 100644 --- a/src/load_lora_character.py +++ b/src/load_lora_character.py @@ -23,6 +23,25 @@ class LoadLoraCharacterNode: FUNCTION = "find_and_apply_lora" CATEGORY = "sn0w" + def levenshtein_distance(self, s1, s2): + if len(s1) < len(s2): + return self.levenshtein_distance(s2, s1) + + if len(s2) == 0: + return len(s1) + + previous_row = range(len(s2) + 1) + for i, c1 in enumerate(s1): + current_row = [i + 1] + for j, c2 in enumerate(s2): + insertions = previous_row[j + 1] + 1 + deletions = current_row[j] + 1 + substitutions = previous_row[j] + (c1 != c2) + current_row.append(min(insertions, deletions, substitutions)) + previous_row = current_row + + return previous_row[-1] + def clean_string(self, input_string): # Remove parentheses and escape characters cleaned_string = re.sub(r'[\\()]', '', input_string) @@ -47,7 +66,7 @@ class LoadLoraCharacterNode: if cleaned_associated_string == cleaned_character: character_name = char['name'] break - + if character_name: lora_loader = LoraLoader() @@ -59,23 +78,21 @@ class LoadLoraCharacterNode: # Extract just the filenames for comparison lora_filenames = [path.split('\\')[-1] for path in lora_paths] - # Find the associated lora path - lora_path = None - character_name_parts = character_name.lower().split() + # Initialize variables to find the most similar filename + closest_match = None + lowest_distance = float('inf') for filename in lora_filenames: - if any(part in filename.lower() for part in character_name_parts): - # Find the full path in full_lora_path - for full_path in full_lora_path: - if filename.lower() in full_path.lower(): - lora_path = full_path - break - if lora_path: - break + distance = self.levenshtein_distance(character_name.lower(), filename.lower()) + if distance < lowest_distance: + lowest_distance = distance + closest_match = filename - print_sn0w(lora_path) + # Find the full path for the closest match + lora_path = next((full_path for full_path in full_lora_path if closest_match.lower() in full_path.lower()), None) if lora_path: + print_sn0w(lora_path) model, clip = lora_loader.load_lora(model, clip, lora_path, lora_strength, lora_strength) - return (model, clip, ) \ No newline at end of file + return model, clip \ No newline at end of file