|
import tkinter as tk |
|
import tkinter.ttk as ttk |
|
from tkinter import filedialog |
|
import os |
|
import csv |
|
import random |
|
import time |
|
from collections import Counter |
|
import re |
|
import ast |
|
import pyautogui |
|
import threading |
|
from pynput import keyboard |
|
from base64 import urlsafe_b64encode |
|
from hashlib import blake2b |
|
import argon2 |
|
import requests |
|
import json |
|
from os import environ as env |
|
import zipfile |
|
import io |
|
from pathlib import Path |
|
from datetime import datetime |
|
import numpy as np |
|
from PIL import Image, ImageOps, ImageDraw, ImageFont,ImageTk |
|
from IPython.display import display |
|
import win32clipboard |
|
from io import BytesIO |
|
from datetime import datetime |
|
import arti_list, tagbag, wlist, copyright_list_reformatted, remove_result_e, remove_result_qe |
|
import character_dictionary as cd |
|
import pandas as pd |
|
import webbrowser |
|
from collections import OrderedDict |
|
|
|
BASE_URL="https://api.novelai.net" |
|
copyright_keys = copyright_list_reformatted.copyright_list |
|
character_keys = list(cd.character_dictionary.keys()) |
|
nsfw_word = list(remove_result_e.keyword_counts.keys()) |
|
questionable_word = list(remove_result_qe.keyword_counts.keys()) |
|
qe_word = nsfw_word + questionable_word |
|
|
|
def argon_hash(email: str, password: str, size: int, domain: str) -> str: |
|
pre_salt = f"{password[:6]}{email}{domain}" |
|
|
|
blake = blake2b(digest_size=16) |
|
blake.update(pre_salt.encode()) |
|
salt = blake.digest() |
|
raw = argon2.low_level.hash_secret_raw( |
|
password.encode(), |
|
salt, |
|
2, |
|
int(2000000 / 1024), |
|
1, |
|
size, |
|
argon2.low_level.Type.ID, |
|
) |
|
hashed = urlsafe_b64encode(raw).decode() |
|
return hashed |
|
|
|
def login(key) -> str: |
|
response = requests.post(f"{BASE_URL}/user/login", json={ "key": key }) |
|
|
|
return response.json()["accessToken"] |
|
|
|
def get_access_key(email: str, password: str) -> str: |
|
return argon_hash(email, password, 64, "novelai_data_access_key")[:64] |
|
|
|
def get_max_size(): |
|
global window |
|
width = window.winfo_screenheight() |
|
return 768 if width < 1440 else 1024 |
|
|
|
def generate_image(access_token, prompt, model, action, parameters): |
|
data = { |
|
"input": prompt, |
|
"model": model, |
|
"action": action, |
|
"parameters": parameters, |
|
} |
|
|
|
response = requests.post(f"{BASE_URL}/ai/generate-image", json=data, headers={ "Authorization": f"Bearer {access_token}" }) |
|
|
|
return response.content |
|
|
|
def history_queue(image, prompt, seed): |
|
global history |
|
history.append([image, prompt, seed]) |
|
if len(history) > 5: |
|
history.pop(0) |
|
|
|
def show_history(): |
|
global history |
|
|
|
|
|
history_window = tk.Toplevel(window) |
|
history_window.title("History") |
|
|
|
|
|
for index, (image, prompt, seed) in enumerate(history): |
|
|
|
image.thumbnail((192, 192)) |
|
photo = ImageTk.PhotoImage(image) |
|
|
|
|
|
image_label = tk.Label(history_window, image=photo) |
|
image_label.image = photo |
|
image_label.grid(row=index, column=0) |
|
|
|
|
|
text_prompt = prompt + ' Seed: ' + str(seed) |
|
text_widget = tk.Text(history_window, height=10, width=75) |
|
text_widget.insert('1.0', text_prompt) |
|
text_widget.grid(row=index, column=1) |
|
text_widget.config(state='disabled') |
|
|
|
def generate(width, height, positive, negative, button): |
|
global temp_clipboard_image |
|
global current_sampler |
|
global NAI_width, NAI_height |
|
global running_flag |
|
global last_generation_seed |
|
try: |
|
scale = float(entry_CFG_value.get()) |
|
except: |
|
scale = 5.0 |
|
if scale > 7.0: scale = 7.0 |
|
elif scale < 4.0: scale = 4.0 |
|
else: scale = round(scale, 1) |
|
|
|
try: |
|
scale2 = float(entry_rescale_value.get()) |
|
except: |
|
scale2 = 0 |
|
if scale2 > 1.00: scale = 1.00 |
|
elif scale2 < 0.0: scale = 0.00 |
|
else: scale2 = round(scale2, 2) |
|
|
|
params = { |
|
"legacy": False, |
|
"quality_toggle": False, |
|
"width": width, |
|
"height": height, |
|
"n_samples": 1, |
|
"seed": random.randint(0,9999999999), |
|
"extra_noise_seed": random.randint(0,9999999999), |
|
"sampler": current_sampler, |
|
"steps": 28, |
|
"scale": scale, |
|
"uncond_scale": 1.0, |
|
"negative_prompt": negative_text.get("1.0", "end-1c").strip(), |
|
"sm" : sema_button_var.get(), |
|
"sm_dyn" : dyn_button_var.get(), |
|
"decrisper": False, |
|
"controlnet_strength": 1.0, |
|
"add_original_image": False, |
|
"cfg_rescale": scale2, |
|
"noise_schedule": "native", |
|
} |
|
|
|
if (hold_seed_var.get()): |
|
params['seed'] = last_generation_seed |
|
|
|
def resize_and_fill(image, max_size=None): |
|
if max_size is None: |
|
max_size = get_max_size() |
|
original_width, original_height = image.size |
|
if original_width > max_size or original_height > max_size: |
|
|
|
image.thumbnail((max_size, max_size)) |
|
|
|
|
|
width, height = image.size |
|
new_image = Image.new("RGB", (max_size, max_size), "black") |
|
new_image.paste(image, ((max_size - width) // 2, (max_size - height) // 2)) |
|
return new_image |
|
else: |
|
return image |
|
|
|
def log_error(e, output_file_path="output_file_path"): |
|
|
|
current_time = datetime.now().strftime("%m/%d %H:%M:%S") |
|
|
|
|
|
error_message = f"#### Error occured at {current_time} ####\nError: {e}\n############################################\n" |
|
|
|
|
|
with open(f"error_log.txt", "a") as file: |
|
file.write(error_message) |
|
|
|
global access_token, access_token_multi, error_count, multi_token_enable |
|
while (running_flag): |
|
time.sleep(1) |
|
try: |
|
running_flag = True |
|
tprint("Running : NAI request received") |
|
if not (multi_token_enable): zipped_bytes = generate_image(access_token, positive, "nai-diffusion-3", "generate", params) |
|
else: zipped_bytes = generate_image(access_token_multi, positive, "nai-diffusion-3", "generate", params) |
|
d = Path(f"output_NAI/{start_time}/txt2img") |
|
d.mkdir(parents=True, exist_ok=True) |
|
zipped = zipfile.ZipFile(io.BytesIO(zipped_bytes)) |
|
image_bytes = zipped.read(zipped.infolist()[0]) |
|
(d / f"{datetime.now().strftime('%Y%m%d_%H%M%S')}.png" ).write_bytes(image_bytes) |
|
i = Image.open(io.BytesIO(image_bytes)) |
|
i = ImageOps.exif_transpose(i).convert("RGB") |
|
if temp_clipboard_image is not None: |
|
temp_clipboard_image.close() |
|
temp_clipboard_image = i |
|
i_resized = resize_and_fill(i) |
|
if 'tk_image' in globals(): |
|
globals()['tk_image'] = None |
|
tk_image = ImageTk.PhotoImage(i_resized) |
|
image_label.config(image=tk_image) |
|
image_label.original_image = i.copy() |
|
image_label.image = tk_image |
|
output_file_path = "output_image.jpg" |
|
history_queue(i_resized.copy(), positive, params['seed']) |
|
i.save(output_file_path) |
|
error_count = 0 |
|
except Exception as e: |
|
|
|
log_error(zipped_bytes.decode('utf-8')[2:-2], "path_to_output_folder") |
|
time.sleep(random.uniform(1.0, 2.5)) |
|
error_count += 1 |
|
if error_count > 5: |
|
mac_var.set(0) |
|
button.config(state=tk.NORMAL) |
|
|
|
global delay_offset |
|
time.sleep(delay_offset) |
|
|
|
running_flag = False |
|
last_generation_seed = params['seed'] |
|
entry_seed_value.set(last_generation_seed) |
|
|
|
if mac_var.get() and not running_flag: |
|
random_function() |
|
time.sleep(random.uniform(5.1, 8.5)) |
|
button.config(state=tk.DISABLED) |
|
window.event_generate(GENERATE_EVENT, when="tail") |
|
else: |
|
time.sleep(random.uniform(1.0, 2.5)) |
|
button.config(state=tk.NORMAL) |
|
tprint('state : idle') |
|
|
|
def filter_csv(input_file, output_file, _search_strings): |
|
output_directory = os.getcwd() |
|
output_file = os.path.join(output_directory, output_file) |
|
search_strings = [s.strip() for s in _search_strings.split(',')] |
|
with open(input_file, 'r', newline='', encoding='utf-8') as f_in, \ |
|
open(output_file, 'w', newline='', encoding='utf-8') as f_out: |
|
reader = csv.reader(f_in) |
|
writer = csv.writer(f_out) |
|
writer_count = 0 |
|
for row in reader: |
|
if all(search_str in value for search_str in search_strings for value in row): |
|
writer.writerow(row) |
|
writer_count += 1 |
|
return writer_count |
|
|
|
def open_file(): |
|
initial_dir = os.getcwd() |
|
filepath = filedialog.askopenfilename( |
|
initialdir=initial_dir, |
|
filetypes=[("CSV Files", "*.csv")] |
|
) |
|
if filepath: |
|
entry_file_path.delete(0, tk.END) |
|
entry_file_path.insert(0, filepath) |
|
|
|
def search(): |
|
global total_rows, cached_rows |
|
input_file = entry_file_path.get() |
|
keywords = entry_keyword.get() |
|
|
|
output_file = 'txt2img_temp_prompt.csv' |
|
writer_count = filter_csv(input_file, output_file, keywords) |
|
total_rows = writer_count |
|
total_rows_count_label.config(text=f".csv ๋ด ํ๋กฌํํธ ํ: {writer_count}", fg="blue") |
|
text_output.insert(tk.END, f"์ด {writer_count}๊ฐ์ ๋ฌธ์์ด์ด ๊ฒ์๋์ด ์ ์ฅ๋์์ต๋๋ค.\n") |
|
|
|
|
|
cached_rows = [] |
|
|
|
def exclude(): |
|
global total_rows, cached_rows |
|
input_file = entry_file_path.get() |
|
keywords = entry_keyword.get() |
|
output_file = 'txt2img_temp_prompt.csv' |
|
keyword_label.config(text="๊ฒ์ํ ํค์๋: ") |
|
|
|
output_directory = os.getcwd() |
|
output_file = os.path.join(output_directory, output_file) |
|
search_strings = [s.strip() for s in keywords.split(',')] |
|
|
|
with open(input_file, 'r', newline='', encoding='utf-8') as f_in, \ |
|
open(output_file, 'w', newline='', encoding='utf-8') as f_out: |
|
reader = csv.reader(f_in) |
|
writer = csv.writer(f_out) |
|
writer_count = 0 |
|
for row in reader: |
|
if not any(search_str in value for search_str in search_strings for value in row): |
|
writer.writerow(row) |
|
writer_count += 1 |
|
total_rows = writer_count |
|
total_rows_count_label.config(text=f".csv ๋ด ํ๋กฌํํธ ํ: {writer_count}", fg="red") |
|
text_output.insert(tk.END, f"์ด {writer_count}๊ฐ์ ๋ฌธ์์ด์ด ๊ฒ์๋์ด ์ ์ฅ๋์์ต๋๋ค.\n") |
|
|
|
|
|
cached_rows = [] |
|
|
|
def copy_image_to_clipboard(): |
|
global temp_clipboard_image |
|
image = temp_clipboard_image |
|
output = BytesIO() |
|
image.convert('RGB').save(output, format='BMP') |
|
data = output.getvalue()[14:] |
|
output.close() |
|
|
|
win32clipboard.OpenClipboard() |
|
win32clipboard.EmptyClipboard() |
|
win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data) |
|
win32clipboard.CloseClipboard() |
|
|
|
def reset(): |
|
cached_rows = None |
|
entry_file_path.delete(0, tk.END) |
|
entry_keyword.delete(0, tk.END) |
|
entry_deep_search.delete(0, tk.END) |
|
text_output.delete('1.0', tk.END) |
|
|
|
def rearrange_keywords_boys_girls(keywords): |
|
boy_keyword = None |
|
girl_keyword = None |
|
|
|
|
|
for keyword in keywords[:10]: |
|
if 'boy' in keyword and len(keyword) <= 5: |
|
boy_keyword = keyword |
|
if 'girl' in keyword and len(keyword) <= 5: |
|
girl_keyword = keyword |
|
|
|
|
|
if boy_keyword and girl_keyword: |
|
boy_index = keywords.index(boy_keyword) |
|
if boy_index != 0: |
|
keywords.insert(0, keywords.pop(boy_index)) |
|
girl_index = keywords.index(girl_keyword) |
|
if girl_index > boy_index: |
|
keywords.insert(boy_index + 1, keywords.pop(girl_index)) |
|
|
|
return keywords |
|
|
|
def random_function(): |
|
global last_deep_search_keywords, cached_rows, last_selected_row_keywords, top_100_keywords, previous_artist, top_100_counts |
|
global current_wildcard_character, current_wildcard_artist |
|
global previous_wildcard_artist, previous_wildcard_character, character_keys, copyright_keys |
|
current_deep_search_keywords = entry_deep_search.get().strip() |
|
auto_hide_keywords = entry_auto_hide.get().split(',') |
|
auto_hide_keywords = [keyword.strip() for keyword in auto_hide_keywords if keyword.strip()] |
|
current_artist = None |
|
|
|
curly_brackets_keywords = re.findall(r'\{([^}]+)\}', current_deep_search_keywords) |
|
|
|
processed_keywords = [] |
|
for group in curly_brackets_keywords: |
|
perfect_match_group = [kw[1:].strip() for kw in group.split('|') if kw.startswith('*')] |
|
regular_group = [kw.strip() for kw in group.split('|') if not kw.startswith('*')] |
|
processed_keywords.append((perfect_match_group, regular_group)) |
|
|
|
modified_deep_search_keywords = re.sub(r'\{[^}]+\}', '', current_deep_search_keywords) |
|
|
|
|
|
remaining_keywords = [kw.strip() for kw in modified_deep_search_keywords.split(',') if kw.strip()] |
|
perfect_match_keywords = [kw[1:].strip() for kw in remaining_keywords if kw.startswith('*')] |
|
|
|
|
|
exclude_keywords = [kw[1:].strip() for kw in remaining_keywords if kw.startswith('~') and not kw[1:].startswith('*')] |
|
include_keywords = [kw for kw in remaining_keywords if not kw.startswith('~') and not kw.startswith('*')] |
|
|
|
if current_deep_search_keywords != last_deep_search_keywords or not cached_rows: |
|
if not os.path.exists('txt2img_temp_prompt.csv'): |
|
text_output.delete('1.0', tk.END) |
|
text_output.insert(tk.END, "txt2img_temp_prompt.csv๊ฐ ์์ด ์ฌ๊ฒ์์ ์ํํฉ๋๋ค. ์ด ์์
์๋ ๋งค์ฐ ๊ธด ์๊ฐ์ด ์์๋ฉ๋๋ค. tags.csv ํ์ผ์ ๋ํด ์ด๊ธฐํ ํค์๋ ๋ฐ .csv ๋ด๋ณด๋ด๊ธฐ ๊ธฐ๋ฅ์ ํ์ฉ ํด ์ฃผ์ธ์.") |
|
try: |
|
with open('txt2img_temp_prompt.csv', 'r', newline='', encoding='utf-8') as f: |
|
reader = csv.reader(f) |
|
rows = [] |
|
for row in reader: |
|
if all(re.search(r'(?:^|, )' + re.escape(kw) + r'(?:,|$)', ', '.join(row)) for kw in perfect_match_keywords) \ |
|
and not any(re.search(r'\b' + re.escape(exclude) + r'\b', cell) for exclude in exclude_keywords for cell in row) \ |
|
and all(include in cell for include in include_keywords for cell in row): |
|
|
|
if all(any(re.search(r'(?:^|, )' + re.escape(kw) + r'(?:,|$)', ', '.join(cell)) for kw in perfect_group) or |
|
any(kw in cell for kw in regular_group) for perfect_group, regular_group in processed_keywords for cell in row): |
|
rows.append(row) |
|
cached_rows = rows |
|
except: |
|
try: |
|
search() |
|
with open('txt2img_temp_prompt.csv', 'r', newline='', encoding='utf-8') as f: |
|
reader = csv.reader(f) |
|
rows = [] |
|
for row in reader: |
|
if all(re.search(r'(?:^|, )' + re.escape(kw) + r'(?:,|$)', ', '.join(row)) for kw in perfect_match_keywords) \ |
|
and not any(re.search(r'\b' + re.escape(exclude) + r'\b', cell) for exclude in exclude_keywords for cell in row) \ |
|
and all(include in cell for include in include_keywords for cell in row): |
|
|
|
if all(any(re.search(r'(?:^|, )' + re.escape(kw) + r'(?:,|$)', ', '.join(cell)) for kw in perfect_group) or |
|
any(kw in cell for kw in regular_group) for perfect_group, regular_group in processed_keywords for cell in row): |
|
rows.append(row) |
|
cached_rows = rows |
|
except: |
|
def open_link(url): |
|
webbrowser.open_new(url) |
|
|
|
text_output.delete('1.0', tk.END) |
|
text_output.insert(tk.END, "tags.csv ํ์ผ์ [ํ์ผ ์ด๊ธฐ] ๋ฒํผ์ ๋๋ฌ ํ์ฌํ๊ฑฐ๋,") |
|
text_output.insert(tk.END, "https://huggingface.co/baqu2213/PoemForSmallFThings/blob/main/Danbooru%20Prompt%20Selector/tags_2023.csv", "link") |
|
text_output.insert(tk.END, " ์์ ๋ค์ด๋ก๋ ํ์๊ธฐ ๋ฐ๋๋๋ค.") |
|
text_output.tag_config("link", foreground="blue", underline=True) |
|
text_output.tag_bind("link", "<Button-1>", lambda e: open_link("https://huggingface.co/baqu2213/PoemForSmallFThings/blob/main/Danbooru%20Prompt%20Selector/tags_2023.csv")) |
|
return |
|
last_deep_search_keywords = current_deep_search_keywords |
|
if not toggle_prompt_var.get(): text_output.delete('1.0', tk.END) |
|
|
|
if random_artist_var.get(): |
|
if(not entry_fixed_prompt.get()): entry_fixed_prompt.insert(tk.END,'1girl') |
|
|
|
if not os.path.exists("counting_result.txt"): |
|
keyword_counts = analyze_cached_rows(cached_rows) |
|
excluded_keywords = set(whitelist[:2974]) |
|
with open("counting_result.txt", "w") as file: |
|
for keyword, count in sorted(keyword_counts.items(), key=lambda item: item[1], reverse=True): |
|
if keyword not in excluded_keywords and keyword in afilter_30000: |
|
file.write(f"{keyword}: {count}\n") |
|
with open("counting_result.txt", "r") as file: |
|
lines = file.readlines() |
|
top_100_data = [ |
|
(line.split(":")[0].strip(), int(line.split(":")[1].strip())) |
|
for line in lines[:3000] |
|
if line.split(":")[0].strip() in afilter_30000[:8528] |
|
] |
|
top_100_keywords, top_100_counts = zip(*top_100_data) if top_100_data else ([], []) |
|
elif (not top_100_keywords): |
|
with open("counting_result.txt", "r") as file: |
|
lines = file.readlines() |
|
top_100_data = [ |
|
(line.split(":")[0].strip(), int(line.split(":")[1].strip())) |
|
for line in lines[:3000] |
|
if line.split(":")[0].strip() in afilter_30000[:8528] |
|
] |
|
top_100_keywords, top_100_counts = zip(*top_100_data) if top_100_data else ([], []) |
|
|
|
formatted_artist_random_keyword = [] |
|
if top_100_keywords: |
|
temp_keyword = [] |
|
temp_keyword += top_100_keywords |
|
whatthefuck = random.random() |
|
if(whatthefuck > 0.9): |
|
for i in range(4): |
|
random_keyword = random.choice(temp_keyword) |
|
temp_keyword.remove(random_keyword) |
|
if(i == 0): formatted_artist_random_keyword = "{{{artist:"+random_keyword+"}}}" |
|
if(i == 1): formatted_artist_random_keyword += ",{artist:"+random_keyword+"}" |
|
if(i == 2): formatted_artist_random_keyword += ",artist:"+random_keyword |
|
if(i == 3): formatted_artist_random_keyword += ",[[artist:"+random_keyword+"]]" |
|
elif(whatthefuck > 0.7): |
|
for i in range(3): |
|
random_keyword = random.choice(temp_keyword) |
|
temp_keyword.remove(random_keyword) |
|
if(i == 0): formatted_artist_random_keyword = "{{{artist:"+random_keyword+"}}}" |
|
if(i == 1): formatted_artist_random_keyword += ",{artist:"+random_keyword+"}" |
|
if(i == 2): formatted_artist_random_keyword += ",[[artist:"+random_keyword+"]]" |
|
elif(whatthefuck > 0.45): |
|
for i in range(2): |
|
random_keyword = random.choice(temp_keyword) |
|
temp_keyword.remove(random_keyword) |
|
if(i == 0): formatted_artist_random_keyword = "{{{artist:"+random_keyword+"}}}" |
|
if(i == 2): formatted_artist_random_keyword += ",[[artist:"+random_keyword+"]]" |
|
else: |
|
random_keyword = random.choice(temp_keyword) |
|
temp_keyword.remove(random_keyword) |
|
formatted_artist_random_keyword = "{{artist:"+random_keyword+"}}" |
|
current_artist = formatted_artist_random_keyword |
|
if not top_100_keywords: random_artist_var.set(0) |
|
else: |
|
formatted_artist_random_keyword = f"์๊ฐ ํค์๋๊ฐ ์์!!" |
|
|
|
if cached_rows: |
|
if toggle_prompt_var.get() and last_selected_row_keywords: |
|
random_row_keywords = [keyword.strip() for keyword in text_output.get("1.0", "end-1c").split(',')] |
|
random_row_keywords = [keyword.strip() for keyword in text_output.get("1.0", "end-1c").split(',')] |
|
|
|
|
|
text_output.delete('1.0', tk.END) |
|
else: |
|
if (safe_search_var.get()): |
|
for i in range(100): |
|
random_index = random.randint(0, len(cached_rows) - 1) |
|
random_row = cached_rows.pop(random_index) |
|
random_row_keywords = [keyword.strip() for keyword in random_row[0].split(',')] |
|
|
|
if not any(keyword in nsfw_word for keyword in random_row_keywords): |
|
break |
|
if len(cached_rows) == 0: |
|
random_row_keywords = [keyword.strip() for keyword in "1girl, blank eyes, cell phone, chibi, crying, crying with eyes open, gloom (expression), holding, holding phone, open mouth, phone, smartphone, solo, surprised, tears, turn pale, white background, simple background, Search fail (text)".split(',')] |
|
break |
|
if i == 99: random_row_keywords = random_row_keywords = [keyword.strip() for keyword in "1girl, blank eyes, cell phone, chibi, crying, crying with eyes open, gloom (expression), holding, holding phone, open mouth, phone, smartphone, solo, surprised, tears, turn pale, white background, simple background, Search fail (text)".split(',')] |
|
last_selected_row_keywords = random_row_keywords.copy() |
|
else: |
|
random_index = random.randint(0, len(cached_rows) - 1) |
|
random_row = cached_rows.pop(random_index) |
|
random_row_keywords = [keyword.strip() for keyword in random_row[0].split(',')] |
|
last_selected_row_keywords = random_row_keywords.copy() |
|
|
|
if(entry_fixed_prompt.get()): |
|
entry_text_keywords = entry_fixed_prompt.get() |
|
if(',' not in entry_text_keywords[-2:]): entry_text_keywords += ',' |
|
entry_text_keywords = entry_text_keywords.split(',') |
|
entry_text_keywords = [kw.strip() for kw in entry_text_keywords if kw.strip()] |
|
|
|
temp_first_keywords = [] |
|
|
|
|
|
|
|
for et_kw in entry_text_keywords: |
|
if ('boy' in et_kw or 'girl' in et_kw) or (et_kw not in random_row_keywords and et_kw not in random_row_keywords): |
|
temp_first_keywords.append(et_kw) |
|
|
|
|
|
boy_keywords = [kw for kw in random_row_keywords if 'boy' in kw and len(kw) <= 7] |
|
|
|
|
|
girl_keywords = [] |
|
if 'girl' in entry_text_keywords[0] and len(entry_text_keywords[0]) <= 7: |
|
girl_keywords = [kw for kw in random_row_keywords if 'girl' in kw and len(kw) <= 7] |
|
|
|
|
|
for kw in boy_keywords + girl_keywords: |
|
if kw in random_row_keywords: |
|
random_row_keywords.remove(kw) |
|
|
|
for kw in temp_first_keywords: |
|
if kw in random_row_keywords: |
|
random_row_keywords.remove(kw) |
|
|
|
|
|
if(girl_keywords and 'girl' in temp_first_keywords[0]): temp_first_keywords.pop(0) |
|
|
|
print(random_row_keywords) |
|
if(wildcard_var2.get() == 1): |
|
temp_len = len(girl_keywords) |
|
print('previous : ',previous_wildcard_character, 'type : ', type(previous_wildcard_character)) |
|
if previous_wildcard_character in random_row_keywords: |
|
random_row_keywords.remove(previous_wildcard_character) |
|
elif(previous_wildcard_character is not None): |
|
split_previous_wildcard_character = previous_wildcard_character.split(',') |
|
split_previous_wildcard_character = [keyword.strip() for keyword in split_previous_wildcard_character] |
|
for _keyword in split_previous_wildcard_character: |
|
if _keyword in random_row_keywords: |
|
random_row_keywords.remove(_keyword) |
|
if _keyword in random_row_keywords: |
|
random_row_keywords.remove(_keyword) |
|
previous_wildcard_character = get_random_keyword('character') |
|
girl_keywords.append(previous_wildcard_character) |
|
if(wildcard_var.get() == 1): |
|
print('previous : ',previous_wildcard_artist, 'type : ', type(previous_wildcard_artist)) |
|
if previous_wildcard_artist is not None and previous_wildcard_artist in random_row_keywords: |
|
random_row_keywords.remove(previous_wildcard_artist) |
|
elif(previous_wildcard_artist is not None): |
|
split_previous_wildcard_artist = previous_wildcard_artist.split(',') |
|
split_previous_wildcard_artist = [keyword.strip() for keyword in split_previous_wildcard_artist] |
|
split_previous_wildcard_artist[0] = split_previous_wildcard_artist[0] |
|
for _keyword in split_previous_wildcard_artist: |
|
if _keyword in random_row_keywords: |
|
random_row_keywords.remove(_keyword) |
|
previous_wildcard_artist = get_random_keyword('artist') |
|
if(wildcard_var2.get() == 1): |
|
girl_keywords.insert(temp_len+1,previous_wildcard_artist) |
|
else: |
|
girl_keywords.append(previous_wildcard_artist) |
|
|
|
|
|
|
|
if temp_first_keywords and 'girl' in temp_first_keywords[0]: |
|
girl_in_gkey = False |
|
for gkey in girl_keywords: |
|
if 'girl' in gkey: |
|
girl_in_gkey = True |
|
if not girl_in_gkey: |
|
temp_gkey = temp_first_keywords.pop(0) |
|
girl_keywords.insert(0, temp_gkey) |
|
|
|
temp_first_keywords = boy_keywords + girl_keywords + temp_first_keywords |
|
|
|
|
|
if remove_artist_var.get(): |
|
for keyword in random_row_keywords: |
|
if keyword in afilter_30000: |
|
random_row_keywords.remove(keyword) |
|
temp_rm = [] |
|
if rm_characteristic_var.get(): |
|
for keyword in random_row_keywords: |
|
if keyword in bag_of_tags or keyword in character_keys or "(" in keyword or "horns" in keyword: |
|
if keyword not in entry_text_keywords: |
|
temp_rm.append(keyword) |
|
for keyword in temp_rm: |
|
random_row_keywords.remove(keyword) |
|
|
|
nsfw_temp = [] |
|
if NSFW_assert_var.get(): |
|
for keyword in random_row_keywords: |
|
if not rm_characteristic_var.get(): |
|
if keyword not in qe_word and (keyword not in bag_of_tags and keyword not in character_keys and "(" not in keyword and "horns" not in keyword): |
|
nsfw_temp.append(keyword) |
|
else: |
|
if keyword not in qe_word: |
|
nsfw_temp.append(keyword) |
|
if nsfw_temp is not None: |
|
if not remove_artist_var.get(): |
|
temp_rm_arti= [] |
|
for keyword in nsfw_temp: |
|
if keyword in afilter_30000: |
|
temp_rm_arti.append(keyword) |
|
for keyword in temp_rm_arti: |
|
nsfw_temp.remove(keyword) |
|
if not rm_copyright_var.get(): |
|
for keyword in nsfw_temp: |
|
if keyword not in copyright_keys: |
|
random_row_keywords.remove(keyword) |
|
else: |
|
for keyword in nsfw_temp: |
|
random_row_keywords.remove(keyword) |
|
for keyword in random_row_keywords[:]: |
|
if " (" in keyword: |
|
temp_first_keywords.append(keyword) |
|
random_row_keywords.remove(keyword) |
|
else: |
|
if not random_row_keywords: random_row_keywords = last_selected_row_keywords |
|
temp_first_keywords = [] |
|
for keyword in random_row_keywords[:]: |
|
if " (" in keyword: |
|
temp_first_keywords.append(keyword) |
|
random_row_keywords.remove(keyword) |
|
|
|
t_temp = [] |
|
for keyword in temp_first_keywords: |
|
t_temp.append(keyword.strip()) |
|
t_temp = list(OrderedDict.fromkeys(t_temp)) |
|
temp_first_keywords = list(t_temp) |
|
|
|
|
|
|
|
if random_artist_var.get(): |
|
temp_first_keywords.append(formatted_artist_random_keyword) |
|
|
|
if (previous_artist and previous_artist in temp_first_keywords): temp_first_keywords.remove(previous_artist) |
|
if (current_artist is (not None)): |
|
for i in range (len(current_artist)): |
|
previous_artist += current_artist[i] |
|
random_row_keywords = temp_first_keywords + random_row_keywords |
|
|
|
|
|
else: random_row_keywords = temp_first_keywords + random_row_keywords |
|
|
|
patterns = auto_hide_keywords |
|
rm_reserved = [] |
|
|
|
for pattern in patterns: |
|
if pattern in random_row_keywords: |
|
rm_reserved.append(pattern) |
|
for pattern in rm_reserved: |
|
random_row_keywords.remove(pattern) |
|
|
|
if entry_fixed_prompt_after.get(): |
|
entry_after_text = [keyword.strip() for keyword in entry_fixed_prompt_after.get().split(',')] |
|
for at_kw in entry_after_text: |
|
if at_kw not in random_row_keywords and at_kw not in random_row_keywords: |
|
random_row_keywords.append(at_kw) |
|
|
|
rm_copyright = [] |
|
if(rm_copyright_var.get()): |
|
for keyword in random_row_keywords: |
|
if keyword in copyright_keys: |
|
rm_copyright.append(keyword) |
|
if rm_copyright is not None: |
|
for keyword in rm_copyright: |
|
random_row_keywords.remove(keyword) |
|
else: |
|
idx = 0 |
|
for keyword in random_row_keywords: |
|
if keyword in copyright_keys: |
|
random_row_keywords[idx] = keyword+" (copyright)" |
|
idx += 1 |
|
pop_character = [] |
|
for keyword in random_row_keywords: |
|
character_temp_keyword = keyword.replace('{', '').replace('}', '').replace('[', '').replace(']', '') |
|
if character_temp_keyword in character_keys: |
|
pop_character.append(keyword) |
|
if pop_character is not None: |
|
found_index = 0 |
|
|
|
for i in range(min(10, len(random_row_keywords))): |
|
if 'girl' in random_row_keywords[i]: |
|
found_index = i |
|
break |
|
elif 'boy' in random_row_keywords[i]: |
|
found_index = i |
|
break |
|
elif 'other' in random_row_keywords[i]: |
|
found_index = i |
|
break |
|
for keyword in pop_character: |
|
found_index += 1 |
|
random_row_keywords.remove(keyword) |
|
random_row_keywords.insert(found_index,keyword) |
|
pop_artist = [] |
|
for keyword in random_row_keywords: |
|
artist_temp_keyword = keyword.replace('{', '').replace('}', '').replace('[', '').replace(']', '') |
|
if artist_temp_keyword in afilter_30000: |
|
pop_artist.append(keyword) |
|
if pop_artist is not None: |
|
for keyword in pop_artist: |
|
found_index += 1 |
|
random_row_keywords.remove(keyword) |
|
random_row_keywords.insert(found_index,"artist:"+keyword) |
|
|
|
random_row_keywords = rearrange_keywords_boys_girls(random_row_keywords) |
|
|
|
text_output.insert(tk.END, f"{', '.join(random_row_keywords)}") |
|
if auto_copy_var.get(): |
|
copy_to_clipboard() |
|
else: |
|
text_output.insert(tk.END, "๊ฒ์ ์กฐ๊ฑด์ ๋ง๋ ๋ฐ์ดํฐ๊ฐ ์๊ฑฐ๋ CSV ํ์ผ์ ๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค.\n") |
|
|
|
cached_rows_count_label.config(text=f"์ฌ์ธต๊ฒ์ ํ๋กฌํํธ ํ: {len(cached_rows)}") |
|
|
|
|
|
|
|
def add_low_frequency_keywords(): |
|
global keyword_counts, most_common_count |
|
keyword_counts = analyze_cached_rows(cached_rows) |
|
if not keyword_counts: |
|
return |
|
|
|
|
|
most_common_count = keyword_counts.most_common(1)[0][1] |
|
|
|
|
|
low_freq_keywords = [keyword for keyword, count in keyword_counts.items() |
|
if keyword not in last_deep_search_keywords and keyword not in whitelist and count / most_common_count <= 0.05] |
|
|
|
|
|
existing_keywords = entry_auto_hide.get().split(',') |
|
existing_keywords = [keyword.strip() for keyword in existing_keywords if keyword.strip()] |
|
|
|
|
|
updated_keywords = existing_keywords + low_freq_keywords |
|
unique_keywords = list(set(updated_keywords)) |
|
for keyword in unique_keywords: |
|
if(keyword in afilter_30000): |
|
unique_keywords.remove(keyword) |
|
entry_auto_hide.delete(0, tk.END) |
|
entry_auto_hide.insert(0, ', '.join(unique_keywords)) |
|
|
|
def copy_to_clipboard(): |
|
window.clipboard_clear() |
|
entry_text = entry_fixed_prompt.get() |
|
if(',' not in entry_text and entry_text): entry_text += ',' |
|
combined_text = text_output.get("1.0", tk.END) |
|
window.clipboard_append(combined_text) |
|
|
|
def turbo_stop(button): |
|
global turbo_stop_bit |
|
button.config(state=tk.DISABLED) |
|
turbo_stop_bit = True |
|
tprint("Stopping pipelines ... ") |
|
window.after(20000, lambda: button_generate.config(state='normal')) |
|
|
|
def exit_program(): |
|
global stop_event, auto_thread |
|
if stop_event is not None: |
|
stop_event.set() |
|
if auto_thread is not None and auto_thread.is_alive(): |
|
auto_thread.join() |
|
window.destroy() |
|
|
|
def save_settings(): |
|
global NAI_ID |
|
with open('app_settings.txt', 'w', encoding='utf-8') as f: |
|
if(len(entry_file_path.get()) > 4): |
|
f.write(entry_file_path.get() + '\n') |
|
else: f.write(" "+'\n') |
|
if(len(entry_keyword.get()) > 3): |
|
f.write(entry_keyword.get() + '\n') |
|
else: f.write(" "+'\n') |
|
if(len(entry_deep_search.get()) > 3): |
|
f.write(entry_deep_search.get() + '\n') |
|
else: f.write(" "+'\n') |
|
if(len(entry_fixed_prompt.get()) > 4): |
|
f.write(entry_fixed_prompt.get() + '\n') |
|
else: f.write(" "+'\n') |
|
if(len(entry_fixed_prompt_after.get()) > 4): |
|
f.write(entry_fixed_prompt_after.get() + '\n') |
|
else: f.write(" "+'\n') |
|
if(len(entry_auto_hide.get()) > 3): |
|
f.write(entry_auto_hide.get() + '\n') |
|
else: f.write(" "+'\n') |
|
if(len(negative_text.get("1.0", tk.END)) > 4): |
|
f.write(negative_text.get("1.0", tk.END)) |
|
else: f.write(" "+'\n') |
|
if(NAI_ID): f.write(NAI_ID + '\n' ) |
|
|
|
def load_settings(): |
|
NAI_ID = "" |
|
if os.path.exists('app_settings.txt'): |
|
with open('app_settings.txt', 'r', encoding='utf-8') as f: |
|
settings = f.readlines() |
|
entry_file_path.insert(0, settings[0].strip()) |
|
entry_keyword.insert(0, settings[1].strip()) |
|
entry_deep_search.insert(0, settings[2].strip()) |
|
entry_fixed_prompt.insert(0, settings[3].strip()) |
|
entry_fixed_prompt_after.insert(0, settings[4].strip()) |
|
entry_auto_hide.insert(0, settings[5].strip()) |
|
if(len(settings)>=7): |
|
negative_text.insert(tk.END, settings[6].strip()) |
|
if(len(settings)>=8): |
|
NAI_ID = settings[7].strip() |
|
return NAI_ID |
|
|
|
def open_prompt_window(): |
|
|
|
prompt_window = tk.Toplevel(window) |
|
prompt_title = f"{entry_keyword.get()}+{last_deep_search_keywords}" if last_deep_search_keywords else "์ถ์ฒ ํ๋กฌํํธ" |
|
prompt_window.title(prompt_title) |
|
|
|
|
|
|
|
text_output1 = tk.Text(prompt_window, height=10, width=50) |
|
text_output1.pack(padx=10, pady=10) |
|
|
|
|
|
text_output1.tag_configure('bold', font=('Arial', 10, 'bold')) |
|
|
|
|
|
text_output2 = tk.Text(prompt_window, height=10, width=50) |
|
text_output2.pack(padx=10, pady=10) |
|
|
|
|
|
text_output3 = tk.Text(prompt_window, height=10, width=50) |
|
text_output3.pack(padx=10, pady=10) |
|
|
|
|
|
keyword_counts = analyze_cached_rows(cached_rows) |
|
|
|
|
|
most_common_count = keyword_counts.most_common(1)[0][1] if keyword_counts else 0 |
|
|
|
|
|
for keyword, count in keyword_counts.most_common(50): |
|
if count / most_common_count >= 0.5: |
|
text_output1.insert(tk.END, f"{keyword}, ", 'bold') |
|
else: |
|
text_output1.insert(tk.END, f"{keyword}, ") |
|
|
|
|
|
for keyword, count in keyword_counts.most_common(200): |
|
text_output2.insert(tk.END, f"{keyword}: {count}, ") |
|
|
|
excluded_keywords = set(whitelist[:2974]) |
|
artist_count = 0 |
|
with open("counting_result.txt", "w") as file: |
|
for keyword, count in sorted(keyword_counts.items(), key=lambda item: item[1], reverse=True): |
|
if keyword not in excluded_keywords and keyword in afilter_30000: |
|
file.write(f"{keyword}: {count}\n") |
|
if(artist_count < 150): |
|
text_output3.insert(tk.END, f"{keyword}: {count}, ") |
|
artist_count += 1 |
|
|
|
|
|
close_button = tk.Button(prompt_window, text="๋ซ๊ธฐ", command=prompt_window.destroy) |
|
close_button.pack(pady=10) |
|
|
|
def analyze_cached_rows(cached_rows): |
|
global top_100_keywords |
|
top_100_keywords = [] |
|
counts = Counter() |
|
for row in cached_rows: |
|
substrings = [substring.strip() for value in row for substring in value.split(',') if substring.strip()] |
|
counts.update(substrings) |
|
return counts |
|
|
|
def exit_program(): |
|
save_settings() |
|
window.destroy() |
|
|
|
def on_ctrl_enter(event): |
|
random_function() |
|
|
|
def on_shift_enter(event): |
|
random_function() |
|
copy_to_clipboard() |
|
|
|
def export_csv(): |
|
source_file = os.path.join(os.getcwd(), 'txt2img_temp_prompt.csv') |
|
if not os.path.exists(source_file): |
|
print("์์ค ํ์ผ์ด ์กด์ฌํ์ง ์์ต๋๋ค.") |
|
return |
|
|
|
|
|
default_filename = f"{entry_keyword.get()}.csv" if entry_keyword.get() else "exported.csv" |
|
file_types = [('CSV ํ์ผ', '*.csv')] |
|
dest_file = filedialog.asksaveasfilename(defaultextension='.csv', filetypes=file_types, initialfile=default_filename) |
|
|
|
if dest_file: |
|
import shutil |
|
shutil.copy(source_file, dest_file) |
|
print(f"ํ์ผ์ด ์ ์ฅ๋์์ต๋๋ค: {dest_file}") |
|
|
|
def export_csv_search(): |
|
|
|
if not cached_rows: |
|
print("๋น์ด์๋ ํ๋กฌํํธํ.") |
|
return |
|
|
|
|
|
default_filename = f"{entry_keyword.get()}.csv" if entry_keyword.get() else "exported.csv" |
|
file_types = [('CSV ํ์ผ', '*.csv')] |
|
dest_file = filedialog.asksaveasfilename(defaultextension='.csv', filetypes=file_types, initialfile=default_filename) |
|
|
|
if dest_file: |
|
with open(dest_file, 'w', newline='', encoding='utf-8') as file: |
|
writer = csv.writer(file) |
|
for row in cached_rows: |
|
writer.writerow(row) |
|
|
|
def for_canonical(f): |
|
return lambda k: f(listener.canonical(k)) |
|
|
|
|
|
def update_label(label, text): |
|
def task(): |
|
label.config(text=text) |
|
label.after(1000, task) |
|
|
|
def NAI_generation(width, height, button): |
|
global access_token_multi, NAI_width, NAI_height |
|
global button_stop, running_flag |
|
|
|
def run_function(): |
|
time.sleep(1) |
|
random_function() |
|
time.sleep(2) |
|
window.event_generate(GENERATE_EVENT, when="tail") |
|
|
|
origin = text_output.get("1.0", tk.END) |
|
pretest =origin.split(', ') |
|
if (turbo_var.get() == 1): |
|
if (('sex' not in pretest and 'group sex' not in pretest) or ('1girl' not in pretest and 'girls' not in origin[:20]) or ('1boy' not in pretest and 'boys' not in origin[:20])): |
|
tprint('๋ถ์คํธ ๊ธฐ๋ฅ์ 1girl, 1boy, sex / boys์ ํธํ๋ฉ๋๋ค.','color=red') |
|
if not mac_var.get(): |
|
button.config(state='normal') |
|
return |
|
else: |
|
thread = threading.Thread(target=run_function) |
|
thread.start() |
|
return |
|
|
|
if(rand_resolution_var.get() == 1): |
|
resolutions = ["1024 x 1024", "960 x 1088", "896 x 1152", "832 x 1216", "1088 x 960", "1152 x 896", "1216 x 832"] |
|
random_resolution = random.choice(resolutions) |
|
selected_resolution.set(random_resolution) |
|
|
|
if(turbo_var.get() == 1 and access_token): |
|
button_stop.config(state='normal') |
|
NAI_generation_turbo(NAI_width, NAI_height, button) |
|
else: |
|
if not (running_flag): |
|
NAI_generation_normal(NAI_width, NAI_height, button) |
|
|
|
def Auto_login_check(): |
|
global access_token, access_token_multi |
|
if os.path.exists('token.txt'): |
|
with open('token.txt', 'r', encoding='utf-8') as f: |
|
tokens = f.readlines() |
|
if(tokens[0]): |
|
access_token = tokens[0].strip() |
|
tprint("1 Account automatically loaded : ",access_token[-5:]) |
|
try: |
|
if(len(tokens)>=2): |
|
access_token_multi = tokens[1].strip() |
|
tprint("2 Account automatically loaded : ",access_token[-5:]+", "+access_token_multi[-5:]) |
|
except: |
|
access_token_multi = None |
|
if(access_token): button_generate.config(state='normal') |
|
|
|
def character_search_thread(): |
|
search_thread = threading.Thread(target=character_search, daemon=True) |
|
search_thread.start() |
|
|
|
def character_search(): |
|
def on_search(): |
|
|
|
selected_indices = listbox.curselection() |
|
if not selected_indices: |
|
print("No selection made.") |
|
return |
|
|
|
|
|
selected_index = selected_indices[0] |
|
|
|
keyword_with_count = listbox.get(selected_index).strip() |
|
keyword = keyword_with_count.split('-')[0].strip() |
|
|
|
|
|
print(f"Analyzing keyword: {keyword}") |
|
character, cosplay = analyze_keywords_in_data('csdataset.parquet', keyword) |
|
character_prompt.delete('1.0', tk.END) |
|
character_prompt.insert(tk.END, f"{', '.join(character)}") |
|
cosplay_prompt.delete('1.0', tk.END) |
|
cosplay_prompt.insert(tk.END, f"{', '.join(cosplay)}") |
|
|
|
def on_key_release(event): |
|
|
|
search_keyword = search_entry.get() |
|
|
|
update_listbox(search_keyword) |
|
|
|
def analyze_keywords_in_data(parquet_file, keyword): |
|
|
|
df = pd.read_parquet(parquet_file) |
|
|
|
bag_of_tags = ['penis', 'character name', 'upper body', 'full body', 'artist name', 'male focus', 'open mouth', 'mature male', 'muscular', 'muscular male', 'closed mouth','closed eyes','1girl', '1boy', '1other', 'white background', 'solo', 'breasts', 'simple background', 'smile', 'looking at viewer', 'flat chest', 'small breasts', 'medium breasts', 'large breasts', 'huge breasts','aqua eyes', 'black eyes', 'blue eyes', 'brown eyes', 'green eyes', 'grey eyes', 'orange eyes', 'purple eyes', 'pink eyes', 'red eyes', 'white eyes', 'yellow eyes', 'amber eyes', 'heterochromia', 'multicolored eyes', 'aqua pupils', 'blue pupils', 'brown pupils', 'green pupils', 'grey pupils', 'orange pupils', 'pink pupils', 'purple pupils', 'red pupils', 'white pupils', 'yellow pupils', 'pointy ears', 'long pointy ears', 'aqua hair', 'black hair', 'blonde hair', 'blue hair', 'light blue hair', 'dark blue hair', 'brown hair', 'light brown hair', 'green hair', 'dark green hair', 'light green hair', 'grey hair', 'orange hair', 'pink hair', 'purple hair', 'light purple hair', 'red hair', 'white hair', 'multicolored hair', 'colored inner hair', 'colored tips', 'roots (hair)', 'gradient hair', 'print hair', 'rainbow hair', 'split-color hair', 'spotted hair', 'streaked hair', 'two-tone hair', 'very short hair', 'short hair', 'medium hair', 'long hair', 'very long hair', 'absurdly long hair', 'big hair', 'bald', 'bald girl', 'bob cut', 'inverted bob', 'bowl cut', 'buzz cut', 'chonmage', 'crew cut', 'flattop', 'okappa', 'pixie cut', 'undercut', 'flipped hair', 'wolf cut', 'cornrows', 'dreadlocks', 'hime cut', 'mullet', 'bow-shaped hair', 'braid', 'braided bangs', 'front braid', 'side braid', 'french braid', 'crown braid', 'single braid', 'multiple braids', 'twin braids', 'low twin braids', 'tri braids', 'quad braids', 'flower-shaped hair', 'hair bun', 'braided bun', 'single hair bun', 'double bun', 'cone hair bun', 'doughnut hair bun', 'heart hair bun', 'triple bun', 'cone hair bun', 'hair rings', 'single hair ring', 'half updo', 'one side up', 'two side up', 'low-braided long hair', 'low-tied long hair', 'mizura', 'multi-tied hair', 'nihongami', 'ponytail', 'folded ponytail', 'front ponytail', 'high ponytail', 'short ponytail', 'side ponytail', 'split ponytail', 'star-shaped hair', 'topknot', 'twintails', 'low twintails', 'short twintails', 'uneven twintails', 'tri tails', 'quad tails', 'quin tails', 'twisted hair', 'afro', 'huge afro', 'beehive hairdo', 'crested hair', 'pompadour', 'quiff', 'shouten pegasus mix mori', 'curly hair', 'drill hair', 'twin drills', 'tri drills', 'hair flaps', 'messy hair', 'pointy hair', 'ringlets', 'spiked hair', 'straight hair', 'wavy hair', 'bangs', 'arched bangs', 'asymmetrical bangs', 'bangs pinned back', 'blunt bangs', 'crossed bangs', 'diagonal bangs', 'dyed bangs', 'fanged bangs', 'hair over eyes', 'hair over one eye', 'long bangs', 'parted bangs', 'curtained hair', 'ribbon bangs', 'short bangs', 'swept bangs', 'hair between eyes', 'hair intakes', 'single hair intake', 'sidelocks', 'asymmetrical sidelocks', 'drill sidelocks', 'low-tied sidelocks', 'sidelocks tied back', 'single sidelock', 'ahoge', 'heart ahoge', 'huge ahoge', 'antenna hair', 'heart antenna hair', 'comb over', 'hair pulled back', 'hair slicked back', 'mohawk', 'oseledets', 'lone nape hair', 'hair bikini', 'hair censor', 'hair in own mouth', 'hair over breasts', 'hair over one breast', 'hair over crotch', 'hair over shoulder', 'hair scarf', 'alternate hairstyle', 'hair down', 'hair up', 'asymmetrical hair', 'sidecut', 'blunt ends', 'dark skin', 'dark-skinned female', 'pale skin', 'sun tatoo', 'black skin', 'blue skin', 'green skin', 'grey skin', 'orange skin', 'pink skin', 'purple skin', 'red skin', 'white skin', 'yellow skin', 'colored skin', 'multiple tails', 'demon tail', 'dragon tail', 'ghost tail', 'pikachu tail', 'snake head tail', 'fiery tail', 'bear tail', 'rabbit tail', 'cat tail', 'cow tail', 'deer tail', 'dog tail', 'ermine tail', 'fox tail', 'horse tail', 'leopard tail', 'lion tail', 'monkey tail', 'mouse tail', 'pig tail', 'sheep tail', 'squirrel tail', 'tiger tail', 'wolf tail', 'crocodilian tail', 'fish tail', 'scorpion tail', 'snake tail', 'tadpole tail'] |
|
mini_bag_of_tags = ['penis', 'character name', 'upper body', 'full body', 'artist name', 'male focus', 'open mouth', 'mature male', 'muscular', 'muscular male', 'closed mouth','closed eyes','1girl', '1boy', '1other', 'white background', 'solo', 'breasts', 'simple background', 'smile', 'looking at viewer'] |
|
|
|
filtered_df = df[df['character'] == keyword] |
|
filtered_df = filtered_df[~filtered_df['character'].str.contains(',', na=False)] |
|
if filtered_df.empty: |
|
filtered_df = df[df['character'].str.contains(keyword, na=False, regex=False)] |
|
filtered_df = filtered_df[~(filtered_df['rating'] == 'e')] |
|
print(len(filtered_df)) |
|
|
|
keyword_count_dict = {} |
|
|
|
|
|
for general in filtered_df['general']: |
|
|
|
tags = [tag.strip() for tag in general.split(',')] |
|
|
|
|
|
for tag in tags: |
|
keyword_count_dict[tag] = keyword_count_dict.get(tag, 0) + 1 |
|
|
|
|
|
exclude_keywords = bag_of_tags |
|
keyword_count_dict1 = keyword_count_dict.copy() |
|
keyword_count_dict1 = {k: v for k, v in keyword_count_dict1.items() if k not in mini_bag_of_tags} |
|
keyword_count_dict = {k: v for k, v in keyword_count_dict.items() if k not in exclude_keywords} |
|
|
|
|
|
highest_count = max(keyword_count_dict.values()) if keyword_count_dict else 0 |
|
highest_count1 = max(keyword_count_dict1.values()) if keyword_count_dict1 else 0 |
|
|
|
if(len(filtered_df)) < 10: |
|
weight = 0.6 |
|
elif(len(filtered_df)) < 30: |
|
weight = 0.5 |
|
elif(len(filtered_df)) < 80: |
|
weight = 0.45 |
|
elif(len(filtered_df)) < 160: |
|
weight = 0.35 |
|
elif(len(filtered_df)) < 280: |
|
weight = 0.3 |
|
else: |
|
weight = 0.2 |
|
|
|
result_list = [] |
|
result_list1 = [] |
|
|
|
for k, v in keyword_count_dict.items(): |
|
if '|' in k: continue |
|
if v >= highest_count * weight: |
|
result_list.append(k) |
|
|
|
for k, v in keyword_count_dict1.items(): |
|
if '|' in k: continue |
|
if v >= highest_count1 * weight: |
|
result_list1.append(k) |
|
|
|
result_list1.insert(0, keyword) |
|
result_list.insert(0, "["+keyword+" (cosplay)]") |
|
return result_list1, result_list |
|
|
|
def update_listbox(search_keyword): |
|
|
|
listbox.delete(0, tk.END) |
|
|
|
|
|
if search_keyword: |
|
|
|
|
|
matching_keywords = sorted( |
|
((k, v) for k, v in cd.character_dictionary.items() if search_keyword.lower() in k.lower()), |
|
key=lambda item: item[1], |
|
reverse=True |
|
) |
|
|
|
|
|
for keyword, count in matching_keywords: |
|
listbox.insert(tk.END, f"{keyword} - {count}") |
|
else: |
|
|
|
all_keywords = sorted(cd.character_dictionary.items(), key=lambda item: item[1], reverse=True) |
|
for keyword, count in all_keywords: |
|
listbox.insert(tk.END, f"{keyword} - {count}") |
|
|
|
|
|
ch_search_window = tk.Toplevel(window) |
|
ch_search_window.title("์บ๋ฆญํฐ ๊ฒ์") |
|
|
|
|
|
left_frame = tk.Frame(ch_search_window) |
|
center_frame = tk.Frame(ch_search_window) |
|
right_frame = tk.Frame(ch_search_window) |
|
|
|
|
|
left_frame.grid(row=0, column=0, sticky="nsew") |
|
center_frame.grid(row=0, column=1, sticky="ns") |
|
right_frame.grid(row=0, column=2, sticky="nsew") |
|
|
|
|
|
search_label = tk.Label(left_frame, text="๊ฒ์ ํ๋ ค๋ ์บ๋ฆญํฐ:") |
|
search_label.grid(row=0, column=0, padx=10, pady=5, sticky="ew") |
|
search_entry = tk.Entry(left_frame, width=35) |
|
search_entry.grid(row=1, column=0, padx=10, pady=5, sticky="ew") |
|
search_entry.bind("<KeyRelease>", on_key_release) |
|
|
|
result_label = tk.Label(left_frame, text="๋งค์นญ ์บ๋ฆญํฐ:") |
|
result_label.grid(row=2, column=0, padx=10, pady=5, sticky="ew") |
|
listbox = tk.Listbox(left_frame) |
|
listbox.grid(row=3, column=0, padx=10, pady=5, sticky="nsew") |
|
|
|
|
|
search_button = tk.Button(center_frame, text="๊ฒ์", command=on_search) |
|
search_button.grid(row=2, column=0, rowspan=4, padx=10, pady=175) |
|
|
|
def character_prompt_auto_insert(): |
|
selected_indices = listbox.curselection() |
|
if not selected_indices: |
|
print("No selection made.") |
|
return |
|
|
|
selected_index = selected_indices[0] |
|
|
|
keyword_with_count = listbox.get(selected_index).strip() |
|
keyword = keyword_with_count.split('-')[0].strip() |
|
prompt = character_prompt.get("1.0", tk.END).replace(keyword+',','') |
|
if(len(prompt) > 8): |
|
text_output.delete('1.0', tk.END) |
|
entry_prompt = entry_fixed_prompt.get().replace('1girl', f'1girl, {keyword}') |
|
result_text = entry_prompt+", "+prompt[:-2]+", "+entry_fixed_prompt_after.get() |
|
text_output.insert(tk.END, result_text) |
|
return (len(prompt) > 8) |
|
|
|
def character_prompt_auto_generate(): |
|
global running_flag |
|
if(character_prompt_auto_insert() and not running_flag): |
|
window.event_generate(GENERATE_EVENT, when="tail") |
|
|
|
def character_cosplay_auto_insert(): |
|
prompt = cosplay_prompt.get("1.0", tk.END) |
|
if(len(prompt) > 8): |
|
text_output.delete('1.0', tk.END) |
|
result_text = entry_fixed_prompt.get()+", "+prompt[:-2]+", "+entry_fixed_prompt_after.get() |
|
text_output.insert(tk.END, result_text) |
|
return (len(prompt) > 8) |
|
|
|
def character_cosplay_auto_generate(): |
|
if(character_cosplay_auto_insert() and not running_flag): |
|
window.event_generate(GENERATE_EVENT, when="tail") |
|
|
|
def wildcard_insertion(): |
|
global bag_of_tags, character_wildcard_saved |
|
text = character_prompt.get("1.0", tk.END).split(',') |
|
text_list = [keyword.strip() for keyword in text] |
|
charactersitics = [] |
|
count = 0 |
|
for texts in text_list: |
|
if count < 4 and texts in bag_of_tags[5:] and 'tail' not in texts and 'pupil' not in texts: |
|
charactersitics.append(texts) |
|
count += 1 |
|
keyword = text_list[0] |
|
character_wildcard_saved.append('100:{{'+keyword+', '+', '.join(charactersitics)+'}}') |
|
character_prompt.insert(tk.END, '\n์ ์ฅ๋ ์์ผ๋์นด๋ : 100:{{'+keyword+', '+', '.join(charactersitics)+'}} ํ์ฌ๋ ๋ฐ๋ก ํ๋ฒ ๋ ํด์ฃผ์
์ผ ํฉ๋๋ค.') |
|
|
|
|
|
character_prompt_frame = tk.Frame(right_frame) |
|
character_prompt_frame.grid(row=0, column=0, padx=10, pady=5, sticky="ew") |
|
prompt_label = tk.Label(character_prompt_frame, text="์บ๋ฆญํฐ ํ๋กฌํํธ:") |
|
prompt_label.grid(row=0, column=0, padx=10, pady=5, sticky="ew") |
|
character_prompt_insert = tk.Button(character_prompt_frame, text="์๋์
๋ ฅ", command=character_prompt_auto_insert) |
|
character_prompt_insert.grid(row=0, column=1, padx=10, pady=5, sticky="ew") |
|
character_prompt_generate = tk.Button(character_prompt_frame, text="์ฆ์์์ฑ", command=character_prompt_auto_generate) |
|
character_prompt_generate.grid(row=0, column=2, padx=10, pady=5, sticky="ew") |
|
character_prompt_wildcard = tk.Button(character_prompt_frame, text="์์ผ๋์นด๋ ์ฝ์
", command=wildcard_insertion) |
|
character_prompt_wildcard.grid(row=0, column=3, padx=10, pady=5, sticky="ew") |
|
character_prompt = tk.Text(right_frame, height=10) |
|
character_prompt.grid(row=1, column=0, padx=10, pady=5, sticky="nsew") |
|
|
|
character_cosplay_frame = tk.Frame(right_frame) |
|
character_cosplay_frame.grid(row=2, column=0, padx=10, pady=5, sticky="ew") |
|
cosplay_label = tk.Label(character_cosplay_frame, text="์บ๋ฆญํฐ (Cosplay):") |
|
cosplay_label.grid(row=0, column=0, padx=10, pady=5, sticky="ew") |
|
character_cosplay_insert = tk.Button(character_cosplay_frame, text="์๋์
๋ ฅ", command=character_cosplay_auto_insert) |
|
character_cosplay_insert.grid(row=0, column=1, padx=10, pady=5, sticky="ew") |
|
character_prompt_generate = tk.Button(character_cosplay_frame, text="์ฆ์์์ฑ", command=character_cosplay_auto_generate) |
|
character_prompt_generate.grid(row=0, column=2, padx=10, pady=5, sticky="ew") |
|
cosplay_prompt = tk.Text(right_frame, height=10) |
|
cosplay_prompt.grid(row=3, column=0, padx=10, pady=5, sticky="ew") |
|
|
|
|
|
left_frame.grid_rowconfigure(0, weight=1) |
|
left_frame.grid_rowconfigure(1, weight=1) |
|
left_frame.grid_rowconfigure(2, weight=1) |
|
left_frame.grid_rowconfigure(3, weight=7) |
|
|
|
right_frame.grid_rowconfigure(0, weight=1) |
|
right_frame.grid_rowconfigure(1, weight=4) |
|
right_frame.grid_rowconfigure(2, weight=1) |
|
right_frame.grid_rowconfigure(3, weight=4) |
|
|
|
|
|
ch_search_window.grid_columnconfigure(0, weight=3, minsize=250) |
|
ch_search_window.grid_columnconfigure(1, weight=1) |
|
ch_search_window.grid_columnconfigure(2, weight=6) |
|
|
|
all_keywords = sorted(cd.character_dictionary.items(), key=lambda item: item[1], reverse=True) |
|
for keyword, count in all_keywords: |
|
listbox.insert(tk.END, f"{keyword} - {count}") |
|
|
|
def NAI_generation_normal(width, height, button): |
|
button.config(state=tk.DISABLED) |
|
positive = text_output.get("1.0", tk.END) |
|
negative = negative_text.get("1.0", "end-1c").strip() |
|
global auto_count_left_flag, auto_count_left |
|
if(auto_count_left_flag and auto_count_left > 0): |
|
auto_count_left -= 1 |
|
thread = threading.Thread(target=generate, args=(width, height, positive, negative, button)) |
|
thread.start() |
|
|
|
def NAI_generation_turbo(width, height, button): |
|
global turbo_count, access_token, access_token_multi |
|
button.config(state=tk.DISABLED) |
|
positive = text_output.get("1.0", tk.END) |
|
negative = negative_text.get("1.0", "end-1c").strip() |
|
|
|
def SELECT(positive): |
|
lines = positive |
|
result = { |
|
"boys": False, |
|
"girls": False, |
|
"1girl": False, |
|
"1boy": False, |
|
"1other": False, |
|
"others": False |
|
} |
|
state = { |
|
"nude,": False, |
|
"pov,": False, |
|
"cum,": False, |
|
"after ": False, |
|
"pussy juice": False, |
|
"barefoot": False, |
|
"breasts": False, |
|
"ejaculation": False, |
|
} |
|
|
|
def insert_spaces(source_list, reference_list): |
|
modified_list = source_list.copy() |
|
for index, keyword in enumerate(reference_list): |
|
if keyword not in source_list: |
|
space_count = len(keyword) |
|
modified_list.insert(index, ' ' * space_count) |
|
return modified_list |
|
|
|
keywords = positive.split(', ') |
|
filtered_keywords = [] |
|
removed_indices = [] |
|
positive0, positive1, positive2, positive3 = None, None, None, None |
|
|
|
for word in result.keys(): |
|
if word in lines: |
|
result[word] = True |
|
for word in state.keys(): |
|
if word in positive: |
|
state[word] = True |
|
|
|
key_index = int((len(keywords)/2)-1) |
|
|
|
global bag_of_tags |
|
eye_color = ['aqua eyes', 'black eyes', 'blue eyes', 'brown eyes', 'green eyes', 'grey eyes', 'orange eyes', 'purple eyes', 'pink eyes', 'red eyes', 'white eyes', 'yellow eyes', 'amber eyes'] |
|
hair_color = ['aqua hair', 'black hair', 'blonde hair', 'blue hair', 'light blue hair', 'dark blue hair', 'brown hair', 'light brown hair', 'green hair', 'dark green hair', 'light green hair', 'grey hair', 'orange hair', 'pink hair', 'purple hair', 'light purple hair', 'red hair', 'white hair'] |
|
|
|
if not wildcard_var2.get() and not rm_characteristic_var.get(): |
|
key_features = [] |
|
for tag in bag_of_tags: |
|
if tag in keywords: |
|
key_features.append(tag) |
|
keywords.remove(tag) |
|
if not any(color in key_features for color in eye_color): key_features.append(random.choice(eye_color)) |
|
if not any(color in key_features for color in hair_color): key_features.append(random.choice(hair_color)) |
|
key_feature = "{" +' ,'.join(key_features) + "}" |
|
keywords.insert(2, key_feature) |
|
|
|
if(result["1boy"]) or (result["boys"]): |
|
if(result["1girl"]): |
|
if('sex,' in positive): |
|
sex_pos_keywords = ['stomach bulge','insertion', 'fucked silly', 'x-ray', 'orgasm', 'cross-section', 'uterus', 'overflow', 'rape', 'vaginal', 'anal'] |
|
facial_keywords = ['tongue','ahegao'] |
|
temp_sex_pos = [] |
|
temp_facial = [] |
|
cum_events = [] |
|
explicit_check = [] |
|
if 'open mouth' in keywords: keywords.remove('open mouth') |
|
if 'closed mouth' in keywords: keywords.remove('closed mouth') |
|
if 'after rape' in keywords: |
|
keywords.remove('after rape') |
|
explicit_check.append('after rape') |
|
for keyword in keywords: |
|
if ('sex' not in keyword and 'cum' not in keyword and 'ejaculation' not in keyword and 'vaginal' not in keyword and 'penetration' not in keyword) and all(sex_pos not in keyword for sex_pos in sex_pos_keywords) and all(facial not in keyword for facial in facial_keywords): |
|
filtered_keywords.append(keyword) |
|
elif 'sex' in keyword: |
|
removed_indices.append(keyword) |
|
elif 'penetration' in keyword: |
|
removed_indices.append(keyword) |
|
elif 'cum' in keyword and keyword != 'cum': |
|
cum_events.append(keyword) |
|
elif any(sex_pos in keyword for sex_pos in sex_pos_keywords): |
|
for sex_pos in sex_pos_keywords: |
|
if sex_pos in keyword: |
|
temp_sex_pos.append(sex_pos) |
|
elif any(facial not in keyword for facial in facial_keywords): |
|
for facial in facial_keywords: |
|
if facial in keyword: |
|
temp_facial.append(facial) |
|
filtered_keywords.insert(int((len(filtered_keywords)/2)-1), ' no penetration, imminent penetration') |
|
filtered_keywords_positive0 = filtered_keywords.copy() |
|
filtered_keywords.remove(' no penetration, imminent penetration') |
|
|
|
for i, keyword in enumerate(filtered_keywords): |
|
if 'pantyhose' in keyword: |
|
filtered_keywords[i] = 'torn ' + filtered_keywords[i] |
|
|
|
key_index = int((len(filtered_keywords)/2)-1) |
|
if 'pussy' in filtered_keywords: key_index = filtered_keywords.index('pussy') |
|
if 'penis' in filtered_keywords: key_index = filtered_keywords.index('penis') |
|
filtered_keywords[key_index:key_index] = ['motion lines', 'surprised'] |
|
for keyword in removed_indices: |
|
if 'cum' not in keyword and 'ejaculation' not in keyword: |
|
filtered_keywords.insert(key_index,keyword) |
|
if(temp_sex_pos): filtered_keywords[key_index:key_index] = temp_sex_pos |
|
if('clothed sex' in filtered_keywords and not 'bottomless' in filtered_keywords): filtered_keywords.insert(filtered_keywords.index('clothed sex')+1, 'bottomless') |
|
pos1_copied_keywords = filtered_keywords.copy() |
|
for i, keyword in enumerate(pos1_copied_keywords): |
|
if 'closed eyes' in keyword: |
|
rand_num = random.randint(0,2) |
|
if(rand_num == 0): pos1_copied_keywords[i] = 'half-' + pos1_copied_keywords[i] |
|
elif(rand_num == 1 and 'closed eyes' in pos1_copied_keywords): |
|
pos1_copied_keywords.remove('closed eyes') |
|
filtered_keywords[i] = 'half-closed eyes' |
|
filtered_keywords_positive1 = pos1_copied_keywords.copy() |
|
|
|
key_index = filtered_keywords.index('surprised') |
|
filtered_keywords.remove('surprised') |
|
filtered_keywords[key_index:key_index] = ["ejaculation","cum"] |
|
for keyword in removed_indices: |
|
if 'cum' in keyword: |
|
filtered_keywords.insert(key_index,keyword) |
|
if(temp_facial): filtered_keywords[key_index:key_index] =temp_facial |
|
filtered_keywords_positive2 = filtered_keywords.copy() |
|
|
|
for i, keyword in enumerate(filtered_keywords): |
|
if 'closed eyes' in keyword: |
|
rand_num = random.randint(0,2) |
|
if(rand_num == 0 and filtered_keywords[i] != 'half-closed eyes'): filtered_keywords[i] = 'half-' + filtered_keywords[i] |
|
elif(rand_num == 1): filtered_keywords[i] = 'empty eyes' |
|
else: filtered_keywords[i] = 'empty eyes, half-closed eyes' |
|
if 'sex' in filtered_keywords: |
|
key_index = filtered_keywords.index('sex') |
|
elif 'group sex' in filtered_keywords: |
|
key_index = filtered_keywords.index('group sex') |
|
filtered_keywords.remove('ejaculation') |
|
filtered_keywords[key_index:key_index] = ['cum drip', 'erection'] + cum_events |
|
if(explicit_check): filtered_keywords[key_index:key_index] = explicit_check |
|
if 'sex' in filtered_keywords and 'group sex' not in filtered_keywords: |
|
if('pussy' in filtered_keywords and not 'anal' in filtered_keywords): filtered_keywords.insert(filtered_keywords.index('sex')+1, 'after vaginal, spread pussy') |
|
elif('anal' in filtered_keywords): filtered_keywords.insert(filtered_keywords.index('sex')+1, 'after anus, cum in ass') |
|
filtered_keywords.insert(filtered_keywords.index('sex'), 'after sex') |
|
filtered_keywords.remove('sex') |
|
elif 'group sex' in filtered_keywords: |
|
if('vaginal' in filtered_keywords and not 'anal' in filtered_keywords): |
|
filtered_keywords.insert(filtered_keywords.index('group sex')+1, 'after vaginal, spread pussy') |
|
if 'multiple penises' in filtered_keywords: filtered_keywords.insert(filtered_keywords.index('group sex')+3, 'cum on body, bukkake') |
|
elif('anal' in filtered_keywords): |
|
filtered_keywords.insert(filtered_keywords.index('group sex')+1, 'after anus, cum in ass') |
|
if 'multiple penises' in filtered_keywords: filtered_keywords.insert(filtered_keywords.index('group sex')+3, 'cum on body, bukkake') |
|
else: filtered_keywords.insert(filtered_keywords.index('group sex')+1, 'cum on body, {bukkake}') |
|
temp_post_keyword = [] |
|
for keyword in sex_pos_keywords: |
|
if not (keyword == 'orgasm' or keyword == 'overflow'): |
|
if keyword in filtered_keywords: |
|
temp_post_keyword.append(keyword) |
|
for keyword in temp_post_keyword: |
|
filtered_keywords.remove(keyword) |
|
|
|
positive0 = ', '.join(insert_spaces(filtered_keywords_positive0, filtered_keywords)).strip() |
|
print("round 1 : ",positive0) |
|
positive1 = ', '.join(insert_spaces(filtered_keywords_positive1, filtered_keywords)).strip() |
|
print("round 2 : ",positive1) |
|
positive2 = ', '.join(insert_spaces(filtered_keywords_positive2, filtered_keywords)).strip() |
|
print("round 3 : ",positive2) |
|
positive3 = ', '.join(filtered_keywords).strip() |
|
print("round 4 : ",positive3) |
|
elif(', penis' in positive): |
|
if(', oral' in positive): |
|
pass |
|
elif(', paizuri' in positive): |
|
pass |
|
elif('job,' in positive): |
|
if('handjob' in positive): |
|
pass |
|
elif('footjob' in positive): |
|
pass |
|
|
|
return positive0, positive1, positive2, positive3 |
|
|
|
positive0, positive1, positive2, positive3 = SELECT(text_output.get("1.0", tk.END)); |
|
|
|
if not hold_seed_var.get(): seed = random.randint(0,9999999999) |
|
else: seed = last_generation_seed |
|
|
|
sleep0 = random.uniform(13.5,19.5) |
|
sleep1 = sleep0 + random.uniform(13.5,19.5) |
|
sleep2 = sleep1 + random.uniform(13.5,19.5) |
|
sleep3 = sleep2 + random.uniform(13.5,19.5) |
|
|
|
global auto_count_left_flag, auto_count_left, turbo_stop_bit |
|
if(auto_count_left_flag and auto_count_left > 0): |
|
auto_count_left -= 5 |
|
thread_init = threading.Thread(target=generate_turbo, args=(seed,turbo_count, access_token, width, height, positive, negative, button, 0, 0)) |
|
thread_init.start() |
|
thread0 = threading.Thread(target=generate_turbo, args=(seed,turbo_count, access_token, width, height, positive0, negative, button, 1, sleep0)) |
|
thread0.start() |
|
thread1 = threading.Thread(target=generate_turbo, args=(seed,turbo_count, access_token, width, height, positive1, negative, button, 2, sleep1)) |
|
thread1.start() |
|
thread2 = threading.Thread(target=generate_turbo, args=(seed,turbo_count, access_token, width, height, positive2, negative, button, 3, sleep2)) |
|
thread2.start() |
|
thread3 = threading.Thread(target=generate_turbo, args=(seed,turbo_count, access_token, width, height, positive3, negative, button, 4, sleep3)) |
|
thread3.start() |
|
|
|
turbo_count += 1 |
|
|
|
def generate_turbo(_seed, turbo_count, tb_access_token,width, height, positive, negative, button, pipe_number, sleeptime): |
|
global temp_clipboard_image |
|
global current_sampler |
|
global NAI_width, NAI_height |
|
global running_flag |
|
global image_queue |
|
global turbo_stop_bit |
|
global task_finished |
|
|
|
if(pipe_number == 0): image_queue.clear() |
|
|
|
try: |
|
scale = float(entry_CFG_value.get()) |
|
except: |
|
scale = 5.0 |
|
if scale > 7.0: scale = 7.0 |
|
elif scale < 4.0: scale = 4.0 |
|
else: scale = round(scale, 1) |
|
|
|
try: |
|
scale2 = float(entry_rescale_value.get()) |
|
except: |
|
scale2 = 0 |
|
if scale2 > 1.00: scale = 1.00 |
|
elif scale2 < 0.0: scale = 0.00 |
|
else: scale2 = round(scale2, 2) |
|
|
|
params = { |
|
"legacy": False, |
|
"quality_toggle": False, |
|
"width": width, |
|
"height": height, |
|
"n_samples": 1, |
|
"seed": _seed, |
|
"extra_noise_seed": random.randint(0,9999999999), |
|
"sampler": current_sampler, |
|
"steps": 28, |
|
"scale": scale, |
|
"uncond_scale": 1.0, |
|
"negative_prompt": negative, |
|
"sm" : sema_button_var.get(), |
|
"sm_dyn" : dyn_button_var.get(), |
|
"decrisper": False, |
|
"controlnet_strength": 1.0, |
|
"add_original_image": False, |
|
"cfg_rescale": scale2, |
|
"noise_schedule": "native", |
|
} |
|
|
|
if (hold_seed_var.get()): |
|
global last_generation_seed |
|
params['seed'] = last_generation_seed |
|
|
|
def merge_images(image_queue): |
|
if len(image_queue) < 4: |
|
return None |
|
|
|
|
|
|
|
width, height = image_queue[0].size |
|
new_image = Image.new('RGB', (width * 2, height * 2)) |
|
|
|
|
|
positions = [(0, 0), (width, 0), (0, height), (width, height)] |
|
|
|
|
|
for i, img in enumerate(image_queue): |
|
pos = positions[i] |
|
new_image.paste(img, pos) |
|
|
|
return new_image |
|
|
|
def insert_queue(i, _number, turbo_count): |
|
global image_queue, temp_clipboard_image |
|
while len(image_queue) < 4: image_queue.append(None) |
|
if _number <= 4: |
|
image_queue[_number-1] = i.copy() |
|
i_resized = resize_and_fill(i) |
|
box_position = (i_resized.width - 25, 10) |
|
draw = ImageDraw.Draw(i_resized) |
|
draw.rectangle([box_position, (box_position[0] + 25, box_position[1] + 25)], fill="black") |
|
font = ImageFont.load_default() |
|
text_position = (box_position[0] + 12, box_position[1] + 12) |
|
draw.text(text_position, str(_number), fill="white", font=font) |
|
if 'tk_image' in globals(): |
|
globals()['tk_image'] = None |
|
tk_image = ImageTk.PhotoImage(i_resized) |
|
image_label.config(image=tk_image) |
|
image_label.original_image = i.copy() |
|
image_label.image = tk_image |
|
history_queue(i_resized.copy(), positive, params['seed']) |
|
if all(img is not None for img in image_queue): |
|
time.sleep(5) |
|
merged_image = merge_images(image_queue) |
|
temp_clipboard_image = merged_image.copy() |
|
if merged_image is not None: |
|
output_directory = Path(f"output_NAI/{start_time}/turbo/grid") |
|
output_directory.mkdir(parents=True, exist_ok=True) |
|
file_path = output_directory / f"{turbo_count:05}.png" |
|
merged_image.save(file_path) |
|
i_resized = resize_and_fill(merged_image) |
|
if 'tk_image' in globals(): |
|
globals()['tk_image'] = None |
|
tk_image = ImageTk.PhotoImage(i_resized) |
|
image_label.config(image=tk_image) |
|
image_label.original_image = i_resized.copy() |
|
image_label.image = tk_image |
|
output_file_path = "output_image.jpg" |
|
merged_image.save(output_file_path) |
|
image_queue = [] |
|
|
|
def resize_and_fill(image, max_size=None): |
|
if max_size is None: |
|
max_size = get_max_size() |
|
original_width, original_height = image.size |
|
if original_width > max_size or original_height > max_size: |
|
|
|
image.thumbnail((max_size, max_size)) |
|
|
|
|
|
width, height = image.size |
|
new_image = Image.new("RGB", (max_size, max_size), "black") |
|
new_image.paste(image, ((max_size - width) // 2, (max_size - height) // 2)) |
|
return new_image |
|
else: |
|
return image |
|
|
|
def log_error(e, output_file_path="output_file_path"): |
|
|
|
current_time = datetime.now().strftime("%m/%d %H:%M:%S") |
|
|
|
|
|
error_message = f"#### Error occured at {current_time} ####\nError: {e}\n############################################\n" |
|
|
|
|
|
with open(f"error_log.txt", "a") as file: |
|
file.write(error_message) |
|
|
|
if(pipe_number != 0): |
|
pipe_start_time = time.time() |
|
while time.time() - pipe_start_time < sleeptime: |
|
if(turbo_stop_bit): |
|
return |
|
time.sleep(1) |
|
|
|
while running_flag: |
|
time.sleep(1) |
|
print('running_flag : ',running_flag,'pipe_number : ',pipe_number, ' : already running ') |
|
if(turbo_stop_bit): |
|
return |
|
print('containing : ',pipe_number) |
|
|
|
running_flag = True |
|
tprint("Running : request received, pipeline : "+str(pipe_number)) |
|
global error_count |
|
try: |
|
zipped_bytes = generate_image(tb_access_token, positive, "nai-diffusion-3", "generate", params) |
|
if(pipe_number != 0): |
|
d = Path(f"output_NAI/{start_time}/turbo") |
|
d.mkdir(parents=True, exist_ok=True) |
|
else: |
|
d = Path(f"output_NAI/{start_time}/turbo/preprocessing") |
|
d.mkdir(parents=True, exist_ok=True) |
|
zipped = zipfile.ZipFile(io.BytesIO(zipped_bytes)) |
|
image_bytes = zipped.read(zipped.infolist()[0]) |
|
(d / f"{turbo_count:05}_{pipe_number}.png" ).write_bytes(image_bytes) |
|
i = Image.open(io.BytesIO(image_bytes)) |
|
i = ImageOps.exif_transpose(i).convert("RGB") |
|
error_count = 0 |
|
if(pipe_number != 0): |
|
if temp_clipboard_image is not None: |
|
temp_clipboard_image.close() |
|
if(pipe_number == 1 and len(image_queue) < 4): image_queue.clear() |
|
temp_clipboard_image = i |
|
insert_queue(i, pipe_number, turbo_count) |
|
tprint("image inserted, pipe number : "+str(pipe_number)) |
|
else: |
|
if temp_clipboard_image is not None: |
|
temp_clipboard_image.close() |
|
temp_clipboard_image = i |
|
i_resized = resize_and_fill(i) |
|
if 'tk_image' in globals(): |
|
globals()['tk_image'] = None |
|
tk_image = ImageTk.PhotoImage(i_resized) |
|
image_label.config(image=tk_image) |
|
image_label.original_image = i.copy() |
|
image_label.image = tk_image |
|
except Exception as e: |
|
|
|
log_error(zipped_bytes.decode('utf-8')[2:-2], "path_to_output_folder") |
|
error_count += 1 |
|
if error_count > 5: |
|
mac_var.set(0) |
|
time.sleep(random.uniform(3.0, 9.0)) |
|
insert_queue(temp_clipboard_image, pipe_number, turbo_count) |
|
|
|
task_finished += 1 |
|
|
|
time.sleep(random.uniform(3.0, 5.5)) |
|
if(pipe_number == 4): button.config(state=tk.NORMAL) |
|
running_flag = False |
|
|
|
last_generation_seed = params['seed'] |
|
entry_seed_value.set(last_generation_seed) |
|
|
|
global delay_offset |
|
time.sleep(delay_offset) |
|
|
|
stopped = False |
|
if (turbo_stop_bit): |
|
time.sleep(1.5) |
|
turbo_stop_bit = False |
|
button.config(state=tk.NORMAL) |
|
stopped = True |
|
if (pipe_number != 4): |
|
tprint("Stopped : request stopped before assign pipeline :"+str(pipe_number+1)) |
|
|
|
if pipe_number == 4 and mac_var.get(): |
|
wait_limit = 0 |
|
while(task_finished < 5 and wait_limit < 20): |
|
wait_limit += 1 |
|
print(f"Wait other pipeline ... : ({wait_limit}/20)") |
|
time.sleep(3) |
|
if(wait_limit == 20): |
|
print(f"Process : {turbo_count} request time-out") |
|
task_finished = 0 |
|
else: |
|
task_finished = 0 |
|
running_flag = False |
|
random_function() |
|
time.sleep(random.uniform(2.1, 5.5)) |
|
if not (turbo_stop_bit): |
|
button.config(state=tk.DISABLED) |
|
window.event_generate(GENERATE_EVENT, when="tail") |
|
else: |
|
turbo_stop_bit = False |
|
if(mac_var.get() and not running_flag): |
|
button.config(state=tk.DISABLED) |
|
window.event_generate(GENERATE_EVENT, when="tail") |
|
else: |
|
if(pipe_number == 4): |
|
global button_stop |
|
button_stop.config(state='disabled') |
|
tprint('state : idle') |
|
|
|
def NAI_setting(button, button_generate): |
|
global NAI_ID |
|
NAI_setting_window = tk.Toplevel(window) |
|
NAI_setting_window_title = "NAI ๋ก๊ทธ์ธ" |
|
|
|
def NAI_close(): |
|
NAI_setting_window.destroy() |
|
|
|
def NAI_token_save(button): |
|
global access_token |
|
with open('token.txt', 'w', encoding='utf-8') as f: |
|
f.write(access_token) |
|
NAI_State_label.config(text="(ํ๋ก๊ทธ๋จ ๊ฒฝ๋ก์ token.txt๊ฐ ์ ์ฅ๋์์ต๋๋ค.)", fg="blue") |
|
button.config(state=tk.DISABLED) |
|
|
|
def NAI_connect(button, connect_button, token_button): |
|
global access_token, NAI_ID |
|
username = entry_NAI_ID.get().strip() |
|
password = entry_NAI_PW.get().strip() |
|
access_key = get_access_key(username, password) |
|
try: |
|
access_token = login(access_key) |
|
access_result = requests.get("https://api.novelai.net/user/information", headers={ "Authorization": f"Bearer {access_token}" }) |
|
NAI_State_label.config(text="(๋ก๊ทธ์ธ ์ฑ๊ณต, ๋ซ๊ธฐ ๋ฒํผ์ ๋๋ฌ์ฃผ์ธ์.)", fg="blue") |
|
button.config(state=tk.DISABLED) |
|
button_generate.config(state="normal") |
|
connect_button.config(state=tk.DISABLED) |
|
NAI_ID = username |
|
token_button.config(state=tk.NORMAL) |
|
except Exception as e: |
|
print(e) |
|
NAI_close() |
|
|
|
button_frame0 = tk.Frame(NAI_setting_window) |
|
button_frame0.grid(row=0, padx=5, pady=5, sticky='ew') |
|
button_frame1 = tk.Frame(button_frame0) |
|
button_frame1.grid(row=0, padx=5, pady=5, sticky='ew') |
|
button_frame1.columnconfigure(0, weight=1) |
|
button_frame1.columnconfigure(1, weight=3) |
|
button_frame1.columnconfigure(2, weight=3) |
|
button_frame1.columnconfigure(3, weight=1) |
|
NAI_ID_label = tk.Label(button_frame1, text="NAI ID: ") |
|
NAI_ID_label.grid(row=0, column=0, sticky='ew') |
|
entry_NAI_ID = tk.Entry(button_frame1) |
|
entry_NAI_ID.grid(row=0, column=1, columnspan=3, padx=5, pady=5, sticky='ew') |
|
if(NAI_ID): entry_NAI_ID.insert(tk.END,NAI_ID) |
|
NAI_PW_label = tk.Label(button_frame1, text="NAI PW: ") |
|
NAI_PW_label.grid(row=1, column=0,sticky='ew') |
|
entry_NAI_PW = tk.Entry(button_frame1, show="*") |
|
entry_NAI_PW.grid(row=1, column=1, columnspan=3,padx=5, pady=5, sticky='ew') |
|
token_output = tk.Button(button_frame0, text="๋ก๊ทธ์ธ ์ ๋ณด ๊ธฐ์ตํ๊ธฐ", command=lambda: NAI_token_save(token_output)) |
|
token_output.grid(row=2, column=1, padx=5, pady=5, sticky='ew') |
|
connect_button = tk.Button(button_frame0, text="์ฐ๊ฒฐ", command=lambda: NAI_connect(button, connect_button, token_output)) |
|
connect_button.grid(row=2, column=0, padx=5, pady=5, sticky='ew') |
|
close_button = tk.Button(button_frame0, text="๋ซ๊ธฐ", command=NAI_close) |
|
close_button.grid(row=2, column=2, padx=5, pady=5, sticky='ew') |
|
NAI_State_label = tk.Label(button_frame0, text="ํด๋น ์ ์๊ธฐ๋ฅ์ ์ ์์ ์ธ ์ ์ ํจํด์ด ์๋์ ์ฐธ๊ณ ๋ถํ๋๋ฆฝ๋๋ค.", fg="red") |
|
NAI_State_label.grid(row=3, column=0, sticky='ew') |
|
|
|
def NAI_setting_multi(button): |
|
global NAI_ID_multi |
|
NAI_setting_window_multi = tk.Toplevel(window) |
|
NAI_setting_window_title = "NAI ๋ก๊ทธ์ธ" |
|
|
|
def NAI_close(): |
|
NAI_setting_window_multi.destroy() |
|
|
|
NAI_ID_label = tk.Label(NAI_setting_window_multi, text="NAI ID: ") |
|
NAI_ID_label.grid(row=0, column=0, columnspan=2, sticky='w') |
|
entry_NAI_ID = tk.Entry(NAI_setting_window_multi, width=50) |
|
entry_NAI_ID.grid(row=0, column=1, columnspan=2, padx=100, pady=5, sticky='e') |
|
if(NAI_ID_multi): entry_NAI_ID.insert(tk.END,NAI_ID_multi) |
|
NAI_PW_label = tk.Label(NAI_setting_window_multi, text="NAI PW: ") |
|
NAI_PW_label.grid(row=1, column=0, columnspan=2, sticky='w') |
|
entry_NAI_PW = tk.Entry(NAI_setting_window_multi, width=50, show="*") |
|
entry_NAI_PW.grid(row=1, column=1, columnspan=2, padx=100, pady=5, sticky='e') |
|
|
|
def NAI_connect(button, connect_button): |
|
global access_token_multi, NAI_ID, NAI_ID_multi |
|
username = entry_NAI_ID.get().strip() |
|
password = entry_NAI_PW.get().strip() |
|
access_key = get_access_key(username, password) |
|
try: |
|
access_token_multi = login(access_key) |
|
access_result = requests.get("https://api.novelai.net/user/information", headers={ "Authorization": f"Bearer {access_token}" }) |
|
|
|
if NAI_ID == NAI_ID_multi: NAI_State_label.config(text="(๊ฐ์ ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธ ํ์
จ์ต๋๋ค.)", fg="red") |
|
else: NAI_State_label.config(text="(๋ก๊ทธ์ธ ์ฑ๊ณต, ๋ซ๊ธฐ ๋ฒํผ์ ๋๋ฌ์ฃผ์ธ์.)", fg="blue") |
|
button.config(state=tk.DISABLED) |
|
connect_button.config(state=tk.DISABLED) |
|
NAI_ID_multi = username |
|
except Exception as e: |
|
print(e) |
|
NAI_close() |
|
|
|
connect_button = tk.Button(NAI_setting_window_multi, text="์ฐ๊ฒฐ", command=lambda: NAI_connect(button, connect_button)) |
|
connect_button.grid(row=2, column=1, columnspan=2, padx=5, pady=5, sticky='w') |
|
close_button = tk.Button(NAI_setting_window_multi, text="๋ซ๊ธฐ", command=NAI_close) |
|
close_button.grid(row=2, column=2, columnspan=2, padx=5, pady=5, sticky='w') |
|
NAI_State_label = tk.Label(NAI_setting_window_multi, text="ํด๋น ๊ธฐ๋ฅ์ NAI Opus ๊ตฌ๋
๊ณ์ 2๊ฐ๊ฐ ์๊ตฌ๋ฉ๋๋ค..", fg="red") |
|
NAI_State_label.grid(row=3, column=1, sticky='ew') |
|
|
|
def on_resolution_change(*args): |
|
global NAI_width, NAI_height |
|
resolution = selected_resolution.get() |
|
NAI_width, NAI_height = resolution.split(' x ') |
|
|
|
def on_option_select(value): |
|
global current_sampler |
|
current_sampler = value |
|
|
|
def open_file_explorer(): |
|
output_file_path = "output_NAI" |
|
if os.path.exists(output_file_path): |
|
os.startfile(output_file_path) |
|
|
|
def on_generate_event(event): |
|
global running_flag |
|
if not (running_flag): |
|
NAI_generation(NAI_width, NAI_height, button_generate) |
|
|
|
def random_artist_management(): |
|
global top_100_keywords, top_100_counts, cached_rows |
|
if not cached_rows: return |
|
if not (top_100_keywords): |
|
if not os.path.exists("counting_result.txt"): |
|
keyword_counts = analyze_cached_rows(cached_rows) |
|
excluded_keywords = set(whitelist[:2974]) |
|
with open("counting_result.txt", "w") as file: |
|
for keyword, count in sorted(keyword_counts.items(), key=lambda item: item[1], reverse=True): |
|
if keyword not in excluded_keywords and keyword in afilter_30000: |
|
file.write(f"{keyword}: {count}\n") |
|
with open("counting_result.txt", "r") as file: |
|
lines = file.readlines() |
|
top_100_data = [ |
|
(line.split(":")[0].strip(), int(line.split(":")[1].strip())) |
|
for line in lines[:3000] |
|
if line.split(":")[0].strip() in afilter_30000[:8528] |
|
] |
|
top_100_keywords, top_100_counts = zip(*top_100_data) if top_100_data else ([], []) |
|
elif (not top_100_keywords): |
|
with open("counting_result.txt", "r") as file: |
|
lines = file.readlines() |
|
top_100_data = [ |
|
(line.split(":")[0].strip(), int(line.split(":")[1].strip())) |
|
for line in lines[:3000] |
|
if line.split(":")[0].strip() in afilter_30000[:8528] |
|
] |
|
top_100_keywords, top_100_counts = zip(*top_100_data) if top_100_data else ([], []) |
|
|
|
|
|
|
|
random_artist_window = tk.Toplevel(window) |
|
|
|
|
|
text_output1 = tk.Text(random_artist_window, height=40, width=50) |
|
text_output1.pack(padx=10, pady=10) |
|
for keyword, count in zip(top_100_keywords, top_100_counts): |
|
text_output1.insert(tk.END, f"{keyword}: {count}\n") |
|
|
|
def update_lists(): |
|
|
|
content = text_output1.get("1.0", tk.END) |
|
lines = content.strip().split("\n") |
|
|
|
|
|
updated_keywords = [] |
|
updated_counts = [] |
|
|
|
|
|
for line in lines: |
|
if line: |
|
parts = line.split(":") |
|
if len(parts) == 2: |
|
updated_keywords.append(parts[0].strip()) |
|
updated_counts.append(int(parts[1].strip())) |
|
|
|
|
|
global top_100_keywords, top_100_counts |
|
top_100_keywords = updated_keywords |
|
top_100_counts = updated_counts |
|
with open("random_artist_keywords_"+str(len(top_100_keywords))+".txt", "w") as f: |
|
for keyword in updated_keywords: |
|
f.write('100: artist:'+keyword + "\n") |
|
|
|
|
|
buttons_frame = tk.Frame(random_artist_window) |
|
buttons_frame.pack(pady=10) |
|
|
|
|
|
save_button = tk.Button(buttons_frame, text="์ ์ฅ", command=update_lists) |
|
save_button.pack(side=tk.LEFT, padx=5) |
|
|
|
|
|
close_button = tk.Button(buttons_frame, text="๋ซ๊ธฐ", command=random_artist_window.destroy) |
|
close_button.pack(side=tk.RIGHT, padx=5) |
|
|
|
random_artist_label = tk.Label(random_artist_window, text='์๊ฐ์ด๋ฆ ์ด '+str(len(top_100_keywords))+'๊ฐ, ์ ์ฅ์์น: exeํ์ผ ์์น') |
|
random_artist_label.pack() |
|
|
|
def open_wildcard_setting(): |
|
global artist_wildcard_saved, character_wildcard_saved |
|
|
|
wildcard_window = tk.Toplevel(window) |
|
wildcard_window.title("์์ผ๋ ์นด๋ ์ค์ ") |
|
|
|
|
|
artist_label = tk.Label(wildcard_window, text="์๊ฐ๋ช
ํ์ผ ๋ถ๋ฌ์ค๊ธฐ ->") |
|
artist_label.grid(row=0, column=0) |
|
artist_button = tk.Button(wildcard_window, text="์ด๊ธฐ", command=lambda: load_wildcard(artist_text, wildcard_window, 'artist')) |
|
artist_button.grid(row=0, column=1) |
|
|
|
artist_text = tk.Text(wildcard_window, height=15, width=60) |
|
artist_text.grid(row=1, column=0, columnspan=2) |
|
if artist_wildcard_saved: |
|
artist_text_content = '\n'.join(artist_wildcard_saved) |
|
artist_text.insert('1.0', artist_text_content) |
|
|
|
|
|
character_label = tk.Label(wildcard_window, text="์บ๋ฆญํฐ ํ์ผ ๋ถ๋ฌ์ค๊ธฐ ->") |
|
character_label.grid(row=2, column=0) |
|
character_button = tk.Button(wildcard_window, text="์ด๊ธฐ", command=lambda: load_wildcard(character_text, wildcard_window, 'character')) |
|
character_button.grid(row=2, column=1) |
|
|
|
character_text = tk.Text(wildcard_window, height=15, width=60) |
|
character_text.grid(row=3, column=0, columnspan=2) |
|
if character_wildcard_saved: |
|
character_text_content = '\n'.join(character_wildcard_saved) |
|
character_text.insert('1.0', character_text_content) |
|
|
|
|
|
buttons_frame = tk.Frame(wildcard_window) |
|
buttons_frame.grid(row=4, column=0, columnspan=2) |
|
|
|
text_label = tk.Label(wildcard_window, text="wildcard ๋ฌธ๋ฒ(์๊ฐ):\noffset:wildcard1 150:null (helloworld)\noffset:wildcard2 100:none (goodbye)\n์์ผ๋ฉด 100: ์ผ๋ก ๊ฐ์ฃผ\noffset/offset ์ดํฉ: wildcard ํ๋ฅ ") |
|
text_label.grid(row=5, column=0,sticky='ew') |
|
text_label2 = tk.Label(wildcard_window, text="wildcard ๋ฌธ๋ฒ(์บ๋ฆญ):\n200:{{arona (blue archive)}}, blue hair, blue eyes, hair over one eye, ...\n150:{{nahida (genshin impact)}}, green eyes, pointy ears, ...\n...") |
|
text_label2.grid(row=6, column=0,sticky='ew') |
|
|
|
load_button = tk.Button(buttons_frame, text="์์ผ๋์นด๋ ํ์ฌ", command=lambda: apply_wildcard(artist_text, character_text, wildcard_window)) |
|
load_button.pack(side=tk.LEFT, padx=10) |
|
|
|
close_button = tk.Button(buttons_frame, text="๋ซ๊ธฐ", command=wildcard_window.destroy) |
|
close_button.pack(side=tk.RIGHT, padx=10) |
|
|
|
def apply_wildcard(artist_text, character_text, window): |
|
global artist_wildcard_saved |
|
artist_wildcard_check = artist_text.get("1.0", tk.END) |
|
if len(artist_wildcard_check) > 5: |
|
lines = artist_wildcard_check.strip().split("\n") |
|
artist_wildcard_saved = lines.copy() |
|
akeywords = [] |
|
current_index = 0 |
|
for line in lines: |
|
parts = line.strip().split(':', 1) |
|
if len(parts) == 2 and parts[0].strip().isdigit(): |
|
weight = int(parts[0].strip()) |
|
else: |
|
weight = 100 |
|
parts = ['100', line.strip()] |
|
keyword = parts[1].strip() |
|
akeywords.append((current_index, current_index + weight - 1, keyword)) |
|
current_index += weight |
|
global artist_wildcard |
|
artist_wildcard = akeywords |
|
check_wildcard.config(state='normal') |
|
|
|
character_wildcard_check = character_text.get("1.0", tk.END) |
|
global character_wildcard_saved |
|
if len(character_wildcard_check) > 5: |
|
lines = character_wildcard_check.strip().split("\n") |
|
character_wildcard_saved = lines.copy() |
|
ckeywords = [] |
|
current_index = 0 |
|
for line in lines: |
|
parts = line.strip().split(':', 1) |
|
if len(parts) == 2 and parts[0].strip().isdigit(): |
|
weight = int(parts[0].strip()) |
|
else: |
|
weight = 100 |
|
parts = ['100', line.strip()] |
|
keyword = parts[1].strip() |
|
ckeywords.append((current_index, current_index + weight - 1, keyword)) |
|
current_index += weight |
|
global character_wildcard |
|
character_wildcard = ckeywords |
|
check_wildcard2.config(state='normal') |
|
|
|
window.destroy() |
|
|
|
def load_wildcard(text_widget, window, _type): |
|
global artist_wildcard_saved, character_wildcard_saved |
|
window.iconify() |
|
filepath = filedialog.askopenfilename(filetypes=[("ํ
์คํธ ํ์ผ", "*.txt")]) |
|
if filepath: |
|
with open(filepath, 'r', encoding='utf-8') as file: |
|
lines = file.readlines() |
|
updated_lines = [] |
|
for line in lines: |
|
line = line.strip() |
|
if ':' in line: |
|
prefix, _ = line.split(':', 1) |
|
if not prefix.strip().isdigit(): |
|
line = f"100: {line}" |
|
else: |
|
line = f"100: {line}" |
|
updated_lines.append(line) |
|
|
|
text_widget.delete('1.0', tk.END) |
|
text_widget.insert('1.0', '\n'.join(updated_lines)) |
|
|
|
if(_type == 'artist'): |
|
artist_wildcard_saved = updated_lines.copy() |
|
elif(_type == 'character'): |
|
character_wildcard_saved = updated_lines.copy() |
|
|
|
window.deiconify() |
|
|
|
def find_keyword(index, keywords): |
|
for start, end, keyword in keywords: |
|
if start <= index <= end: |
|
return keyword |
|
return None |
|
|
|
def get_random_keyword(req_keyword): |
|
|
|
global artist_wildcard, character_wildcard |
|
if(req_keyword == 'artist'): keywords = artist_wildcard |
|
elif(req_keyword == 'character'): keywords = character_wildcard |
|
print('lenghth = ',len(keywords)) |
|
max_index = keywords[-1][1] |
|
random_index = random.randint(0, max_index) |
|
return find_keyword(random_index, keywords) |
|
|
|
def tprint(*args): |
|
ctext = "" |
|
color = None |
|
for t in args: |
|
if(type(t) is str and 'color=' in t): |
|
color = t[6:] |
|
else: |
|
ctext += str(t) |
|
if not color: running_state.config(text=ctext, fg='black') |
|
else: running_state.config(text=ctext, fg='red') |
|
|
|
|
|
def show_automation_option(): |
|
global auto_thread, stop_event |
|
top = tk.Toplevel(window) |
|
top.title("Automation Stop Condition") |
|
|
|
global var, timer_label, timer_entry, count_label, count_entry |
|
var = tk.StringVar(value="unlimited") |
|
|
|
def show_option(): |
|
if var.get() == 'timer': |
|
timer_label.grid(row=4, column=0) |
|
timer_entry.grid(row=4, column=1) |
|
count_label.grid_forget() |
|
count_entry.grid_forget() |
|
elif var.get() == 'count': |
|
count_label.grid(row=4, column=0) |
|
count_entry.grid(row=4, column=1) |
|
timer_label.grid_forget() |
|
timer_entry.grid_forget() |
|
else: |
|
timer_label.grid_forget() |
|
timer_entry.grid_forget() |
|
count_label.grid_forget() |
|
count_entry.grid_forget() |
|
|
|
label_time = tk.Label(top, text="์ด๋ฏธ์ง ์์ฑ๋น ์ง์ฐ์๊ฐ ์ถ๊ฐ (์ด)") |
|
label_time.grid(row=0, column=0, columnspan=3) |
|
|
|
delay_entry = tk.Entry(top) |
|
delay_entry.grid(row=1, column=0, columnspan=3) |
|
|
|
label = tk.Label(top, text="์๋ํ ์ข
๋ฃ ์กฐ๊ฑด") |
|
label.grid(row=2, column=0, columnspan=3) |
|
|
|
radio1 = tk.Radiobutton(top, text="๋ฌด์ ํ", variable=var, value="unlimited", command=show_option) |
|
radio1.grid(row=3, column=0) |
|
|
|
radio2 = tk.Radiobutton(top, text="ํ์ด๋จธ", variable=var, value="timer", command=show_option) |
|
radio2.grid(row=3, column=1) |
|
|
|
radio3 = tk.Radiobutton(top, text="์์ฑ ์นด์ดํธ", variable=var, value="count", command=show_option) |
|
radio3.grid(row=3, column=2) |
|
|
|
timer_label = tk.Label(top, text="์๋ํ ๋์ ์๊ฐ(๋ถ) :") |
|
timer_entry = tk.Entry(top) |
|
|
|
count_label = tk.Label(top, text="์๋ ์์ฑ ํ์:") |
|
count_entry = tk.Entry(top) |
|
|
|
|
|
def on_apply(top): |
|
global auto_time_left_flag, auto_time_left, auto_count_left_flag, auto_count_left, delay_offset, delay_offset_label |
|
|
|
selected_option = var.get() |
|
if delay_entry.get(): |
|
try: |
|
delay_offset = round(float(delay_entry.get()), 1) |
|
delay_offset_label.config(text="Dealy offset : "+str(delay_offset)) |
|
except ValueError as e: |
|
print(e) |
|
delay_offset = 0 |
|
else: |
|
delay_offset = 0 |
|
delay_offset_label.config(text="") |
|
if selected_option == "timer": |
|
auto_time_left_flag = True |
|
auto_count_left_flag = False |
|
try: |
|
|
|
auto_time_left = int(timer_entry.get()) * 60 |
|
except ValueError: |
|
|
|
print("Invalid input for timer. Please enter a number.") |
|
return |
|
elif selected_option == "count": |
|
auto_count_left_flag = True |
|
auto_time_left_flag = False |
|
try: |
|
auto_count_left = int(count_entry.get()) |
|
except ValueError: |
|
|
|
print("Invalid input for count. Please enter a number.") |
|
return |
|
else: |
|
auto_time_left_flag = False |
|
auto_count_left_flag = False |
|
stop_auto_thread() |
|
start_auto_thread() |
|
mac_var.set(1) |
|
top.destroy() |
|
|
|
apply_button = tk.Button(top, text="์ ์ฉ", command=lambda: on_apply(top)) |
|
stop_button = tk.Button(top, text="์ค๋จ", command=on_stop) |
|
close_button = tk.Button(top, text="๋ซ๊ธฐ", command=top.destroy) |
|
|
|
apply_button.grid(row=5, column=0, pady=5) |
|
stop_button.grid(row=5, column=1, pady=5) |
|
close_button.grid(row=5, column=2, pady=5) |
|
|
|
def auto_time_thread(stop_event): |
|
global auto_time_left, auto_time_left_flag |
|
|
|
def seconds_to_hms(seconds): |
|
h = seconds // 3600 |
|
m = (seconds % 3600) // 60 |
|
s = seconds % 60 |
|
return f"{h:02d}:{m:02d}:{s:02d}" |
|
|
|
def update_label_for_time_finished(): |
|
automation_state.config(text="์ง์ ํ ์๊ฐ์ด ๋ชจ๋ ์์ง๋์ด ์๋ํ๊ฐ ์ข
๋ฃ๋์์ต๋๋ค.") |
|
auto_time_left_flag = False |
|
mac_var.set(0) |
|
|
|
while not stop_event.is_set() and auto_time_left > 0: |
|
time.sleep(1) |
|
auto_time_left -= 1 |
|
remaining_time = seconds_to_hms(auto_time_left) |
|
window.after(0, lambda: automation_state.config(text=f"์๋ํ ๋จ์์๊ฐ : {remaining_time}")) |
|
|
|
if auto_time_left <= 0: |
|
window.after(0, update_label_for_time_finished) |
|
|
|
if stop_event.is_set(): |
|
window.after(0, lambda: automation_state.config(text="Conditional automation not set (A.์ค์ )")) |
|
auto_time_left_flag = False |
|
|
|
def auto_count_thread(stop_event): |
|
global auto_count_left, auto_count_left_flag |
|
|
|
def update_label_for_count_finished(): |
|
mac_var.set(0) |
|
auto_count_left_flag = False |
|
automation_state.config(text="์ง์ ํ ํ์๊ฐ ๋ชจ๋ ์์ง๋์ด ์๋ํ๊ฐ ์ข
๋ฃ๋์์ต๋๋ค.") |
|
|
|
while not stop_event.is_set(): |
|
time.sleep(1) |
|
window.after(0, lambda: automation_state.config(text=f"์๋ํ ๋จ์ํ์ : {auto_count_left}")) |
|
if auto_count_left <= 0: |
|
window.after(0, update_label_for_count_finished) |
|
break |
|
if stop_event.is_set(): |
|
window.after(0, lambda: automation_state.config(text="Conditional automation not set (A.์ค์ )")) |
|
mac_var.set(0) |
|
auto_count_left_flag = False |
|
|
|
|
|
def start_auto_thread(): |
|
global auto_thread, stop_event |
|
stop_event = threading.Event() |
|
auto_thread = None |
|
|
|
if auto_time_left_flag: |
|
auto_thread = threading.Thread(target=auto_time_thread, args=(stop_event,)) |
|
elif auto_count_left_flag: |
|
auto_thread = threading.Thread(target=auto_count_thread, args=(stop_event,)) |
|
|
|
if auto_thread is not None: |
|
auto_thread.start() |
|
|
|
def stop_auto_thread(): |
|
global stop_event, auto_thread |
|
if stop_event is not None: |
|
stop_event.set() |
|
|
|
|
|
|
|
def on_stop(): |
|
global auto_thread, stop_event |
|
stop_auto_thread() |
|
|
|
def on_hold_seed_button_click(): |
|
global last_generation_seed |
|
last_generation_seed = entry_seed_value.get() |
|
|
|
def update_fullscreen_image(new_window, new_image_label): |
|
last_updated_image = None |
|
while True: |
|
time.sleep(1) |
|
if not new_window.winfo_exists(): |
|
break |
|
try: |
|
current_image = getattr(image_label, 'original_image', None) |
|
if current_image and current_image != last_updated_image: |
|
resized_image = resize_image_to_fit(current_image, new_window.winfo_height()) |
|
tk_image = ImageTk.PhotoImage(resized_image) |
|
new_window.after(0, lambda img=tk_image: new_image_label.config(image=img)) |
|
new_image_label.image = tk_image |
|
last_updated_image = current_image |
|
except ValueError: |
|
print(ValueError) |
|
|
|
def show_fullscreen_image(): |
|
new_window = tk.Toplevel() |
|
new_window.attributes('-fullscreen', True) |
|
new_window.configure(bg='black') |
|
|
|
new_image_label = tk.Label(new_window, relief='solid', borderwidth=1, bg='black') |
|
new_image_label.pack(expand=True, fill='both') |
|
new_window.bind("<Escape>", lambda e: new_window.destroy()) |
|
|
|
update_thread = threading.Thread(target=update_fullscreen_image, args=(new_window, new_image_label)) |
|
update_thread.daemon = True |
|
update_thread.start() |
|
|
|
def resize_image_to_fit(image, target_height): |
|
original_width, original_height = image.size |
|
|
|
ratio = target_height / float(original_height) |
|
new_width = int(original_width * ratio) |
|
|
|
resized_image = image.resize((new_width, target_height), Image.Resampling.LANCZOS) |
|
return resized_image |
|
|
|
auto_time_left_flag = False |
|
auto_time_left = 0 |
|
auto_count_left_flag = False |
|
auto_count_left = 0 |
|
stop_event = None |
|
auto_thread = None |
|
delay_offset = 0 |
|
|
|
start_time = datetime.now().strftime('%Y%m%d_%H%M') |
|
thread_controller = False |
|
turbo_count = 0 |
|
on_press_flag = False |
|
window = tk.Tk() |
|
window.title("Prompt Selector for Danbooru tags") |
|
last_deep_search_keywords = None |
|
cached_rows = [] |
|
total_rows = 0 |
|
last_selected_row_keywords = ['1girl','nahida (genshin impact)', 'looking at viewer', 'garden'] |
|
top_100_keywords = [] |
|
top_100_counts = [] |
|
previous_artist = None |
|
listener = None |
|
current_keys = set() |
|
click_count = 0 |
|
access_token = None |
|
temp_clipboard_image = None |
|
NAI_width = 1024 |
|
NAI_height = 1024 |
|
current_sampler = "k_euler_ancestral" |
|
running_flag = False |
|
NAI_ID = None |
|
artist_wildcard = [] |
|
character_wildcard_saved = [] |
|
artist_wildcard_saved = [] |
|
character_wildcard =[] |
|
access_token_multi = None |
|
NAI_ID_multi = None |
|
image_queue = [] |
|
last_generation_seed = random.randint(0,9999999999) |
|
turbo_stop_bit = False |
|
task_finished = 0 |
|
error_count = 0 |
|
multi_token_enable = False |
|
|
|
whitelist = wlist.whitelist |
|
bag_of_tags = tagbag.bag_of_tags |
|
afilter_30000 = arti_list.afilter_30000 |
|
history = [] |
|
|
|
current_wildcard_artist = [] |
|
current_wildcard_character = [] |
|
|
|
previous_wildcard_artist = None |
|
previous_wildcard_character = None |
|
|
|
GENERATE_EVENT = "<<GenerateEvent>>" |
|
window.bind(GENERATE_EVENT, on_generate_event) |
|
|
|
left_frame = tk.Frame(window) |
|
left_frame.grid(row=0, column=0, sticky="nsew") |
|
|
|
right_frame = tk.Frame(window) |
|
right_frame.grid(row=0, column=1, sticky="nsew") |
|
window.grid_columnconfigure(0, weight=1) |
|
window.grid_columnconfigure(1, weight=1) |
|
|
|
|
|
frame_row0 = tk.Frame(left_frame) |
|
frame_row0.grid(row=0, column=0, padx=5, pady=5, sticky='w') |
|
|
|
|
|
label_file_path = tk.Label(frame_row0, text="CSV ํ์ผ ๊ฒฝ๋ก:") |
|
label_file_path.grid(row=0, column=0, sticky='w') |
|
entry_file_path = tk.Entry(frame_row0, width=55) |
|
entry_file_path.grid(row=0, column=1, columnspan=4, padx=5, pady=5, sticky='ew') |
|
button_open_file = tk.Button(frame_row0, text="ํ์ผ ์ด๊ธฐ", command=open_file) |
|
button_open_file.grid(row=0, column=5, padx=5, pady=6, sticky='e') |
|
|
|
|
|
keyword_label = tk.Label(frame_row0, text="์ด๊ธฐํ ํค์๋: ") |
|
keyword_label.grid(row=1, column=0, sticky='w') |
|
entry_keyword = tk.Entry(frame_row0) |
|
entry_keyword.grid(row=1, column=1, columnspan=4, padx=5, pady=5, sticky='ew') |
|
button_export_csv = tk.Button(frame_row0, text=".csv ๋ด๋ณด๋ด๊ธฐ", command=export_csv) |
|
button_export_csv.grid(row=1, column=5, padx=5, pady=6, sticky='e') |
|
|
|
|
|
frame_buttons = tk.Frame(left_frame) |
|
frame_buttons.grid(row=1, column=0, sticky='ew') |
|
frame_buttons.columnconfigure(0, weight=1) |
|
frame_buttons.columnconfigure(1, weight=0) |
|
frame_buttons.columnconfigure(2, weight=0) |
|
frame_buttons.columnconfigure(3, weight=1) |
|
|
|
|
|
button_search = tk.Button(frame_buttons, text="ํด๋น ํค์๋ ๊ฒ์", command=search) |
|
button_search.grid(row=0, column=1, padx=5, sticky='ew') |
|
button_exclude = tk.Button(frame_buttons, text="ํด๋น ํค์๋ ์ ์ธ", command=exclude) |
|
button_exclude.grid(row=0, column=2, padx=5, sticky='ew') |
|
|
|
total_rows_count_label = tk.Label(frame_buttons, text=".csv ๋ด ํ๋กฌํํธ ํ: 0") |
|
total_rows_count_label.grid(row=0, column=3, padx=5, sticky='ew') |
|
|
|
|
|
deep_search_frame = tk.Frame(left_frame) |
|
deep_search_frame.grid(row=2, column=0, pady=10, sticky='w') |
|
deep_search_frame.columnconfigure(0, weight=2) |
|
deep_search_frame.columnconfigure(1, weight=2) |
|
deep_search_frame.columnconfigure(2, weight=1) |
|
|
|
label_deep_search = tk.Label(deep_search_frame, text="์ฌ์ธต๊ฒ์ ํค์๋ ์
๋ ฅ: key,*key,~key,{key1|key2} ") |
|
label_deep_search.grid(row=0, column=0, sticky='w') |
|
|
|
|
|
cached_rows_count_label = tk.Label(deep_search_frame, text="์ฌ์ธต๊ฒ์ ํ๋กฌํํธ ํ: 0") |
|
cached_rows_count_label.grid(row=0, column=1, padx=5, sticky='w') |
|
|
|
button_export_deep_csv = tk.Button(deep_search_frame, text=".csv ๋ด๋ณด๋ด๊ธฐ", command=export_csv_search) |
|
button_export_deep_csv.grid(row=0, column=2, padx=5, sticky='e') |
|
|
|
entry_deep_search = tk.Entry(deep_search_frame, width=82) |
|
entry_deep_search.grid(row=1, column=0, columnspan=3,padx=5, pady=5, sticky='ew') |
|
|
|
|
|
button_frame = tk.Frame(left_frame) |
|
button_frame.grid(row=5, column=0, padx=5, sticky='w') |
|
|
|
|
|
button_frame.columnconfigure(0, weight=1) |
|
button_frame.columnconfigure(1, weight=1) |
|
button_frame.columnconfigure(2, weight=1) |
|
button_frame.columnconfigure(3, weight=1) |
|
button_frame.columnconfigure(4, weight=1) |
|
button_frame.columnconfigure(5, weight=1) |
|
button_frame.columnconfigure(6, weight=1) |
|
|
|
|
|
button_random = tk.Button(button_frame, text="๋๋ค", command=random_function) |
|
button_random.grid(row=0, column=0, sticky='ew') |
|
|
|
|
|
button_frame_frame = tk.Frame(button_frame) |
|
button_frame_frame.grid(row=0, column=1, sticky='ew') |
|
toggle_prompt_var = tk.IntVar() |
|
button_toggle_prompt = tk.Checkbutton(button_frame_frame, text="ํ๋กฌํํธ ๊ณ ์ ", variable=toggle_prompt_var) |
|
button_toggle_prompt.grid(row=0, column=0, sticky='ew') |
|
safe_search_var = tk.IntVar() |
|
button_toggle_safe_search = tk.Checkbutton(button_frame_frame, text="์ธ์ดํ์์น", variable=safe_search_var) |
|
button_toggle_safe_search.grid(row=1, column=0, sticky='ew') |
|
|
|
|
|
auto_copy_var = tk.IntVar() |
|
check_auto_copy = tk.Checkbutton(button_frame, text="์๋ ๋ณต์ฌ", variable=auto_copy_var) |
|
check_auto_copy.grid(row=0, column=2, sticky='ew') |
|
|
|
|
|
button_exit = tk.Button(button_frame, text="์ข
๋ฃ", command=exit_program) |
|
button_exit.grid(row=0, column=3, sticky='ew') |
|
|
|
|
|
button_generate = tk.Button(button_frame, text="NAI ์์ฒญ", command=lambda: NAI_generation(NAI_width, NAI_height, button_generate)) |
|
button_generate.grid(row=0, column=4, sticky='ew') |
|
button_generate.config(state='disabled') |
|
|
|
|
|
button_stop = tk.Button(button_frame, text="์ค๋จ",command=lambda: turbo_stop(button_stop)) |
|
button_stop.grid(row=0, column=5, sticky='ew') |
|
button_stop.config(state='disabled') |
|
|
|
|
|
button_setting = tk.Button(button_frame, text="NAI ์ค์ ", command=lambda: NAI_setting(button_setting, button_generate)) |
|
button_setting.grid(row=0, column=6, sticky='ew') |
|
|
|
|
|
sub_frame = tk.Frame(button_frame) |
|
sub_frame.grid(row=0, column=7, sticky='ns') |
|
|
|
|
|
mac_var = tk.IntVar() |
|
mac_button = tk.Checkbutton(sub_frame, text="์๋ํ", variable=mac_var) |
|
mac_button.grid(row=0, column=0, sticky='ew') |
|
|
|
|
|
turbo_var = tk.IntVar() |
|
turbo_button = tk.Checkbutton(sub_frame, text="ํฐ๋ณดon", variable=turbo_var) |
|
turbo_button.grid(row=1, column=0, sticky='ew') |
|
|
|
|
|
button_auto_setting = tk.Button(button_frame, text="A.์ค์ ", command=show_automation_option) |
|
button_auto_setting.grid(row=0, column=8, sticky='ew') |
|
|
|
|
|
text_frame = tk.Frame(left_frame) |
|
text_frame.grid(row=6, column=0, padx=5, pady=5, sticky='w') |
|
text_frame.columnconfigure(0, weight=1) |
|
text_frame.columnconfigure(1, weight=7) |
|
|
|
text_frame2 = tk.Frame(left_frame) |
|
text_frame2.grid(row=8, column=0, padx=5, pady=5, sticky='w') |
|
text_frame2.columnconfigure(0, weight=1) |
|
text_frame2.columnconfigure(1, weight=7) |
|
|
|
_size = get_max_size() |
|
|
|
|
|
text_output_label = tk.Label(text_frame, text="ํ๋กฌํํธ", borderwidth=1, relief="solid",height=6) |
|
text_output_label.grid(row=0, column=0, padx=5, pady=5, sticky='w') |
|
if _size<=768: text_output_width = 74 |
|
else: text_output_width = 65 |
|
text_output = tk.Text(text_frame, width=text_output_width, height=7) |
|
text_output.grid(row=0, column=1, sticky='ew') |
|
|
|
fixed_prompt_frame = tk.Frame(left_frame) |
|
fixed_prompt_frame.grid(row=7, column=0, padx=5, pady=5, sticky='w') |
|
fixed_prompt_frame.columnconfigure(0, weight=1) |
|
fixed_prompt_frame.columnconfigure(1, weight=1) |
|
|
|
fixed_prompt_label_left = tk.Label(fixed_prompt_frame, text="์ ํ ๊ณ ์ ํ๋กฌํํธ (ํ๋กฌํํธ ์)") |
|
fixed_prompt_label_left.grid(row=0, column=0, sticky='ew') |
|
fixed_prompt_label_right = tk.Label(fixed_prompt_frame, text="ํํ ๊ณ ์ ํ๋กฌํํธ (ํ๋กฌํํธ ๋ค)") |
|
fixed_prompt_label_right.grid(row=0, column=1, sticky='ew') |
|
entry_fixed_prompt = tk.Entry(fixed_prompt_frame, width=40) |
|
entry_fixed_prompt.grid(row=1, column=0,padx=5, pady=5, sticky='ew') |
|
entry_fixed_prompt_after = tk.Entry(fixed_prompt_frame, width=40) |
|
entry_fixed_prompt_after.grid(row=1, column=1, padx=5, pady=5, sticky='ew') |
|
|
|
|
|
NP_label = tk.Label(text_frame2, text="๋ค๊ฑฐํฐ๋ธ\nํ๋กฌํํธ", borderwidth=1, relief="solid",height=2) |
|
NP_label.grid(row=0,column=0, padx=5, pady=5, sticky='ew') |
|
negative_text = tk.Text(text_frame2, width=65, height=3) |
|
negative_text.grid(row=0, column=1, padx=5, pady=5, sticky='w') |
|
|
|
auto_hide_frame = tk.Frame(left_frame) |
|
auto_hide_frame.grid(row=9, column=0, padx=5, pady=5, sticky='w') |
|
auto_hide_frame.columnconfigure(0, weight=2) |
|
auto_hide_frame.columnconfigure(1, weight=2) |
|
auto_hide_frame.columnconfigure(2, weight=1) |
|
|
|
|
|
auto_hide_label = tk.Label(auto_hide_frame, text="์๋ ์จ๊น ํค์๋: keyword1, keyword2, ...") |
|
auto_hide_label.grid(row=0, column=0, sticky='w') |
|
entry_auto_hide = tk.Entry(auto_hide_frame, width=82) |
|
entry_auto_hide.grid(row=1, column=0, columnspan=3, padx=5, pady=5, sticky='ew') |
|
|
|
character_search_button = tk.Button(auto_hide_frame, text="์บ๋ฆญํฐ ๊ฒ์", command=character_search_thread) |
|
character_search_button.grid(row=0, column=1, padx=2, pady=5, sticky='e') |
|
recommend_prompt_button = tk.Button(auto_hide_frame, text="์ถ์ฒ ํ๋กฌํํธ", command=open_prompt_window) |
|
recommend_prompt_button.grid(row=0, column=2, padx=2, pady=5, sticky='e') |
|
|
|
|
|
|
|
|
|
checkbox_frame = tk.Frame(left_frame) |
|
checkbox_frame.grid(row=10, column=0, pady=15, sticky='ew') |
|
checkbox_frame2 = tk.Frame(left_frame) |
|
checkbox_frame2.grid(row=10, column=1, padx=5, pady=15, sticky='ew') |
|
|
|
|
|
checkbox_frame.columnconfigure(0, weight=1) |
|
checkbox_frame.columnconfigure(1, weight=1) |
|
checkbox_frame.columnconfigure(2, weight=1) |
|
checkbox_frame.columnconfigure(3, weight=1) |
|
checkbox_frame.columnconfigure(4, weight=1) |
|
checkbox_frame.columnconfigure(5, weight=1) |
|
|
|
|
|
|
|
remove_artist_var = tk.IntVar() |
|
check_remove_artist = tk.Checkbutton(checkbox_frame, text="์๊ฐ๋ช
์ ๊ฑฐ", variable=remove_artist_var) |
|
check_remove_artist.grid(row=0, column=0, sticky='ew') |
|
|
|
|
|
random_artist_var = tk.IntVar() |
|
check_random_artist = tk.Checkbutton(checkbox_frame, text="๋๋ค ์๊ฐ ์ถ๊ฐ", variable=random_artist_var) |
|
check_random_artist.grid(row=0, column=1, sticky='ew') |
|
|
|
|
|
random_artist_setting = tk.Button(checkbox_frame, text="๋๋ค ์๊ฐ ๊ด๋ฆฌ", command=random_artist_management) |
|
random_artist_setting.grid(row=0, column=2, sticky='ew') |
|
|
|
|
|
rm_characteristic_var = tk.IntVar() |
|
rm_characteristic_label = tk.Checkbutton(checkbox_frame, text="์บ๋ฆญํฐ ํน์ง ์ ๊ฑฐ", variable=rm_characteristic_var) |
|
rm_characteristic_label.grid(row=0, column=3, sticky='ew') |
|
|
|
|
|
wildcard_var = tk.IntVar(value= 0) |
|
check_wildcard = tk.Checkbutton(checkbox_frame, text="์์ผ๋์นด๋(์๊ฐ)", variable=wildcard_var, state='disabled') |
|
check_wildcard.grid(row=1, column=0, sticky='ew') |
|
|
|
|
|
wildcard_var2 = tk.IntVar(value= 0) |
|
check_wildcard2 = tk.Checkbutton(checkbox_frame, text="์์ผ๋์นด๋(์บ๋ฆญํฐ)", variable=wildcard_var2, state='disabled') |
|
check_wildcard2.grid(row=1, column=1, sticky='ew') |
|
|
|
|
|
widldcard_button = tk.Button(checkbox_frame, text="์์ผ๋์นด๋ ์ค์ ", command=open_wildcard_setting) |
|
widldcard_button.grid(row=1, column=2, sticky='ew') |
|
|
|
|
|
folder_button = tk.Button(checkbox_frame, text="์ ์ฅ ํด๋", command=open_file_explorer) |
|
folder_button.grid(row=1, column=3, padx=5, sticky='ew') |
|
|
|
|
|
rm_copyright_var = tk.IntVar() |
|
rm_copyright_label = tk.Checkbutton(checkbox_frame, text="์ํ๋ช
์ ๊ฑฐ", variable=rm_copyright_var) |
|
rm_copyright_label.grid(row=2, column=0, pady=5, sticky='ew') |
|
|
|
|
|
NSFW_assert_var = tk.IntVar() |
|
NSFW_assert_label = tk.Checkbutton(checkbox_frame, text="NSFW Only", variable=NSFW_assert_var) |
|
NSFW_assert_label.grid(row=2, column=1, pady=5, sticky='ew') |
|
|
|
window.bind('<Control-Return>', on_ctrl_enter) |
|
window.bind('<Shift-Return>', on_shift_enter) |
|
|
|
NAI_ID = load_settings() |
|
if not (entry_keyword.get()): entry_keyword.insert(0, "1girl") |
|
if not (entry_fixed_prompt.get()): entry_fixed_prompt.insert(0, '1girl,') |
|
if not (entry_fixed_prompt_after.get()): entry_fixed_prompt_after.insert(0, 'great quality, aesthetic, absurdres') |
|
if not (entry_auto_hide.get()): entry_auto_hide.insert(0, 'monochrome, doujin cover, bad source, censored, bar censor') |
|
|
|
|
|
|
|
resolution1_frame = tk.Frame(left_frame) |
|
resolution1_frame.grid(row=16, column=0, padx=5, pady=5, sticky='ew') |
|
resolution2_frame = tk.Frame(left_frame) |
|
resolution2_frame.grid(row=17, column=0, padx=5, pady=5, sticky='ew') |
|
selected_resolution = tk.StringVar(value="1024 x 1024") |
|
|
|
tk.Radiobutton(resolution1_frame, text="1024 x 1024", variable=selected_resolution, value="1024 x 1024").grid(row=0, column=0, sticky='w') |
|
tk.Radiobutton(resolution1_frame, text="960 x 1088", variable=selected_resolution, value="960 x 1088").grid(row=0, column=1, sticky='w') |
|
tk.Radiobutton(resolution1_frame, text="896 x 1152", variable=selected_resolution, value="896 x 1152").grid(row=0, column=2, sticky='w') |
|
tk.Radiobutton(resolution1_frame, text="832 x 1216", variable=selected_resolution, value="832 x 1216").grid(row=0, column=3, sticky='w') |
|
tk.Radiobutton(resolution2_frame, text="1088 x 960", variable=selected_resolution, value="1088 x 960").grid(row=0, column=0, sticky='w') |
|
tk.Radiobutton(resolution2_frame, text="1152 x 896", variable=selected_resolution, value="1152 x 896").grid(row=0, column=1, sticky='w') |
|
tk.Radiobutton(resolution2_frame, text="1216 x 832", variable=selected_resolution, value="1216 x 832").grid(row=0, column=2, sticky='w') |
|
selected_resolution.trace_add('write', on_resolution_change) |
|
|
|
sema_button_var = tk.IntVar(value=1) |
|
sema_button = tk.Checkbutton(resolution1_frame, text="SEMA", variable=sema_button_var) |
|
sema_button.grid(row=0, column=5, sticky='w') |
|
|
|
dyn_button_var = tk.IntVar() |
|
dyn_button = tk.Checkbutton(resolution1_frame, text="+DYN", variable=dyn_button_var) |
|
dyn_button.grid(row=0, column=6, sticky='w') |
|
|
|
rand_resolution_var = tk.IntVar() |
|
rand_resolution_button = tk.Checkbutton(resolution1_frame, text="๋๋ค ํด์๋", variable=rand_resolution_var) |
|
rand_resolution_button.grid(row=0, column=7, sticky='w') |
|
|
|
entry_CFG_value = tk.StringVar() |
|
entry_CFG_label = tk.Label(resolution2_frame, text=" CFG Scale : ", justify=tk.LEFT) |
|
entry_CFG_label.grid(row=0, column=4, sticky='w') |
|
entry_CFG_value.set("5.0") |
|
|
|
entry_CFG = tk.Entry(resolution2_frame, width=5, textvariable=entry_CFG_value) |
|
entry_CFG.grid(row=0, column=5, sticky='w') |
|
|
|
options = ["k_euler", "k_euler_ancestral", "k_dpmpp_2s_ancestral", "k_dpmpp_sde"] |
|
selected_option = tk.StringVar() |
|
selected_option.set(options[1]) |
|
option_menu = tk.OptionMenu(resolution2_frame, selected_option, *options, command=on_option_select) |
|
option_menu.grid(row=0, column=6, padx=5, sticky='ew') |
|
|
|
resolution3_frame = tk.Frame(left_frame) |
|
resolution3_frame.grid(row=18, column=0, padx=5, pady=5, sticky='ew') |
|
resolution3_frame.columnconfigure(0, weight=2) |
|
resolution3_frame.columnconfigure(1, weight=1) |
|
resolution3_frame.columnconfigure(2, weight=1) |
|
|
|
running_state = tk.Label(resolution3_frame, text="state : idle") |
|
running_state.grid(row = 0, column= 0, sticky='w') |
|
automation_state = tk.Label(resolution3_frame, text="Conditional automation not set (A.์ค์ )") |
|
automation_state.grid(row = 1, column= 0, sticky='w') |
|
delay_offset_label = tk.Label(resolution3_frame, text="Dealy offset : "+str(delay_offset)) |
|
delay_offset_label.grid(row = 1, column= 1, sticky='e') |
|
entry_rescale_value = tk.StringVar() |
|
entry_rescale_label = tk.Label(resolution3_frame, text=" Prompt Guidance Rescale : ", justify=tk.LEFT) |
|
entry_rescale_label.grid(row=0, column=1, sticky='e') |
|
entry_rescale_value.set("0.0") |
|
entry_rescale = tk.Entry(resolution3_frame, width=5, textvariable=entry_rescale_value) |
|
entry_rescale.grid(row=0, column=2, sticky='w') |
|
|
|
image_label = tk.Label(right_frame, relief='solid', borderwidth=1) |
|
image_label.grid(row=0, column=0, rowspan=15, padx=10, pady=10, sticky="n") |
|
|
|
right_frame_area16 = tk.Frame(right_frame) |
|
right_frame_area16.grid(row=16, column=0, padx=5, pady=5, sticky='ew') |
|
entry_seed_value = tk.IntVar() |
|
entry_seed_label = tk.Label(right_frame_area16, text=" seed : ", justify=tk.LEFT) |
|
entry_seed_label.grid(row=0, column=0, sticky='ew') |
|
entry_seed_value.set(last_generation_seed) |
|
entry_seed = tk.Entry(right_frame_area16, width=15, textvariable=entry_seed_value) |
|
entry_seed.grid(row=0, column=1, sticky='ew') |
|
hold_seed_var = tk.IntVar(value=0) |
|
hold_seed_button = tk.Checkbutton(right_frame_area16, text="์๋๊ณ ์ ", variable=hold_seed_var, command=on_hold_seed_button_click) |
|
hold_seed_button.grid(row=0, column=2, sticky='ew') |
|
|
|
btn_add_low_freq = tk.Button(right_frame_area16, text="์ด๋ฏธ์ง๋ฅผ ํด๋ฆฝ๋ณด๋์ ๋ณต์ฌ", fg="blue", command=copy_image_to_clipboard) |
|
btn_add_low_freq.grid(row=0, column=3, padx=5, pady=5, sticky='ew') |
|
|
|
show_fullscreen_btn = tk.Button(right_frame_area16, text="์ ์ฒดํ๋ฉด ๋ณด๊ธฐ (ESC๋ก ๋ซ๊ธฐ)", command=show_fullscreen_image) |
|
show_fullscreen_btn.grid(row=0, column=4, padx=5, pady=5, sticky='ew') |
|
|
|
show_history_btn = tk.Button(right_frame_area16, text="history", command=show_history) |
|
show_history_btn.grid(row=0, column=5, padx=5, pady=5, sticky='ew') |
|
|
|
|
|
white_image = Image.new('RGB', (_size, _size), 'white') |
|
white_photo = ImageTk.PhotoImage(white_image) |
|
|
|
|
|
image_label.config(image=white_photo) |
|
image_label.image = white_photo |
|
|
|
Auto_login_check() |
|
|
|
window.protocol("WM_DELETE_WINDOW", exit_program) |
|
window.mainloop() |
|
|