216 lines
9.1 KiB
Python
216 lines
9.1 KiB
Python
import random
|
|
import re
|
|
|
|
_NAMES_USA = [
|
|
"Aiko", "Alara", "Amara", "Amira", "Andromeda", "Aoife", "Ara", "Aria",
|
|
"Ariel", "Arya", "Asel", "Ashira", "Astrid", "Aurora", "Aya", "Ayame",
|
|
"Bree", "Briar", "Calla", "Calypso", "Celeste", "Clio", "Cora", "Dalia",
|
|
"Dawn", "Daya", "Delia", "Deva", "Eila", "Eira", "Elara", "Elene",
|
|
"Elin", "Elira", "Ember", "Era", "Eris", "Estelle", "Eve", "Faye",
|
|
"Fern", "Fiora", "Fleur", "Flora", "Gaia", "Greer", "Gwen", "Halo",
|
|
"Haven", "Hera", "Ida", "Indra", "Io", "Iris", "Iva", "Jade",
|
|
"Jaya", "Juno", "Kai", "Kaia", "Kaya", "Kessa", "Kira", "Laia",
|
|
"Leda", "Lila", "Lira", "Lirien", "Luma", "Luna", "Lyra", "Maia",
|
|
"Mara", "Marit", "Maya", "Meira", "Mira", "Miya", "Nadia", "Naia",
|
|
"Nara", "Neva", "Nia", "Nike", "Nina", "Noor", "Nora", "Nova",
|
|
"Nyx", "Ora", "Orla", "Petra", "Quinn", "Ren", "Rhea", "Riona",
|
|
"Rue", "Saga", "Sage", "Sarai", "Selene", "Sera", "Silva", "Sol",
|
|
"Sora", "Sylva", "Tala", "Tara", "Theia", "Tova", "Ula", "Uma",
|
|
"Una", "Vega", "Vela", "Vera", "Vesper", "Vira", "Vivi", "Wren",
|
|
"Xara", "Xena", "Yael", "Yuki", "Zara", "Zita", "Zoe", "Zora",
|
|
]
|
|
|
|
_NAMES = [
|
|
"Aaf", "Aafje", "Aafke", "Aagje", "Aaltje", "Abby", "Abigail", "Ada",
|
|
"Adèle", "Adriana", "Agnes", "Aisha", "Ayla", "Alana", "Aletta", "Alexandra",
|
|
"Alice", "Alicia", "Alida", "Alina", "Alise", "Aliza", "Alma", "Amalia",
|
|
"Amanda", "Amber", "Amelie", "Amélie", "Amira", "Amy", "An", "Ana",
|
|
"Anabel", "Anastasia", "Andrea", "Angela", "Angelina", "Aniek", "Anika",
|
|
"Anissa", "Anja", "Anke", "Anna", "Annabel", "Anne", "Annebel",
|
|
"Annemarie", "Annet", "Annette", "Annie", "Anouk", "Ans", "Antje",
|
|
"Antoinette", "Ariane", "Arianna", "Ariana", "Arwen", "Ashley", "Astrid",
|
|
"Aukje", "Aurora", "Avalon", "Aya",
|
|
|
|
"Babette", "Barbara", "Bea", "Beatrix", "Beau", "Bente", "Berber",
|
|
"Bernadette", "Bertje", "Betsy", "Bianca", "Bibi", "Bodil", "Bo",
|
|
"Bobbi", "Bregje", "Brechtje", "Brenda", "Brit", "Britt",
|
|
|
|
"Cato", "Catharina", "Celine", "Céline", "Cemre", "Chantal", "Charlotte",
|
|
"Chelsey", "Chiara", "Chloë", "Christa", "Christel", "Christina", "Cindy",
|
|
"Claire", "Clara", "Clarissa", "Claudia", "Cleo", "Coby", "Conny", "Cora",
|
|
"Cornelia", "Cynthia",
|
|
|
|
"Daantje", "Dafne", "Daisy", "Dana", "Daniëlle", "Daphne", "Debbie",
|
|
"Demi", "Denise", "Desi", "Diana", "Dide", "Diede", "Dieuwertje", "Dina",
|
|
"Dinja", "Dionne", "Do", "Dominique", "Doortje", "Dora", "Doris", "Doutzen",
|
|
|
|
"Eef", "Eefje", "Eeke", "Eline", "Elisa", "Elise", "Elisabeth", "Ella",
|
|
"Elle", "Ellen", "Ellemijn", "Ellis", "Els", "Elsa", "Else", "Elvira",
|
|
"Emilia", "Emma", "Emmy", "Eva", "Evelien", "Eveline", "Evi",
|
|
|
|
"Fabiënne", "Famke", "Fay", "Faye", "Fem", "Femke", "Fenna", "Fenne",
|
|
"Fien", "Fiene", "Fieke", "Fleur", "Fleurtje", "Floor", "Floortje",
|
|
"Flore", "Florianne", "Froukje",
|
|
|
|
"Gabriëlle", "Gea", "Geertje", "Geertruida", "Geke", "Gerda", "Gerdi",
|
|
"Gerdien", "Gertrude", "Ghislaine", "Gina", "Gitte", "Greet", "Greetje",
|
|
"Greta", "Grietje", "Guusje", "Gwen",
|
|
|
|
"Hanna", "Hannah", "Hanne", "Hanneke", "Hannelore", "Harriët", "Hedwig",
|
|
"Heleen", "Helena", "Helene", "Henriëtte", "Hester", "Hilde", "Hinke",
|
|
|
|
"Ilona", "Ilse", "Imke", "Imme", "Ina", "Indy", "Ineke", "Ines", "Inge",
|
|
"Ingrid", "Iris", "Isa", "Isabel", "Isabella", "Isabelle", "Ise", "Iva",
|
|
"Ivana",
|
|
|
|
"Jacoba", "Jacqueline", "Jada", "Jade", "Janna", "Janne", "Janneke",
|
|
"Jantien", "Jasmijn", "Jasmine", "Jayda", "Jelka", "Jelke", "Jente",
|
|
"Jenthe", "Jet", "Jette", "Jill", "Jo", "Joan", "Joanna", "Johanna",
|
|
"Jolanda", "Jolie", "Josephine", "Josje", "Judith", "Julia", "Julie",
|
|
"Juliette", "Juna", "Juni", "Juul", "Juut",
|
|
|
|
"Kaat", "Kaatje", "Karen", "Karin", "Karlijn", "Kiki", "Kim", "Kirsten",
|
|
"Klara", "Klasina", "Kris", "Kristel",
|
|
|
|
"Lana", "Lara", "Laura", "Laurien", "Lena", "Lene", "Leni", "Lenie",
|
|
"Lenthe", "Lieke", "Lien", "Lieve", "Linde", "Lindsey", "Lisa", "Lisanne",
|
|
"Liset", "Liselotte", "Livia", "Liz", "Liza", "Lizzy", "Loïs", "Lola",
|
|
"Lonneke", "Lotte", "Lou", "Louise", "Lova", "Luca", "Lucia", "Lucie",
|
|
"Luna",
|
|
|
|
"Maaike", "Maan", "Maartje", "Maayke", "Madeleine", "Madelief", "Maike",
|
|
"Maja", "Malou", "Manon", "Mara", "Mare", "Margot", "Margriet", "Maria",
|
|
"Marieke", "Marije", "Marijne", "Marit", "Marja", "Marjan", "Marjolein",
|
|
"Marleen", "Marloes", "Marlot", "Marly", "Martha", "Marthe", "Mathilde",
|
|
"Maud", "Mees", "Meike", "Melanie", "Melissa", "Merel", "Mette", "Mia",
|
|
"Mieke", "Mila", "Milou", "Minke", "Mira", "Mirjam", "Myrthe",
|
|
|
|
"Naomi", "Natasja", "Nathalie", "Nena", "Nienke", "Nina", "Noa", "Noëlle",
|
|
"Noor", "Nora", "Nova",
|
|
|
|
"Olivia", "Olga",
|
|
|
|
"Pien", "Pleun",
|
|
|
|
"Quinty",
|
|
|
|
"Renske", "Renée", "Rianne", "Riek", "Rika", "Rina", "Rinske", "Rivka",
|
|
"Robin", "Romy", "Roos", "Roosmarijn", "Rosa", "Rosalie", "Rosanne",
|
|
"Rose", "Rowena", "Ruby",
|
|
|
|
"Sabine", "Sanne", "Sara", "Sarah", "Sarina", "Saskia", "Selma", "Senna",
|
|
"Sera", "Sharon", "Silke", "Sjoukje", "Sofie", "Sophie", "Soraya",
|
|
"Sterre", "Susan", "Susanne", "Suzan", "Suzanne", "Suze", "Sylvia",
|
|
|
|
"Tamar", "Tara", "Tess", "Tessa", "Teuntje", "Thea", "Theodora", "Thera",
|
|
"Theresa", "Thirza", "Tine", "Tineke", "Tirza", "Tjitske", "Toos",
|
|
"Trijntje", "Truus",
|
|
|
|
"Valerie", "Veerle", "Vera", "Vera-Lynn", "Veronique", "Victoria", "Vienna",
|
|
"Vieve", "Vita", "Vivian", "Vivienne",
|
|
|
|
"Wende", "Wendy", "Wiep", "Wietske", "Wies", "Wiesje", "Willeke", "Wilma",
|
|
|
|
"Yara", "Yfke", "Ymkje", "Yolanda", "Yuna",
|
|
|
|
"Zara", "Zoë", "Zofia", "Zonne", "Zwaantje",
|
|
]
|
|
|
|
def generate_associative_name(tags=None):
|
|
"""Return a random evocative name for a new group."""
|
|
return random.choice(_NAMES)
|
|
|
|
|
|
def clean_tag(tag):
|
|
return tag.replace("_", " ").strip()
|
|
|
|
|
|
def generate_associative_description(tags):
|
|
"""
|
|
Generate a 'real-alike' associative name based on WD tagger tags.
|
|
tags: list of dicts {'tag': str, 'score': float, 'cat': int}
|
|
"""
|
|
if not tags:
|
|
return None
|
|
|
|
# Filter by score
|
|
high_score_tags = [t for t in tags if t['score'] > 0.4]
|
|
if not high_score_tags:
|
|
high_score_tags = tags[:5]
|
|
|
|
# Categories: 0=general, 4=character
|
|
characters = [clean_tag(t['tag']) for t in high_score_tags if t['cat'] == 4]
|
|
general = [clean_tag(t['tag']) for t in high_score_tags if t['cat'] == 0]
|
|
|
|
# Key attributes
|
|
subject = None
|
|
if characters:
|
|
subject = characters[0].title()
|
|
elif "1girl" in [t['tag'] for t in high_score_tags]:
|
|
subject = "Maiden"
|
|
elif "1boy" in [t['tag'] for t in high_score_tags]:
|
|
subject = "Youth"
|
|
else:
|
|
subject = "Subject"
|
|
|
|
# Actions/Poses
|
|
actions = ["standing", "sitting", "lying", "running", "walking", "dancing", "sleeping"]
|
|
found_action = next((clean_tag(t['tag']) for t in high_score_tags if t['tag'] in actions), None)
|
|
|
|
# Setting/Background
|
|
settings = ["forest", "beach", "city", "space", "room", "garden", "ocean", "mountain", "sky", "underwater", "street"]
|
|
found_setting = next((clean_tag(t['tag']) for t in high_score_tags if t['tag'] in settings), None)
|
|
|
|
# Appearance
|
|
colors = ["red", "blue", "green", "white", "black", "gold", "silver", "pink", "purple", "yellow"]
|
|
found_color = next((clean_tag(t['tag']) for t in high_score_tags if clean_tag(t['tag']).split()[0] in colors), None)
|
|
if not found_color:
|
|
found_color = next((clean_tag(t['tag']) for t in high_score_tags if any(c in t['tag'] for c in colors)), None)
|
|
|
|
# Styles/Atmosphere
|
|
styles = ["cyberpunk", "fantasy", "realistic", "ethereal", "dark", "bright", "sketch", "oil painting"]
|
|
found_style = next((clean_tag(t['tag']) for t in high_score_tags if t['tag'] in styles), None)
|
|
|
|
# Build the name
|
|
templates = []
|
|
|
|
if found_style and subject:
|
|
templates.append(f"{found_style.title()} {subject}")
|
|
|
|
if found_color and subject:
|
|
templates.append(f"The {found_color.title()} {subject}")
|
|
|
|
if subject and found_action:
|
|
if found_action.endswith("ing"):
|
|
templates.append(f"{subject} {found_action.title()}")
|
|
else:
|
|
# Basic attempt at present participle
|
|
action_ing = found_action
|
|
if action_ing.endswith("e"):
|
|
action_ing = action_ing[:-1] + "ing"
|
|
else:
|
|
action_ing += "ing"
|
|
templates.append(f"{subject} {action_ing.title()}")
|
|
|
|
if subject and found_setting:
|
|
templates.append(f"{subject} in the {found_setting.title()}")
|
|
|
|
if found_style and found_setting:
|
|
templates.append(f"{found_style.title()} {found_setting.title()}")
|
|
|
|
if not templates:
|
|
# Fallback: combine two random general tags
|
|
if len(general) >= 2:
|
|
return f"{general[0].title()} {general[1].title()}"
|
|
elif general:
|
|
return general[0].title()
|
|
else:
|
|
return "Untitled Artwork"
|
|
|
|
# Return a random template result
|
|
return random.choice(templates)
|
|
|
|
def get_base_name(name: str) -> str:
|
|
"""Remove timestamp prefixes from filename."""
|
|
return re.sub(r'^(\d{8}_\d{6}_)+', '', name)
|