baqu2213 commited on
Commit
37e237e
โ€ข
1 Parent(s): c067e2f

Upload 5 files

Browse files
.gitattributes CHANGED
@@ -85,3 +85,4 @@ Danbooru[[:space:]]Prompt[[:space:]]Selector/prompt_selector_auto_1129_delay_off
85
  Danbooru[[:space:]]Prompt[[:space:]]Selector/prompt_selector_auto_1201.exe filter=lfs diff=lfs merge=lfs -text
86
  Danbooru[[:space:]]Prompt[[:space:]]Selector/TEST/prompt_selector_auto_1201_TEST.exe filter=lfs diff=lfs merge=lfs -text
87
  Danbooru[[:space:]]Prompt[[:space:]]Selector/TEST/prompt_selector_auto_1202_testv2.exe filter=lfs diff=lfs merge=lfs -text
 
 
85
  Danbooru[[:space:]]Prompt[[:space:]]Selector/prompt_selector_auto_1201.exe filter=lfs diff=lfs merge=lfs -text
86
  Danbooru[[:space:]]Prompt[[:space:]]Selector/TEST/prompt_selector_auto_1201_TEST.exe filter=lfs diff=lfs merge=lfs -text
87
  Danbooru[[:space:]]Prompt[[:space:]]Selector/TEST/prompt_selector_auto_1202_testv2.exe filter=lfs diff=lfs merge=lfs -text
88
+ Danbooru[[:space:]]Prompt[[:space:]]Selector/prompt_selector_auto_1202.exe filter=lfs diff=lfs merge=lfs -text
Danbooru Prompt Selector/arti_list.py ADDED
The diff for this file is too large to render. See raw diff
 
Danbooru Prompt Selector/prompt_selector_auto_1202.exe ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:477db87b29c97d3195b7a9a2e45c847b4ee6cbd27f32d5a25c56f556b6ad914e
3
+ size 83204847
Danbooru Prompt Selector/prompt_selector_auto_1202.py ADDED
@@ -0,0 +1,1406 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import tkinter as tk
2
+ import tkinter.ttk as ttk
3
+ from tkinter import filedialog
4
+ import os
5
+ import csv
6
+ import random
7
+ import time
8
+ from collections import Counter
9
+ import re
10
+ import ast
11
+ import pyautogui
12
+ import threading
13
+ from pynput import keyboard
14
+ from base64 import urlsafe_b64encode
15
+ from hashlib import blake2b
16
+ import argon2
17
+ import requests
18
+ import json
19
+ from os import environ as env
20
+ import zipfile
21
+ import io
22
+ from pathlib import Path
23
+ from datetime import datetime
24
+ import numpy as np
25
+ from PIL import Image, ImageOps, ImageFilter,ImageTk
26
+ from IPython.display import display
27
+ import win32clipboard
28
+ from io import BytesIO
29
+ from datetime import datetime
30
+ import arti_list, tagbag, wlist
31
+ from ttkthemes import ThemedTk
32
+
33
+ BASE_URL="https://api.novelai.net"
34
+
35
+ def argon_hash(email: str, password: str, size: int, domain: str) -> str:
36
+ pre_salt = f"{password[:6]}{email}{domain}"
37
+ # salt
38
+ blake = blake2b(digest_size=16)
39
+ blake.update(pre_salt.encode())
40
+ salt = blake.digest()
41
+ raw = argon2.low_level.hash_secret_raw(
42
+ password.encode(),
43
+ salt,
44
+ 2,
45
+ int(2000000 / 1024),
46
+ 1,
47
+ size,
48
+ argon2.low_level.Type.ID,
49
+ )
50
+ hashed = urlsafe_b64encode(raw).decode()
51
+ return hashed
52
+
53
+ def login(key) -> str:
54
+ response = requests.post(f"{BASE_URL}/user/login", json={ "key": key })
55
+ # catch any errors
56
+ return response.json()["accessToken"]
57
+
58
+ def get_access_key(email: str, password: str) -> str:
59
+ return argon_hash(email, password, 64, "novelai_data_access_key")[:64]
60
+
61
+ def get_max_size():
62
+ global window
63
+ width = window.winfo_screenheight()
64
+ return 768 if width < 1440 else 1024
65
+
66
+ def generate_image(access_token, prompt, model, action, parameters):
67
+ data = {
68
+ "input": prompt,
69
+ "model": model,
70
+ "action": action,
71
+ "parameters": parameters,
72
+ }
73
+
74
+ response = requests.post(f"{BASE_URL}/ai/generate-image", json=data, headers={ "Authorization": f"Bearer {access_token}" })
75
+ # catch any errors
76
+ return response.content
77
+
78
+ def generate(width, height, positive, negative, button):
79
+ global temp_clipboard_image
80
+ global current_sampler
81
+ global NAI_width, NAI_height
82
+ global running_flag
83
+ try:
84
+ scale = float(entry_CFG_value.get())
85
+ except:
86
+ scale = 5.0
87
+ if scale > 7.0: scale = 7.0
88
+ elif scale < 4.0: scale = 4.0
89
+ else: scale = round(scale, 1)
90
+ params = {
91
+ "legacy": False,
92
+ "quality_toggle": False,
93
+ "width": width,
94
+ "height": height,
95
+ "n_samples": 1,
96
+ "seed": random.randint(0,9999999999),
97
+ "extra_noise_seed": random.randint(0,9999999999),
98
+ "sampler": current_sampler,
99
+ "steps": 28,
100
+ "scale": scale,
101
+ "uncond_scale": 1.0,
102
+ "negative_prompt": negative_text.get("1.0", "end-1c").strip(),
103
+ "sm" : sema_button_var.get(),
104
+ "sm_dyn" : dyn_button_var.get(),
105
+ "decrisper": False,
106
+ "controlnet_strength": 1.0,
107
+ "add_original_image": False,
108
+ "cfg_rescale": 0.0,
109
+ "noise_schedule": "native",
110
+ }
111
+
112
+ def resize_and_fill(image, max_size=None):
113
+ if max_size is None:
114
+ max_size = get_max_size()
115
+ original_width, original_height = image.size
116
+ if original_width > max_size or original_height > max_size:
117
+ # ๋น„์œจ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ํฌ๊ธฐ ์กฐ์ •
118
+ image.thumbnail((max_size, max_size))
119
+
120
+ # ์ƒˆ ์ด๋ฏธ์ง€ ํฌ๊ธฐ ๊ณ„์‚ฐ
121
+ width, height = image.size
122
+ new_image = Image.new("RGB", (max_size, max_size), "black")
123
+ new_image.paste(image, ((max_size - width) // 2, (max_size - height) // 2))
124
+ return new_image
125
+ else:
126
+ return image
127
+
128
+ def log_error(e, output_file_path="output_file_path"):
129
+ # ํ˜„์žฌ ์‹œ๊ฐ„์„ ์–ป์Šต๋‹ˆ๋‹ค
130
+ current_time = datetime.now().strftime("%m/%d %H:%M:%S")
131
+
132
+ # ์—๋Ÿฌ ๋กœ๊ทธ ๋ฉ”์‹œ์ง€
133
+ error_message = f"#### Error occured at {current_time} ####\nError: {e}\n############################################\n"
134
+
135
+ # ์ง€์ •๋œ ์ถœ๋ ฅ ํด๋”์˜ error_log.txt ํŒŒ์ผ์— ์“ฐ๊ธฐ
136
+ with open(f"error_log.txt", "a") as file:
137
+ file.write(error_message)
138
+
139
+ global access_token
140
+ try:
141
+ zipped_bytes = generate_image(access_token, positive, "nai-diffusion-3", "generate", params)
142
+ d = Path("output_NAI")
143
+ d.mkdir(exist_ok=True)
144
+ zipped = zipfile.ZipFile(io.BytesIO(zipped_bytes))
145
+ image_bytes = zipped.read(zipped.infolist()[0])
146
+ (d / f"{datetime.now().strftime('%Y%m%d_%H%M%S')}.png" ).write_bytes(image_bytes)
147
+ i = Image.open(io.BytesIO(image_bytes))
148
+ i = ImageOps.exif_transpose(i).convert("RGB")
149
+ if temp_clipboard_image is not None:
150
+ temp_clipboard_image.close()
151
+ temp_clipboard_image = i
152
+ i_resized = resize_and_fill(i)
153
+ if 'tk_image' in globals():
154
+ globals()['tk_image'] = None
155
+ tk_image = ImageTk.PhotoImage(i_resized)
156
+ image_label.config(image=tk_image)
157
+ image_label.image = tk_image # ์ฐธ์กฐ ์œ ์ง€
158
+ output_file_path = "output_image.jpg"
159
+ i.save(output_file_path)
160
+ except Exception as e:
161
+ #text_output.insert(tk.END, f"Error: {e}", fg='red')
162
+ log_error(e, "path_to_output_folder")
163
+ time.sleep(random.uniform(3.0, 9.0))
164
+ button.config(state=tk.DISABLED)
165
+ window.event_generate(GENERATE_EVENT, when="tail")
166
+
167
+ time.sleep(random.uniform(1.0, 2.5))
168
+ button.config(state=tk.NORMAL)
169
+ running_flag = False
170
+
171
+ if mac_var.get() and not running_flag:
172
+ random_function()
173
+ time.sleep(random.uniform(5.1, 8.5))
174
+ button.config(state=tk.DISABLED)
175
+ window.event_generate(GENERATE_EVENT, when="tail")
176
+
177
+ def filter_csv(input_file, output_file, _search_strings):
178
+ output_directory = os.getcwd()
179
+ output_file = os.path.join(output_directory, output_file)
180
+ search_strings = [s.strip() for s in _search_strings.split(',')]
181
+ with open(input_file, 'r', newline='', encoding='utf-8') as f_in, \
182
+ open(output_file, 'w', newline='', encoding='utf-8') as f_out:
183
+ reader = csv.reader(f_in)
184
+ writer = csv.writer(f_out)
185
+ writer_count = 0
186
+ for row in reader:
187
+ if all(search_str in value for search_str in search_strings for value in row):
188
+ writer.writerow(row)
189
+ writer_count += 1
190
+ return writer_count
191
+
192
+ def open_file():
193
+ initial_dir = os.getcwd()
194
+ filepath = filedialog.askopenfilename(
195
+ initialdir=initial_dir,
196
+ filetypes=[("CSV Files", "*.csv")]
197
+ )
198
+ if filepath:
199
+ entry_file_path.delete(0, tk.END)
200
+ entry_file_path.insert(0, filepath)
201
+
202
+ def search():
203
+ global total_rows, cached_rows # cached_rows๋ฅผ global๋กœ ์„ ์–ธ
204
+ input_file = entry_file_path.get()
205
+ keywords = entry_keyword.get()
206
+
207
+ output_file = 'txt2img_temp_prompt.csv'
208
+ writer_count = filter_csv(input_file, output_file, keywords)
209
+ total_rows = writer_count
210
+ total_rows_count_label.config(text=f".csv ๋‚ด ํ”„๋กฌํ”„ํŠธ ํ–‰: {writer_count}", fg="blue")
211
+ text_output.insert(tk.END, f"์ด {writer_count}๊ฐœ์˜ ๋ฌธ์ž์—ด์ด ๊ฒ€์ƒ‰๋˜์–ด ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.\n")
212
+
213
+ # ๊ฒ€์ƒ‰ ํ›„ cached_rows ์ดˆ๊ธฐํ™”
214
+ cached_rows = []
215
+
216
+ def exclude():
217
+ global total_rows, cached_rows # cached_rows๋ฅผ global๋กœ ์„ ์–ธ
218
+ input_file = entry_file_path.get()
219
+ keywords = entry_keyword.get()
220
+ output_file = 'txt2img_temp_prompt.csv'
221
+ keyword_label.config(text="๊ฒ€์ƒ‰ํ•  ํ‚ค์›Œ๋“œ: ")
222
+
223
+ output_directory = os.getcwd()
224
+ output_file = os.path.join(output_directory, output_file)
225
+ search_strings = [s.strip() for s in keywords.split(',')]
226
+
227
+ with open(input_file, 'r', newline='', encoding='utf-8') as f_in, \
228
+ open(output_file, 'w', newline='', encoding='utf-8') as f_out:
229
+ reader = csv.reader(f_in)
230
+ writer = csv.writer(f_out)
231
+ writer_count = 0
232
+ for row in reader:
233
+ if not any(search_str in value for search_str in search_strings for value in row):
234
+ writer.writerow(row)
235
+ writer_count += 1
236
+ total_rows = writer_count
237
+ total_rows_count_label.config(text=f".csv ๋‚ด ํ”„๋กฌํ”„ํŠธ ํ–‰: {writer_count}", fg="red")
238
+ text_output.insert(tk.END, f"์ด {writer_count}๊ฐœ์˜ ๋ฌธ์ž์—ด์ด ๊ฒ€์ƒ‰๋˜์–ด ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.\n")
239
+
240
+ # ์ œ์™ธ ํ›„ cached_rows ์ดˆ๊ธฐํ™”
241
+ cached_rows = []
242
+
243
+ def copy_image_to_clipboard():
244
+ global temp_clipboard_image
245
+ image = temp_clipboard_image
246
+ output = BytesIO()
247
+ image.convert('RGB').save(output, format='BMP')
248
+ data = output.getvalue()[14:] # BMP ํŒŒ์ผ ํ—ค๋” ์ œ๊ฑฐ
249
+ output.close()
250
+
251
+ win32clipboard.OpenClipboard()
252
+ win32clipboard.EmptyClipboard()
253
+ win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data)
254
+ win32clipboard.CloseClipboard()
255
+
256
+ def reset():
257
+ cached_rows = None
258
+ entry_file_path.delete(0, tk.END)
259
+ entry_keyword.delete(0, tk.END)
260
+ entry_deep_search.delete(0, tk.END)
261
+ text_output.delete('1.0', tk.END)
262
+
263
+ def random_function():
264
+ global last_deep_search_keywords, cached_rows, last_selected_row_keywords, top_100_keywords, previous_artist, top_100_counts
265
+ current_deep_search_keywords = entry_deep_search.get().strip()
266
+ auto_hide_keywords = entry_auto_hide.get().split(',')
267
+ auto_hide_keywords = [keyword.strip() for keyword in auto_hide_keywords if keyword.strip()]
268
+ current_artist = None
269
+
270
+ curly_brackets_keywords = re.findall(r'\{([^}]+)\}', current_deep_search_keywords)
271
+ # ๊ฐ ๋ธŒ๋ž˜ํ‚ท ๋‚ด ํ‚ค์›Œ๋“œ ๊ทธ๋ฃน์„ ์ฒ˜๋ฆฌํ•˜์—ฌ ์™„๋ฒฝ ์ผ์น˜ ํ‚ค์›Œ๋“œ์™€ ์ผ๋ฐ˜ ํ‚ค์›Œ๋“œ๋ฅผ ๊ตฌ๋ถ„
272
+ processed_keywords = []
273
+ for group in curly_brackets_keywords:
274
+ perfect_match_group = [kw[1:].strip() for kw in group.split('|') if kw.startswith('*')]
275
+ regular_group = [kw.strip() for kw in group.split('|') if not kw.startswith('*')]
276
+ processed_keywords.append((perfect_match_group, regular_group))
277
+
278
+ modified_deep_search_keywords = re.sub(r'\{[^}]+\}', '', current_deep_search_keywords)
279
+
280
+ # ๋‚จ์€ ํ‚ค์›Œ๋“œ๋“ค์„ ์‰ผํ‘œ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฒ˜๋ฆฌ
281
+ remaining_keywords = [kw.strip() for kw in modified_deep_search_keywords.split(',') if kw.strip()]
282
+ perfect_match_keywords = [kw[1:].strip() for kw in remaining_keywords if kw.startswith('*')]
283
+
284
+ # exclude_keywords์™€ include_keywords ์ •์˜
285
+ exclude_keywords = [kw[1:].strip() for kw in remaining_keywords if kw.startswith('~') and not kw[1:].startswith('*')]
286
+ include_keywords = [kw for kw in remaining_keywords if not kw.startswith('~') and not kw.startswith('*')]
287
+
288
+ if current_deep_search_keywords != last_deep_search_keywords or not cached_rows:
289
+ entry_auto_hide.delete(0, tk.END)
290
+ entry_auto_hide.insert(tk.END, 'monochrome, doujin cover, bad source, censored, bar censor, photoshop (medium)')
291
+ with open('txt2img_temp_prompt.csv', 'r', newline='', encoding='utf-8') as f:
292
+ reader = csv.reader(f)
293
+ rows = []
294
+ for row in reader:
295
+ if all(re.search(r'(?:^|, )' + re.escape(kw) + r'(?:,|$)', ', '.join(row)) for kw in perfect_match_keywords) \
296
+ and not any(exclude in cell for exclude in exclude_keywords for cell in row) \
297
+ and all(include in cell for include in include_keywords for cell in row):
298
+ # '{}' ์•ˆ์˜ ํ‚ค์›Œ๋“œ ์ฒ˜๋ฆฌ
299
+ if all(any(re.search(r'(?:^|, )' + re.escape(kw) + r'(?:,|$)', ', '.join(cell)) for kw in perfect_group) or
300
+ any(kw in cell for kw in regular_group) for perfect_group, regular_group in processed_keywords for cell in row):
301
+ rows.append(row)
302
+ cached_rows = rows
303
+
304
+ last_deep_search_keywords = current_deep_search_keywords
305
+ if not toggle_prompt_var.get(): text_output.delete('1.0', tk.END)
306
+
307
+ if random_artist_var.get():
308
+ if(not entry_fixed_prompt.get()): entry_fixed_prompt.insert(tk.END,'1girl')
309
+
310
+ if not os.path.exists("counting_result.txt"):
311
+ keyword_counts = analyze_cached_rows(cached_rows)
312
+ excluded_keywords = set(whitelist[:2974])
313
+ with open("counting_result.txt", "w") as file:
314
+ for keyword, count in sorted(keyword_counts.items(), key=lambda item: item[1], reverse=True):
315
+ if keyword not in excluded_keywords and keyword in afilter_30000:
316
+ file.write(f"{keyword}: {count}\n")
317
+ with open("counting_result.txt", "r") as file:
318
+ lines = file.readlines()
319
+ top_100_data = [
320
+ (line.split(":")[0].strip(), int(line.split(":")[1].strip()))
321
+ for line in lines[:3000]
322
+ if line.split(":")[0].strip() in afilter_30000[:8528]
323
+ ]
324
+ top_100_keywords, top_100_counts = zip(*top_100_data) if top_100_data else ([], [])
325
+ elif (not top_100_keywords):
326
+ with open("counting_result.txt", "r") as file:
327
+ lines = file.readlines()
328
+ top_100_data = [
329
+ (line.split(":")[0].strip(), int(line.split(":")[1].strip()))
330
+ for line in lines[:3000]
331
+ if line.split(":")[0].strip() in afilter_30000[:8528]
332
+ ]
333
+ top_100_keywords, top_100_counts = zip(*top_100_data) if top_100_data else ([], [])
334
+
335
+ formatted_artist_random_keyword = []
336
+ if top_100_keywords:
337
+ temp_keyword = []
338
+ temp_keyword += top_100_keywords
339
+ whatthefuck = random.random()
340
+ print(whatthefuck)
341
+ if(whatthefuck > 0.9):
342
+ for i in range(4):
343
+ random_keyword = random.choice(temp_keyword)
344
+ temp_keyword.remove(random_keyword)
345
+ if(i == 0): formatted_artist_random_keyword = "{{{artist:"+random_keyword+"}}}"
346
+ if(i == 1): formatted_artist_random_keyword += ",{artist:"+random_keyword+"}"
347
+ if(i == 2): formatted_artist_random_keyword += ",artist:"+random_keyword
348
+ if(i == 3): formatted_artist_random_keyword += ",[[artist:"+random_keyword+"]]"
349
+ elif(whatthefuck > 0.7):
350
+ for i in range(3):
351
+ random_keyword = random.choice(temp_keyword)
352
+ temp_keyword.remove(random_keyword)
353
+ if(i == 0): formatted_artist_random_keyword = "{{{artist:"+random_keyword+"}}}"
354
+ if(i == 1): formatted_artist_random_keyword += ",{artist:"+random_keyword+"}"
355
+ if(i == 2): formatted_artist_random_keyword += ",[[artist:"+random_keyword+"]]"
356
+ elif(whatthefuck > 0.45):
357
+ for i in range(2):
358
+ random_keyword = random.choice(temp_keyword)
359
+ temp_keyword.remove(random_keyword)
360
+ if(i == 0): formatted_artist_random_keyword = "{{{artist:"+random_keyword+"}}}"
361
+ if(i == 2): formatted_artist_random_keyword += ",[[artist:"+random_keyword+"]]"
362
+ else:
363
+ random_keyword = random.choice(temp_keyword)
364
+ temp_keyword.remove(random_keyword)
365
+ formatted_artist_random_keyword = "{{artist:"+random_keyword+"}}"
366
+ current_artist = formatted_artist_random_keyword
367
+ print(formatted_artist_random_keyword)
368
+ if not top_100_keywords: random_artist_var.set(0)
369
+ else:
370
+ formatted_artist_random_keyword = f"์ž‘๊ฐ€ ํ‚ค์›Œ๋“œ๊ฐ€ ์—†์Œ!!"
371
+
372
+ if cached_rows:
373
+ if toggle_prompt_var.get() and last_selected_row_keywords:
374
+ random_row_keywords = text_output.get("1.0", "end-1c").split(',')
375
+ #random_row_keywords[-1].strip()
376
+ if random_row_keywords[0]=='': random_row_keywords = last_selected_row_keywords
377
+ text_output.delete('1.0', tk.END)
378
+ else:
379
+ random_index = random.randint(0, len(cached_rows) - 1)
380
+ random_row = cached_rows.pop(random_index)
381
+ random_row_keywords = [keyword.strip() for keyword in random_row[0].split(',')]
382
+ last_selected_row_keywords = random_row_keywords
383
+
384
+ if(entry_fixed_prompt.get()):
385
+ entry_text_keywords = entry_fixed_prompt.get()
386
+ if(',' not in entry_text_keywords[-2:]): entry_text_keywords += ','
387
+ entry_text_keywords = entry_text_keywords.split(',')
388
+ entry_text_keywords = [kw.strip() for kw in entry_text_keywords if kw.strip()]
389
+
390
+ temp_first_keywords = []
391
+ #print("1 :", temp_first_keywords)
392
+
393
+ # entry_text_keywords์˜ ๋ชจ๋“  ํ‚ค์›Œ๋“œ๋ฅผ temp_first_keywords์— ์ถ”๊ฐ€
394
+ for et_kw in entry_text_keywords:
395
+ 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):
396
+ temp_first_keywords.append(et_kw)
397
+
398
+ # 'boy' ํ‚ค์›Œ๋“œ ์ฒ˜๋ฆฌ
399
+ boy_keywords = [kw for kw in random_row_keywords if 'boy' in kw and len(kw) <= 7]
400
+
401
+ # 'girl' ํ‚ค์›Œ๋“œ ์ฒ˜๋ฆฌ ๋ฐ ์œ„์น˜ ์กฐ์ •
402
+ girl_keywords = []
403
+ if 'girl' in entry_text_keywords[0] and len(entry_text_keywords[0]) <= 7:
404
+ girl_keywords = [kw for kw in random_row_keywords if 'girl' in kw and len(kw) <= 7]
405
+
406
+ # random_row_keywords์—์„œ boy์™€ girl ํ‚ค์›Œ๋“œ ์ œ๊ฑฐ
407
+ for kw in boy_keywords + girl_keywords:
408
+ if kw in random_row_keywords:
409
+ random_row_keywords.remove(kw)
410
+
411
+ for kw in temp_first_keywords:
412
+ if kw in random_row_keywords:
413
+ random_row_keywords.remove(kw)
414
+
415
+
416
+ # temp_first_keywords์— boy์™€ girl ํ‚ค์›Œ๋“œ๋ฅผ ์ ์ ˆํ•œ ์œ„์น˜์— ์ถ”๊ฐ€
417
+ if(girl_keywords and 'girl' in temp_first_keywords[0]): temp_first_keywords.pop(0)
418
+ print(wildcard_var.get())
419
+ if(wildcard_var2.get() == 1):
420
+ temp_len = len(girl_keywords)
421
+ girl_keywords.append(get_random_keyword('character'))
422
+ if(wildcard_var.get() == 1):
423
+ if(wildcard_var2.get() == 1): girl_keywords.insert(temp_len+1,get_random_keyword('artist'))
424
+ else: girl_keywords.append(get_random_keyword('artist'))
425
+ temp_first_keywords = boy_keywords + girl_keywords + temp_first_keywords
426
+ #print("2 :", temp_first_keywords)
427
+
428
+ if remove_artist_var.get():
429
+ for keyword in random_row_keywords:
430
+ if keyword in afilter_30000:
431
+ random_row_keywords.remove(keyword)
432
+ temp_rm = []
433
+ if rm_characteristic_var.get():
434
+ for keyword in random_row_keywords:
435
+ if keyword in bag_of_tags or "(" in keyword:
436
+ random_row_keywords.remove(keyword)
437
+ temp_rm.append(keyword)
438
+ for keyword in random_row_keywords:
439
+ if "(" in keyword:
440
+ random_row_keywords.remove(keyword)
441
+ temp_rm.append(keyword)
442
+ print('removed : ',temp_rm)
443
+
444
+ for keyword in random_row_keywords[:]: # ๋ณต์‚ฌ๋ณธ์„ ์ˆœํšŒํ•˜์—ฌ ์›๋ณธ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆ˜์ •
445
+ if " (" in keyword:
446
+ temp_first_keywords.append(keyword)
447
+ random_row_keywords.remove(keyword)
448
+ else:
449
+ if not random_row_keywords: random_row_keywords = last_selected_row_keywords
450
+ temp_first_keywords = []
451
+ for keyword in random_row_keywords[:]: # ๋ณต์‚ฌ๋ณธ์„ ์ˆœํšŒํ•˜์—ฌ ์›๋ณธ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆ˜์ •
452
+ if " (" in keyword:
453
+ temp_first_keywords.append(keyword)
454
+ random_row_keywords.remove(keyword)
455
+
456
+ last_selected_row_keywords = random_row_keywords
457
+ #print("3 :", temp_first_keywords)
458
+ if random_artist_var.get():
459
+ temp_first_keywords.append(formatted_artist_random_keyword)
460
+ #print("4 :", temp_first_keywords)
461
+ if (previous_artist and previous_artist in temp_first_keywords): temp_first_keywords.remove(previous_artist)
462
+ if (current_artist is (not None)):
463
+ for i in range (len(current_artist)):
464
+ previous_artist += current_artist[i]
465
+ random_row_keywords = temp_first_keywords + random_row_keywords
466
+ #print("5 :", random_row_keywords)
467
+ elif toggle_prompt_var.get(): random_row_keywords = temp_first_keywords + random_row_keywords
468
+ else: random_row_keywords = temp_first_keywords + random_row_keywords
469
+
470
+ patterns = [r'\b{}\b'.format(re.escape(keyword)) for keyword in auto_hide_keywords]
471
+
472
+ for pattern in patterns:
473
+ random_row_keywords = [re.sub(pattern + '(, )?', '', keyword) for keyword in random_row_keywords]
474
+ random_row_keywords = [re.sub('(?<=, )' + pattern, '', keyword) for keyword in random_row_keywords]
475
+
476
+ if entry_fixed_prompt_after.get():
477
+ entry_after_text = entry_fixed_prompt_after.get().strip().split(',')
478
+ for at_kw in entry_after_text:
479
+ if at_kw not in random_row_keywords and ' '+at_kw not in random_row_keywords:
480
+ random_row_keywords.append(at_kw)
481
+
482
+ random_row_keywords = [keyword.strip(', ') for keyword in random_row_keywords]
483
+ random_row_keywords = [keyword for keyword in random_row_keywords if keyword]
484
+ #print(random_row_keywords)
485
+ text_output.insert(tk.END, f"{', '.join(random_row_keywords)}")
486
+ if auto_copy_var.get():
487
+ copy_to_clipboard()
488
+ else:
489
+ text_output.insert(tk.END, "๊ฒ€์ƒ‰ ์กฐ๊ฑด์— ๋งž๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๊ฑฐ๋‚˜ CSV ํŒŒ์ผ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.\n")
490
+
491
+ cached_rows_count_label.config(text=f"์‹ฌ์ธต๊ฒ€์ƒ‰ ํ”„๋กฌํ”„ํŠธ ํ–‰: {len(cached_rows)}")
492
+
493
+ def add_low_frequency_keywords():
494
+ global keyword_counts, most_common_count
495
+ keyword_counts = analyze_cached_rows(cached_rows)
496
+ if not keyword_counts: # keyword_counts๊ฐ€ ๋น„์–ด์žˆ๋Š” ๊ฒฝ์šฐ ํ•จ์ˆ˜๋ฅผ ๋น ์ ธ๋‚˜์˜ต๋‹ˆ๋‹ค.
497
+ return
498
+
499
+ # ๊ฐ€์žฅ ํ”ํ•œ ํ‚ค์›Œ๋“œ์˜ ๋นˆ๋„์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
500
+ most_common_count = keyword_counts.most_common(1)[0][1]
501
+
502
+ # ์กฐ๊ฑด์— ๋งž๋Š” ํ‚ค์›Œ๋“œ๋“ค์„ ์ฐพ์Šต๋‹ˆ๋‹ค.
503
+ low_freq_keywords = [keyword for keyword, count in keyword_counts.items()
504
+ if keyword not in last_deep_search_keywords and keyword not in whitelist and count / most_common_count <= 0.05]
505
+
506
+ # ์ž๋™ ์ˆจ๊น€ ํ‚ค์›Œ๋“œ ์ž…๋ ฅ์ฐฝ์— ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
507
+ existing_keywords = entry_auto_hide.get().split(',')
508
+ existing_keywords = [keyword.strip() for keyword in existing_keywords if keyword.strip()] # ๊ณต๋ฐฑ ์ œ๊ฑฐ ๋ฐ ๋นˆ ๋ฌธ์ž์—ด ์ œ๊ฑฐ
509
+
510
+ # ๊ธฐ์กด ํ‚ค์›Œ๋“œ์— ์ƒˆ๋กœ์šด ์ €๋นˆ๋„ ํ‚ค์›Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
511
+ updated_keywords = existing_keywords + low_freq_keywords
512
+ unique_keywords = list(set(updated_keywords)) # ์ค‘๋ณต ์ œ๊ฑฐ
513
+ for keyword in unique_keywords:
514
+ if(keyword in afilter_30000):
515
+ unique_keywords.remove(keyword)
516
+ entry_auto_hide.delete(0, tk.END)
517
+ entry_auto_hide.insert(0, ', '.join(unique_keywords))
518
+
519
+ def copy_to_clipboard():
520
+ window.clipboard_clear()
521
+ entry_text = entry_fixed_prompt.get()
522
+ if(',' not in entry_text and entry_text): entry_text += ','
523
+ combined_text = text_output.get("1.0", tk.END)
524
+ window.clipboard_append(combined_text)
525
+
526
+ def exit_program():
527
+ window.destroy()
528
+
529
+ def save_settings():
530
+ global NAI_ID
531
+ with open('app_settings.txt', 'w', encoding='utf-8') as f: #1
532
+ if(len(entry_file_path.get()) > 4):
533
+ f.write(entry_file_path.get() + '\n')
534
+ else: f.write(" "+'\n')
535
+ if(len(entry_keyword.get()) > 3): #2
536
+ f.write(entry_keyword.get() + '\n')
537
+ else: f.write(" "+'\n')
538
+ if(len(entry_deep_search.get()) > 3): #3
539
+ f.write(entry_deep_search.get() + '\n')
540
+ else: f.write(" "+'\n')
541
+ if(len(entry_fixed_prompt.get()) > 4): #4
542
+ f.write(entry_fixed_prompt.get() + '\n')
543
+ else: f.write(" "+'\n')
544
+ if(len(entry_fixed_prompt_after.get()) > 4): #5
545
+ f.write(entry_fixed_prompt_after.get() + '\n')
546
+ else: f.write(" "+'\n')
547
+ if(len(entry_auto_hide.get()) > 3): #6
548
+ f.write(entry_auto_hide.get() + '\n')
549
+ else: f.write(" "+'\n')
550
+ if(len(negative_text.get("1.0", tk.END)) > 4): #7
551
+ f.write(negative_text.get("1.0", tk.END))
552
+ else: f.write(" "+'\n')
553
+ if(NAI_ID): f.write(NAI_ID + '\n' ) #ํ•ญ์ƒ ๋งˆ์ง€๋ง‰์— ์˜ค๋„๋ก ๊ธฐ์–ต #8
554
+
555
+ def load_settings():
556
+ NAI_ID = ""
557
+ if os.path.exists('app_settings.txt'):
558
+ with open('app_settings.txt', 'r', encoding='utf-8') as f:
559
+ settings = f.readlines()
560
+ entry_file_path.insert(0, settings[0].strip())
561
+ entry_keyword.insert(0, settings[1].strip())
562
+ entry_deep_search.insert(0, settings[2].strip())
563
+ entry_fixed_prompt.insert(0, settings[3].strip())
564
+ entry_fixed_prompt_after.insert(0, settings[4].strip())
565
+ entry_auto_hide.insert(0, settings[5].strip())
566
+ if(len(settings)>=7):
567
+ negative_text.insert(tk.END, settings[6].strip())
568
+ if(len(settings)>=8):
569
+ NAI_ID = settings[7].strip() #ํ•ญ์ƒ ๋งˆ์ง€๋ง‰์— ์˜ค๋„๋ก ๊ธฐ์–ต
570
+ return NAI_ID
571
+
572
+ def open_prompt_window():
573
+ # ์ƒˆ ์ฐฝ ์ƒ์„ฑ
574
+ prompt_window = tk.Toplevel(window)
575
+ prompt_title = f"{entry_keyword.get()}+{last_deep_search_keywords}" if last_deep_search_keywords else "์ถ”์ฒœ ํ”„๋กฌํ”„ํŠธ"
576
+ prompt_window.title(prompt_title)
577
+
578
+
579
+ # ์ฒซ ๋ฒˆ์งธ Text Output Box ์„ค์ •
580
+ text_output1 = tk.Text(prompt_window, height=10, width=50)
581
+ text_output1.pack(padx=10, pady=10)
582
+
583
+ # ๊ตต์€ ๊ธ€์”จ ์Šคํƒ€์ผ ํƒœ๊ทธ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
584
+ text_output1.tag_configure('bold', font=('Arial', 10, 'bold'))
585
+
586
+ # ๋‘ ๋ฒˆ์งธ Text Output Box ์„ค์ •
587
+ text_output2 = tk.Text(prompt_window, height=10, width=50)
588
+ text_output2.pack(padx=10, pady=10)
589
+
590
+ # ์„ธ ๋ฒˆ์งธ Text Output Box ์„ค์ •
591
+ text_output3 = tk.Text(prompt_window, height=10, width=50)
592
+ text_output3.pack(padx=10, pady=10)
593
+
594
+ # cached_rows ๋ถ„์„
595
+ keyword_counts = analyze_cached_rows(cached_rows)
596
+
597
+ # ๊ฐ€์žฅ ๋†’์€ count ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
598
+ most_common_count = keyword_counts.most_common(1)[0][1] if keyword_counts else 0
599
+
600
+ # text_output1์— ๊ฐ€์žฅ ํ”ํ•œ ํ‚ค์›Œ๋“œ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ , ์กฐ๊ฑด์— ๋”ฐ๋ผ ๊ตต๊ฒŒ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
601
+ for keyword, count in keyword_counts.most_common(50):
602
+ if count / most_common_count >= 0.5: # count๊ฐ€ ๊ฐ€์žฅ ๋†’์€ ํ‚ค์›Œ๋“œ ๋Œ€๋น„ 60% ์ด์ƒ์ธ ๊ฒฝ์šฐ
603
+ text_output1.insert(tk.END, f"{keyword}, ", 'bold')
604
+ else:
605
+ text_output1.insert(tk.END, f"{keyword}, ")
606
+
607
+ # text_output2์— ๋ชจ๋“  ํ‚ค์›Œ๋“œ์™€ ๋นˆ๋„์ˆ˜ ์ถœ๋ ฅ
608
+ for keyword, count in keyword_counts.most_common(200):
609
+ text_output2.insert(tk.END, f"{keyword}: {count}, ")
610
+
611
+ excluded_keywords = set(whitelist[:2974])
612
+ artist_count = 0
613
+ with open("counting_result.txt", "w") as file:
614
+ for keyword, count in sorted(keyword_counts.items(), key=lambda item: item[1], reverse=True):
615
+ if keyword not in excluded_keywords and keyword in afilter_30000:
616
+ file.write(f"{keyword}: {count}\n")
617
+ if(artist_count < 150):
618
+ text_output3.insert(tk.END, f"{keyword}: {count}, ")
619
+ artist_count += 1
620
+
621
+ # ๋‹ซ๊ธฐ ๋ฒ„ํŠผ ์„ค์ •
622
+ close_button = tk.Button(prompt_window, text="๋‹ซ๊ธฐ", command=prompt_window.destroy)
623
+ close_button.pack(pady=10)
624
+
625
+ def analyze_cached_rows(cached_rows):
626
+ global top_100_keywords
627
+ top_100_keywords = []
628
+ counts = Counter()
629
+ for row in cached_rows:
630
+ substrings = [substring.strip() for value in row for substring in value.split(',') if substring.strip()]
631
+ counts.update(substrings)
632
+ return counts
633
+
634
+ def exit_program():
635
+ save_settings()
636
+ window.destroy()
637
+
638
+ def on_ctrl_enter(event):
639
+ random_function()
640
+
641
+ def on_shift_enter(event):
642
+ random_function()
643
+ copy_to_clipboard()
644
+
645
+ def export_csv():
646
+ source_file = os.path.join(os.getcwd(), 'txt2img_temp_prompt.csv')
647
+ if not os.path.exists(source_file):
648
+ print("์†Œ์Šค ํŒŒ์ผ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.")
649
+ return
650
+
651
+ # ๊ธฐ๋ณธ ํŒŒ์ผ ์ด๋ฆ„์„ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ํ‚ค์›Œ๋“œ๋กœ ์„ค์ •
652
+ default_filename = f"{entry_keyword.get()}.csv" if entry_keyword.get() else "exported.csv"
653
+ file_types = [('CSV ํŒŒ์ผ', '*.csv')]
654
+ dest_file = filedialog.asksaveasfilename(defaultextension='.csv', filetypes=file_types, initialfile=default_filename)
655
+
656
+ if dest_file: # ์‚ฌ์šฉ์ž๊ฐ€ ํŒŒ์ผ ์ด๋ฆ„์„ ์„ ํƒํ–ˆ์„ ๊ฒฝ์šฐ
657
+ import shutil
658
+ shutil.copy(source_file, dest_file)
659
+ print(f"ํŒŒ์ผ์ด ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค: {dest_file}")
660
+
661
+ def export_csv_search():
662
+
663
+ if not cached_rows:
664
+ print("๋น„์–ด์žˆ๋Š” ํ”„๋กฌํ”„ํŠธํ–‰.")
665
+ return
666
+
667
+ # ๊ธฐ๋ณธ ํŒŒ์ผ ์ด๋ฆ„์„ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ํ‚ค์›Œ๋“œ๋กœ ์„ค์ •
668
+ default_filename = f"{entry_keyword.get()}.csv" if entry_keyword.get() else "exported.csv"
669
+ file_types = [('CSV ํŒŒ์ผ', '*.csv')]
670
+ dest_file = filedialog.asksaveasfilename(defaultextension='.csv', filetypes=file_types, initialfile=default_filename)
671
+
672
+ if dest_file: # ์‚ฌ์šฉ์ž๊ฐ€ ํŒŒ์ผ ์œ„์น˜๋ฅผ ์„ ํƒํ–ˆ๋‹ค๋ฉด
673
+ with open(dest_file, 'w', newline='', encoding='utf-8') as file:
674
+ writer = csv.writer(file)
675
+ for row in cached_rows:
676
+ writer.writerow(row) # ๊ฐ ํ–‰์„ csv ํŒŒ์ผ์— ์“ด๋‹ค
677
+
678
+ def simulate_shortcuts():
679
+ global listener, on_press_flag
680
+
681
+ on_press_flag = True
682
+ random_function()
683
+ on_press_flag = False
684
+ try:
685
+ current_keys.clear()
686
+ current_keys.add(keyboard.Key.ctrl_l)
687
+ except KeyError:
688
+ pass
689
+
690
+ def on_activate_simulate_shortcuts():
691
+ simulate_shortcuts()
692
+
693
+ def for_canonical(f):
694
+ return lambda k: f(listener.canonical(k))
695
+
696
+ def start_keyboard_listener():
697
+ global listener
698
+ listener = keyboard.Listener(on_press=on_press, on_release=on_release)
699
+ listener.start()
700
+
701
+ def on_press(key):
702
+ global on_press_flag
703
+
704
+ current_keys.add(key)
705
+
706
+ # Ctrl + ` ์กฐํ•ฉ ๊ฐ์ง€
707
+ if keyboard.Key.ctrl_l in current_keys:
708
+ if any(k.vk == 192 for k in current_keys if hasattr(k, 'vk')):
709
+ on_press_flag = True
710
+ simulate_shortcuts()
711
+
712
+ def on_release(key):
713
+ try:
714
+ current_keys.remove(key)
715
+ except KeyError:
716
+ pass
717
+
718
+ def v_automatic(save_position, prompt_position):
719
+ # ํ”„๋กฌํ”„ํŠธ ์ฐฝ ํด๋ฆญ
720
+ copy_to_clipboard()
721
+ pyautogui.click(prompt_position)
722
+ time.sleep(0.5)
723
+ random_function()
724
+ pyautogui.hotkey('ctrl', 'a', 'v','Right','Right','Enter')
725
+ time.sleep(0.5)
726
+ pyautogui.click(save_position)
727
+
728
+ def start_automation(save_position, prompt_position, label, window_to_close, automation_event):
729
+ def automation_task():
730
+ while automation_event.is_set():
731
+ random_delay = random.uniform(17.5, 23.5)
732
+ next_click_time = time.time() + random_delay
733
+ while time.time() < next_click_time and automation_event.is_set():
734
+ time_remaining = max(next_click_time - time.time(), 0)
735
+ label.config(text=f"๋‹ค์Œ ํด๋ฆญ๊นŒ์ง€: {time_remaining:.2f}์ดˆ")
736
+ time.sleep(0.1)
737
+ if automation_event.is_set():
738
+ v_automatic(save_position, prompt_position)
739
+
740
+ automation_thread = threading.Thread(target=automation_task, daemon=True)
741
+ automation_thread.start()
742
+ random_function()
743
+
744
+ def stop_automation():
745
+ automation_event.clear()
746
+ window_to_close.destroy()
747
+
748
+ window_to_close.protocol("WM_DELETE_WINDOW", stop_automation)
749
+
750
+ def stop_automation(window_to_close, automation_event, start_button, stop_button):
751
+ automation_event.clear() # Stop the automation task
752
+ start_button['state'] = 'normal' # Enable the start button
753
+ stop_button['state'] = 'disabled' # Disable the stop button
754
+ window_to_close.destroy() # Close the automation window
755
+ window.deiconify()
756
+
757
+ # ๋ผ๋ฒจ์„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ•จ์ˆ˜
758
+ def update_label(label, text):
759
+ def task():
760
+ label.config(text=text)
761
+ label.after(1000, task) # ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ UI ์—…๋ฐ์ดํŠธ
762
+
763
+ def open_automation_window():
764
+ window.iconify()
765
+ automation_event = threading.Event()
766
+ automation_event.set() # Enable the automation event
767
+ auto_window = tk.Toplevel(window)
768
+ auto_window.title("์ž๋™ํ™” ์„ค์ •")
769
+ auto_window.geometry("300x200") # ์ฐฝ ํฌ๊ธฐ ์กฐ์ •
770
+ auto_window.attributes('-topmost', True) # ์ฐฝ์„ ํ•ญ์ƒ ๋งจ ์œ„์— ์œ„์น˜
771
+ auto_window.focus_force() # ์ฐฝ ์—ด๋ฆด ๋•Œ ํฌ์ปค์Šค ๊ฐ•์ œ ์ด๋™
772
+
773
+ save_position = None
774
+ prompt_position = None
775
+ automation_running = threading.Event()
776
+
777
+ def get_mouse_position(event=None):
778
+ nonlocal save_position, prompt_position
779
+ x, y = pyautogui.position()
780
+ if not save_position:
781
+ save_position = (x, y)
782
+ position_label.config(text=f"์ €์žฅ ๋ฒ„ํŠผ์˜ ์ขŒํ‘œ: {x}, {y}\nํ”„๋กฌํ”„ํŠธ ์ฐฝ์˜ ์ขŒํ‘œ: ")
783
+ elif not prompt_position:
784
+ prompt_position = (x, y)
785
+ position_label.config(text=f"์ €์žฅ ๋ฒ„ํŠผ์˜ ์ขŒํ‘œ: {save_position[0]}, {save_position[1]}\nํ”„๋กฌํ”„ํŠธ ์ฐฝ์˜ ์ขŒํ‘œ: {x}, {y}")
786
+ start_button.config(state="normal")
787
+ if save_position and prompt_position:
788
+ start_button.config(state="normal")
789
+ stop_button.config(state="normal")
790
+
791
+
792
+ position_label = tk.Label(auto_window, text="์—”ํ„ฐ๋ฅผ ๋ˆŒ๋Ÿฌ ๋งˆ์šฐ์Šค ์ขŒํ‘œ๋ฅผ ์ €์žฅํ•˜์„ธ์š”\n(ํด๋ฆญ X, 1.์ €์žฅ->2.ํ”„๋กฌํ”„ํŠธ์ฐฝ ์ˆœ์„œ)", justify=tk.LEFT)
793
+ position_label.pack(pady=10)
794
+
795
+ start_button = tk.Button(auto_window, text="์‹œ์ž‘", state="disabled",
796
+ command=lambda: start_automation(save_position, prompt_position, countdown_label, auto_window, automation_event))
797
+ start_button.pack(side=tk.LEFT, fill='x', expand=True)
798
+
799
+ stop_button = tk.Button(auto_window, text="์ค‘์ง€", state="disabled",
800
+ command=lambda: stop_automation(auto_window, automation_event, start_button, stop_button))
801
+ stop_button.pack(side=tk.RIGHT, fill='x', expand=True)
802
+
803
+ countdown_label = tk.Label(auto_window, text="")
804
+ countdown_label.pack(pady=10)
805
+
806
+ auto_window.bind('<Return>', get_mouse_position)
807
+
808
+ def NAI_generation(width, height, button):
809
+ button.config(state=tk.DISABLED)
810
+ positive = text_output.get("1.0", tk.END)
811
+ negative = negative_text.get("1.0", "end-1c").strip()
812
+ thread = threading.Thread(target=generate, args=(width, height, positive, negative, button))
813
+ thread.start()
814
+
815
+ def NAI_setting(button, button_generate):
816
+ global NAI_ID
817
+ NAI_setting_window = tk.Toplevel(window)
818
+ NAI_setting_window_title = "NAI ๋กœ๊ทธ์ธ"
819
+
820
+ def NAI_close():
821
+ NAI_setting_window.destroy()
822
+
823
+ NAI_ID_label = tk.Label(NAI_setting_window, text="NAI ID: ")
824
+ NAI_ID_label.grid(row=0, column=0, columnspan=2, sticky='w')
825
+ entry_NAI_ID = tk.Entry(NAI_setting_window, width=50)
826
+ entry_NAI_ID.grid(row=0, column=1, columnspan=2, padx=100, pady=5, sticky='e')
827
+ if(NAI_ID): entry_NAI_ID.insert(tk.END,NAI_ID)
828
+ NAI_PW_label = tk.Label(NAI_setting_window, text="NAI PW: ")
829
+ NAI_PW_label.grid(row=1, column=0, columnspan=2, sticky='w')
830
+ entry_NAI_PW = tk.Entry(NAI_setting_window, width=50, show="*")
831
+ entry_NAI_PW.grid(row=1, column=1, columnspan=2, padx=100, pady=5, sticky='e')
832
+
833
+ def NAI_connect(button, connect_button):
834
+ global access_token, NAI_ID
835
+ username = entry_NAI_ID.get().strip()
836
+ password = entry_NAI_PW.get().strip()
837
+ access_key = get_access_key(username, password)
838
+ try:
839
+ access_token = login(access_key)
840
+ access_result = requests.get("https://api.novelai.net/user/information", headers={ "Authorization": f"Bearer {access_token}" })
841
+ NAI_State_label.config(text="(๋กœ๊ทธ์ธ ์„ฑ๊ณต, ๋‹ซ๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์ฃผ์„ธ์š”.)", fg="blue")
842
+ button.config(state=tk.DISABLED)
843
+ button_generate.config(state="normal")
844
+ connect_button.config(state=tk.DISABLED)
845
+ NAI_ID = username
846
+ except Exception as e:
847
+ print(e)
848
+ NAI_close()
849
+
850
+ connect_button = tk.Button(NAI_setting_window, text="์—ฐ๊ฒฐ", command=lambda: NAI_connect(button, connect_button))
851
+ connect_button.grid(row=2, column=1, columnspan=2, padx=5, pady=5, sticky='w')
852
+ close_button = tk.Button(NAI_setting_window, text="๋‹ซ๊ธฐ", command=NAI_close)
853
+ close_button.grid(row=2, column=2, columnspan=2, padx=5, pady=5, sticky='w')
854
+ NAI_State_label = tk.Label(NAI_setting_window, text="ํ•ด๋‹น ์ ‘์†๊ธฐ๋Šฅ์€ ์ •์ƒ์ ์ธ ์ ‘์† ํŒจํ„ด์ด ์•„๋‹Œ์  ์ฐธ๊ณ  ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.", fg="red")
855
+ NAI_State_label.grid(row=3, column=1, sticky='ew')
856
+
857
+ def on_resolution_change(*args):
858
+ global NAI_width, NAI_height
859
+ resolution = selected_resolution.get()
860
+ NAI_width, NAI_height = resolution.split(' x ')
861
+
862
+ def on_option_select(value):
863
+ global current_sampler
864
+ current_sampler = value
865
+
866
+ def open_file_explorer():
867
+ output_file_path = "output_NAI"
868
+ if os.path.exists(output_file_path):
869
+ os.startfile(output_file_path)
870
+
871
+ def on_generate_event(event):
872
+ global running_flag
873
+ if not (running_flag):
874
+ NAI_generation(NAI_width, NAI_height, button_generate)
875
+ running_flag = True
876
+
877
+ def random_artist_management():
878
+ global top_100_keywords, top_100_counts, cached_rows
879
+ if not cached_rows: return
880
+ if not (top_100_keywords):
881
+ if not os.path.exists("counting_result.txt"):
882
+ keyword_counts = analyze_cached_rows(cached_rows)
883
+ excluded_keywords = set(whitelist[:2974])
884
+ with open("counting_result.txt", "w") as file:
885
+ for keyword, count in sorted(keyword_counts.items(), key=lambda item: item[1], reverse=True):
886
+ if keyword not in excluded_keywords and keyword in afilter_30000:
887
+ file.write(f"{keyword}: {count}\n")
888
+ with open("counting_result.txt", "r") as file:
889
+ lines = file.readlines()
890
+ top_100_data = [
891
+ (line.split(":")[0].strip(), int(line.split(":")[1].strip()))
892
+ for line in lines[:3000]
893
+ if line.split(":")[0].strip() in afilter_30000[:8528]
894
+ ]
895
+ top_100_keywords, top_100_counts = zip(*top_100_data) if top_100_data else ([], [])
896
+ elif (not top_100_keywords):
897
+ with open("counting_result.txt", "r") as file:
898
+ lines = file.readlines()
899
+ top_100_data = [
900
+ (line.split(":")[0].strip(), int(line.split(":")[1].strip()))
901
+ for line in lines[:3000]
902
+ if line.split(":")[0].strip() in afilter_30000[:8528]
903
+ ]
904
+ top_100_keywords, top_100_counts = zip(*top_100_data) if top_100_data else ([], [])
905
+
906
+ # top_100_keywords ๋‚ด์˜
907
+ # ์ƒˆ ์ฐฝ ์ƒ์„ฑ
908
+ random_artist_window = tk.Toplevel(window)
909
+
910
+ # ์ฒซ ๋ฒˆ์งธ Text Output Box ์„ค์ •
911
+ text_output1 = tk.Text(random_artist_window, height=40, width=50)
912
+ text_output1.pack(padx=10, pady=10)
913
+ for keyword, count in zip(top_100_keywords, top_100_counts):
914
+ text_output1.insert(tk.END, f"{keyword}: {count}\n")
915
+
916
+ def update_lists():
917
+ # Text ์œ„์ ฏ์—์„œ ๋‚ด์šฉ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
918
+ content = text_output1.get("1.0", tk.END)
919
+ lines = content.strip().split("\n") # ์ค„๋ฐ”๊ฟˆ์œผ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
920
+
921
+ # ๊ฐฑ์‹ ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋‘ ๊ฐœ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
922
+ updated_keywords = []
923
+ updated_counts = []
924
+
925
+ # ๊ฐ ์ค„์„ ์ฒ˜๋ฆฌ๏ฟฝ๏ฟฝ๏ฟฝ์—ฌ ๋ฆฌ์ŠคํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
926
+ for line in lines:
927
+ if line: # ๋นˆ ์ค„์ด ์•„๋‹Œ ๊ฒฝ์šฐ์—๋งŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
928
+ parts = line.split(":")
929
+ if len(parts) == 2: # "ํ‚ค์›Œ๋“œ: ์นด์šดํŠธ" ํ˜•์‹์ด ๋งž๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
930
+ updated_keywords.append(parts[0].strip())
931
+ updated_counts.append(int(parts[1].strip()))
932
+
933
+ # ์ „์—ญ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค.
934
+ global top_100_keywords, top_100_counts
935
+ top_100_keywords = updated_keywords
936
+ top_100_counts = updated_counts
937
+ with open("random_artist_keywords_"+str(len(top_100_keywords))+".txt", "w") as f:
938
+ for keyword in updated_keywords:
939
+ f.write('100: artist:'+keyword + "\n")
940
+
941
+ # ๋ฒ„ํŠผ๋“ค์„ ๋‹ด์„ ํ”„๋ ˆ์ž„ ์ƒ์„ฑ
942
+ buttons_frame = tk.Frame(random_artist_window)
943
+ buttons_frame.pack(pady=10)
944
+
945
+ # '์ €์žฅ' ๋ฒ„ํŠผ์„ ํ”„๋ ˆ์ž„์˜ ์™ผ์ชฝ์— ๋ฐฐ์น˜
946
+ save_button = tk.Button(buttons_frame, text="์ €์žฅ", command=update_lists)
947
+ save_button.pack(side=tk.LEFT, padx=5)
948
+
949
+ # '๋‹ซ๊ธฐ' ๋ฒ„ํŠผ์„ ํ”„๋ ˆ์ž„์˜ ์˜ค๋ฅธ์ชฝ์— ๋ฐฐ์น˜
950
+ close_button = tk.Button(buttons_frame, text="๋‹ซ๊ธฐ", command=random_artist_window.destroy)
951
+ close_button.pack(side=tk.RIGHT, padx=5)
952
+
953
+ random_artist_label = tk.Label(random_artist_window, text='์ž‘๊ฐ€์ด๋ฆ„ ์ด '+str(len(top_100_keywords))+'๊ฐœ, ์ €์žฅ์œ„์น˜: exeํŒŒ์ผ ์œ„์น˜')
954
+ random_artist_label.pack()
955
+
956
+ def open_wildcard_setting():
957
+ # ์ƒˆ ์ฐฝ ์ƒ์„ฑ
958
+ wildcard_window = tk.Toplevel(window)
959
+ wildcard_window.title("์™€์ผ๋“œ ์นด๋“œ ์„ค์ •")
960
+
961
+ # ์ž‘๊ฐ€๋ช… ํŒŒ์ผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
962
+ artist_label = tk.Label(wildcard_window, text="์ž‘๊ฐ€๋ช… ํŒŒ์ผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ->")
963
+ artist_label.grid(row=0, column=0)
964
+ artist_button = tk.Button(wildcard_window, text="์—ด๊ธฐ", command=lambda: load_wildcard(artist_text, wildcard_window))
965
+ artist_button.grid(row=0, column=1)
966
+
967
+ artist_text = tk.Text(wildcard_window, height=15, width=60)
968
+ artist_text.grid(row=1, column=0, columnspan=2)
969
+
970
+ # ์บ๋ฆญํ„ฐ ํŒŒ์ผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
971
+ character_label = tk.Label(wildcard_window, text="์บ๋ฆญํ„ฐ ํŒŒ์ผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ->")
972
+ character_label.grid(row=2, column=0)
973
+ character_button = tk.Button(wildcard_window, text="์—ด๊ธฐ", command=lambda: load_wildcard(character_text, wildcard_window))
974
+ character_button.grid(row=2, column=1)
975
+
976
+ character_text = tk.Text(wildcard_window, height=15, width=60)
977
+ character_text.grid(row=3, column=0, columnspan=2)
978
+
979
+ # ๋ฒ„ํŠผ๋“ค
980
+ buttons_frame = tk.Frame(wildcard_window)
981
+ buttons_frame.grid(row=4, column=0, columnspan=2)
982
+
983
+ text_label = tk.Label(wildcard_window, text="wildcard ๋ฌธ๋ฒ•(์ž‘๊ฐ€):\noffset:wildcard1 150:null (helloworld)\noffset:wildcard2 100:none (goodbye)\n์—†์œผ๋ฉด 100: ์œผ๋กœ ๊ฐ„์ฃผ\noffset/offset ์ดํ•ฉ: wildcard ํ™•๋ฅ ")
984
+ text_label.grid(row=5, column=0,sticky='ew')
985
+ 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...")
986
+ text_label2.grid(row=6, column=0,sticky='ew')
987
+
988
+ load_button = tk.Button(buttons_frame, text="์™€์ผ๋“œ์นด๋“œ ํƒ‘์žฌ", command=lambda: apply_wildcard(artist_text, character_text, wildcard_window))
989
+ load_button.pack(side=tk.LEFT, padx=10)
990
+
991
+ close_button = tk.Button(buttons_frame, text="๋‹ซ๊ธฐ", command=wildcard_window.destroy)
992
+ close_button.pack(side=tk.RIGHT, padx=10)
993
+
994
+ def apply_wildcard(artist_text, character_text, window):
995
+ artist_wildcard_check = artist_text.get("1.0", tk.END)
996
+ if len(artist_wildcard_check) > 5:
997
+ lines = artist_wildcard_check.strip().split("\n")
998
+ akeywords = []
999
+ current_index = 0
1000
+ for line in lines:
1001
+ parts = line.strip().split(':', 1)
1002
+ if len(parts) == 2 and parts[0].strip().isdigit():
1003
+ weight = int(parts[0].strip())
1004
+ else:
1005
+ weight = 100
1006
+ parts = ['100', line.strip()] # '100:'์„ ์•ž์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
1007
+ keyword = parts[1].strip()
1008
+ akeywords.append((current_index, current_index + weight - 1, keyword))
1009
+ current_index += weight
1010
+ global artist_wildcard
1011
+ artist_wildcard = akeywords
1012
+ check_wildcard.config(state='normal')
1013
+
1014
+ character_wildcard_check = character_text.get("1.0", tk.END)
1015
+ if len(character_wildcard_check) > 5:
1016
+ lines = character_wildcard_check.strip().split("\n")
1017
+ ckeywords = []
1018
+ current_index = 0
1019
+ for line in lines:
1020
+ parts = line.strip().split(':', 1)
1021
+ if len(parts) == 2 and parts[0].strip().isdigit():
1022
+ weight = int(parts[0].strip())
1023
+ else:
1024
+ weight = 100
1025
+ parts = ['100', line.strip()] # '100:'์„ ์•ž์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
1026
+ keyword = parts[1].strip()
1027
+ ckeywords.append((current_index, current_index + weight - 1, keyword))
1028
+ current_index += weight
1029
+ global character_wildcard
1030
+ character_wildcard = ckeywords
1031
+ check_wildcard2.config(state='normal')
1032
+
1033
+ window.destroy()
1034
+
1035
+
1036
+ def load_wildcard(text_widget, window):
1037
+ window.iconify()
1038
+ filepath = filedialog.askopenfilename(filetypes=[("ํ…์ŠคํŠธ ํŒŒ์ผ", "*.txt")])
1039
+ if filepath:
1040
+ with open(filepath, 'r', encoding='utf-8') as file:
1041
+ lines = file.readlines()
1042
+ updated_lines = []
1043
+ for line in lines:
1044
+ line = line.strip()
1045
+ if ':' in line:
1046
+ prefix, _ = line.split(':', 1)
1047
+ if not prefix.strip().isdigit():
1048
+ line = f"100: {line}"
1049
+ else:
1050
+ line = f"100: {line}"
1051
+ updated_lines.append(line)
1052
+
1053
+ text_widget.delete('1.0', tk.END)
1054
+ text_widget.insert('1.0', '\n'.join(updated_lines))
1055
+ window.deiconify()
1056
+
1057
+ def find_keyword(index, keywords):
1058
+ for start, end, keyword in keywords:
1059
+ if start <= index <= end:
1060
+ print(keyword)
1061
+ return keyword
1062
+ return None
1063
+
1064
+ def get_random_keyword(req_keyword):
1065
+ #called from artist_wildcard, character_wildcard
1066
+ global artist_wildcard, character_wildcard
1067
+ if(req_keyword == 'artist'): keywords = artist_wildcard
1068
+ elif(req_keyword == 'character'): keywords = character_wildcard
1069
+ print('lenghth = ',len(keywords))
1070
+ max_index = keywords[-1][1]
1071
+ print(len(keywords))
1072
+ random_index = random.randint(0, max_index)
1073
+ print(random_index)
1074
+ return find_keyword(random_index, keywords)
1075
+
1076
+ on_press_flag = False
1077
+ window = tk.Tk()
1078
+ window.title("Prompt Selector for Danbooru tags")
1079
+ last_deep_search_keywords = None
1080
+ cached_rows = []
1081
+ total_rows = 0
1082
+ last_selected_row_keywords = ['1girl','nahida (genshin impact)', 'looking at viewer', 'garden']
1083
+ top_100_keywords = []
1084
+ top_100_counts = []
1085
+ previous_artist = None
1086
+ listener = None
1087
+ current_keys = set()
1088
+ click_count = 0
1089
+ access_token = None
1090
+ temp_clipboard_image = None
1091
+ NAI_width = 1024
1092
+ NAI_height = 1024
1093
+ current_sampler = "k_euler_ancestral"
1094
+ running_flag = False
1095
+ NAI_ID = None
1096
+ artist_wildcard = []
1097
+ character_wildcard =[]
1098
+
1099
+ whitelist = wlist.whitelist
1100
+ bag_of_tags = tagbag.bag_of_tags
1101
+ afilter_30000 = arti_list.afilter_30000
1102
+
1103
+ current_wildcard_artist = []
1104
+ current_wildcard_character = []
1105
+
1106
+ GENERATE_EVENT = "<<GenerateEvent>>"
1107
+ window.bind(GENERATE_EVENT, on_generate_event)
1108
+
1109
+ left_frame = tk.Frame(window)
1110
+ left_frame.grid(row=0, column=0, sticky="nsew")
1111
+ #left_frame.grid_columnconfigure(0, weight=1)
1112
+ right_frame = tk.Frame(window)
1113
+ right_frame.grid(row=0, column=1, sticky="nsew")
1114
+ window.grid_columnconfigure(0, weight=1)
1115
+ window.grid_columnconfigure(1, weight=1)
1116
+
1117
+ #ํŒŒ์ผ ๊ฒฝ๋กœ ๋ฐ ํ‚ค์›Œ๋“œ ์ž…๋ ฅ์ฐฝ ๊ทธ๋ฆฌ๋“œ ๊ด€๋ฆฌ
1118
+ frame_row0 = tk.Frame(left_frame)
1119
+ frame_row0.grid(row=0, column=0, padx=5, pady=5, sticky='w')
1120
+
1121
+ # ํŒŒ์ผ ๊ฒฝ๋กœ ์ž…๋ ฅ์ฐฝ
1122
+ label_file_path = tk.Label(frame_row0, text="CSV ํŒŒ์ผ ๊ฒฝ๋กœ:")
1123
+ label_file_path.grid(row=0, column=0, sticky='w')
1124
+ entry_file_path = tk.Entry(frame_row0, width=55)
1125
+ entry_file_path.grid(row=0, column=1, columnspan=4, padx=5, pady=5, sticky='ew')
1126
+ button_open_file = tk.Button(frame_row0, text="ํŒŒ์ผ ์—ด๊ธฐ", command=open_file)
1127
+ button_open_file.grid(row=0, column=5, padx=5, pady=6, sticky='e')
1128
+
1129
+ # ํ‚ค์›Œ๋“œ ์ž…๋ ฅ์ฐฝ
1130
+ keyword_label = tk.Label(frame_row0, text="์ดˆ๊ธฐํ™” ํ‚ค์›Œ๋“œ: ")
1131
+ keyword_label.grid(row=1, column=0, sticky='w')
1132
+ entry_keyword = tk.Entry(frame_row0)
1133
+ entry_keyword.grid(row=1, column=1, columnspan=4, padx=5, pady=5, sticky='ew')
1134
+ button_export_csv = tk.Button(frame_row0, text=".csv ๋‚ด๋ณด๋‚ด๊ธฐ", command=export_csv)
1135
+ button_export_csv.grid(row=1, column=5, padx=5, pady=6, sticky='e')
1136
+
1137
+ # ๋ฒ„ํŠผ ํ”„๋ ˆ์ž„
1138
+ frame_buttons = tk.Frame(left_frame)
1139
+ frame_buttons.grid(row=1, column=0, sticky='ew')
1140
+ frame_buttons.columnconfigure(0, weight=1) # ์™ผ์ชฝ์— ๊ฐ€์ค‘์น˜ ๋ถ€์—ฌ
1141
+ frame_buttons.columnconfigure(1, weight=0) # ๋ฒ„ํŠผ ์—ด์€ ๊ฐ€์ค‘์น˜ ์—†์Œ
1142
+ frame_buttons.columnconfigure(2, weight=0) # ๋ฒ„ํŠผ ์—ด์€ ๊ฐ€์ค‘์น˜ ์—†์Œ
1143
+ frame_buttons.columnconfigure(3, weight=1) # ์˜ค๋ฅธ์ชฝ์— ๊ฐ€์ค‘์น˜ ๋ถ€์—ฌ
1144
+
1145
+ # ๋ฒ„ํŠผ๋“ค
1146
+ button_search = tk.Button(frame_buttons, text="ํ•ด๋‹น ํ‚ค์›Œ๋“œ ๊ฒ€์ƒ‰", command=search)
1147
+ button_search.grid(row=0, column=1, padx=5, sticky='ew') # ๋ณ€๊ฒฝ: column=1
1148
+ button_exclude = tk.Button(frame_buttons, text="ํ•ด๋‹น ํ‚ค์›Œ๋“œ ์ œ์™ธ", command=exclude)
1149
+ button_exclude.grid(row=0, column=2, padx=5, sticky='ew') # ๋ณ€๊ฒฝ: column=2
1150
+
1151
+ total_rows_count_label = tk.Label(frame_buttons, text=".csv ๋‚ด ํ”„๋กฌํ”„ํŠธ ํ–‰: 0")
1152
+ total_rows_count_label.grid(row=0, column=3, padx=5, sticky='ew')
1153
+
1154
+ # ์‹ฌ์ธต๊ฒ€์ƒ‰ ํ‚ค์›Œ๋“œ ์ž…๋ ฅ์ฐฝ
1155
+ deep_search_frame = tk.Frame(left_frame)
1156
+ deep_search_frame.grid(row=2, column=0, pady=10, sticky='w')
1157
+ deep_search_frame.columnconfigure(0, weight=2)
1158
+ deep_search_frame.columnconfigure(1, weight=2)
1159
+ deep_search_frame.columnconfigure(2, weight=1)
1160
+
1161
+ label_deep_search = tk.Label(deep_search_frame, text="์‹ฌ์ธต๊ฒ€์ƒ‰ ํ‚ค์›Œ๋“œ ์ž…๋ ฅ: key,*key,~key,{key1|key2} ")
1162
+ label_deep_search.grid(row=0, column=0, sticky='w')
1163
+
1164
+ # Tkinter UI ์„ค์ • ๋ถ€๋ถ„์— ๋ ˆ์ด๋ธ” ์ถ”๊ฐ€
1165
+ cached_rows_count_label = tk.Label(deep_search_frame, text="์‹ฌ์ธต๊ฒ€์ƒ‰ ํ”„๋กฌํ”„ํŠธ ํ–‰: 0")
1166
+ cached_rows_count_label.grid(row=0, column=1, padx=5, sticky='w')
1167
+
1168
+ button_export_deep_csv = tk.Button(deep_search_frame, text=".csv ๋‚ด๋ณด๋‚ด๊ธฐ", command=export_csv_search)
1169
+ button_export_deep_csv.grid(row=0, column=2, padx=5, sticky='e')
1170
+
1171
+ entry_deep_search = tk.Entry(deep_search_frame, width=82)
1172
+ entry_deep_search.grid(row=1, column=0, columnspan=3,padx=5, pady=5, sticky='ew')
1173
+
1174
+ # ๋ฒ„ํŠผ๋“ค์„ ํฌํ•จํ•  ํ”„๋ ˆ์ž„ ์ƒ์„ฑ
1175
+ button_frame = tk.Frame(left_frame)
1176
+ button_frame.grid(row=5, column=0, padx=5, pady=5, sticky='w')
1177
+
1178
+ # ๋ฒ„ํŠผ ํ”„๋ ˆ์ž„ ๋‚ด์˜ ์—ด ์„ค์ •
1179
+ button_frame.columnconfigure(0, weight=1)
1180
+ button_frame.columnconfigure(1, weight=1)
1181
+ button_frame.columnconfigure(2, weight=1)
1182
+ button_frame.columnconfigure(3, weight=1)
1183
+ button_frame.columnconfigure(4, weight=1)
1184
+ button_frame.columnconfigure(5, weight=1)
1185
+ button_frame.columnconfigure(6, weight=1)
1186
+
1187
+ # "๋žœ๋ค" ๋ฒ„ํŠผ
1188
+ button_random = tk.Button(button_frame, text="๋žœ๋ค", command=random_function)
1189
+ button_random.grid(row=0, column=0, sticky='ew')
1190
+
1191
+ # "ํ”„๋กฌํ”„ํŠธ ๊ณ ์ •" ํ† ๊ธ€ ๋ฒ„ํŠผ
1192
+ toggle_prompt_var = tk.IntVar()
1193
+ button_toggle_prompt = tk.Checkbutton(button_frame, text="ํ”„๋กฌํ”„ํŠธ ๊ณ ์ •", variable=toggle_prompt_var)
1194
+ button_toggle_prompt.grid(row=0, column=1, sticky='ew')
1195
+
1196
+ # "์ž๋™ ๋ณต์‚ฌ" ์ฒดํฌ๋ฐ•์Šค
1197
+ auto_copy_var = tk.IntVar()
1198
+ check_auto_copy = tk.Checkbutton(button_frame, text="์ž๋™ ๋ณต์‚ฌ", variable=auto_copy_var)
1199
+ check_auto_copy.grid(row=0, column=2, sticky='ew')
1200
+
1201
+ # "๋ณต์‚ฌ" ๋ฒ„ํŠผ
1202
+ button_copy = tk.Button(button_frame, text="๋ณต์‚ฌ", command=copy_to_clipboard)
1203
+ button_copy.grid(row=0, column=3, sticky='ew')
1204
+
1205
+ # "์ข…๋ฃŒ" ๋ฒ„ํŠผ
1206
+ button_exit = tk.Button(button_frame, text="์ข…๋ฃŒ", command=exit_program)
1207
+ button_exit.grid(row=0, column=4, sticky='ew')
1208
+
1209
+ # "์ƒ์„ฑ" ๋ฒ„ํŠผ
1210
+ button_generate = tk.Button(button_frame, text="NAI ์š”์ฒญ", command=lambda: NAI_generation(NAI_width, NAI_height, button_generate))
1211
+ button_generate.grid(row=0, column=5, sticky='ew')
1212
+ button_generate.config(state='disabled')
1213
+
1214
+ # "์„ค์ •" ๋ฒ„ํŠผ
1215
+ button_setting = tk.Button(button_frame, text="NAI ๋กœ๊ทธ์ธ ์„ค์ •", command=lambda: NAI_setting(button_setting, button_generate))
1216
+ button_setting.grid(row=0, column=6, sticky='ew')
1217
+
1218
+ mac_var = tk.IntVar()
1219
+ mac_button = tk.Checkbutton(button_frame, text="์ž๋™์ƒ์„ฑ", variable=mac_var)
1220
+ mac_button.grid(row=0, column=7, sticky='ew')
1221
+
1222
+ # ํ…์ŠคํŠธ ๋ฐ ๊ณ ์ • ํ”„๋กฌํ”„ํŠธ ๋„ค๊ฑฐํ‹ฐ๋ธŒ ๋“ฑ ํ”„๋กฌํ”„ํŠธ ์ฐฝ
1223
+ text_frame = tk.Frame(left_frame)
1224
+ text_frame.grid(row=6, column=0, padx=5, pady=5, sticky='w')
1225
+ text_frame.columnconfigure(0, weight=1)
1226
+ text_frame.columnconfigure(1, weight=7)
1227
+
1228
+ text_frame2 = tk.Frame(left_frame)
1229
+ text_frame2.grid(row=8, column=0, padx=5, pady=5, sticky='w')
1230
+ text_frame2.columnconfigure(0, weight=1)
1231
+ text_frame2.columnconfigure(1, weight=7)
1232
+
1233
+ _size = get_max_size()
1234
+
1235
+ # ์ถœ๋ ฅ ํ…์ŠคํŠธ ์ฐฝ
1236
+ text_output_label = tk.Label(text_frame, text="ํ”„๋กฌํ”„ํŠธ", borderwidth=1, relief="solid",height=6)
1237
+ text_output_label.grid(row=0, column=0, padx=5, pady=5, sticky='w')
1238
+ if _size<=768: text_output_width = 74
1239
+ else: text_output_width = 65
1240
+ text_output = tk.Text(text_frame, width=text_output_width, height=7)
1241
+ text_output.grid(row=0, column=1, sticky='ew')
1242
+
1243
+ fixed_prompt_frame = tk.Frame(left_frame)
1244
+ fixed_prompt_frame.grid(row=7, column=0, padx=5, pady=5, sticky='w')
1245
+ fixed_prompt_frame.columnconfigure(0, weight=1)
1246
+ fixed_prompt_frame.columnconfigure(1, weight=1)
1247
+
1248
+ fixed_prompt_label_left = tk.Label(fixed_prompt_frame, text="์„ ํ–‰ ๊ณ ์ • ํ”„๋กฌํ”„ํŠธ (ํ”„๋กฌํ”„ํŠธ ์•ž)")
1249
+ fixed_prompt_label_left.grid(row=0, column=0, sticky='ew')
1250
+ fixed_prompt_label_right = tk.Label(fixed_prompt_frame, text="ํ›„ํ–‰ ๊ณ ์ • ํ”„๋กฌํ”„ํŠธ (ํ”„๋กฌํ”„ํŠธ ๋’ค)")
1251
+ fixed_prompt_label_right.grid(row=0, column=1, sticky='ew')
1252
+ entry_fixed_prompt = tk.Entry(fixed_prompt_frame, width=40)
1253
+ entry_fixed_prompt.grid(row=1, column=0,padx=5, pady=5, sticky='ew')
1254
+ entry_fixed_prompt_after = tk.Entry(fixed_prompt_frame, width=40)
1255
+ entry_fixed_prompt_after.grid(row=1, column=1, padx=5, pady=5, sticky='ew')
1256
+
1257
+ # ๋„ค๊ฑฐํ‹ฐ๋ธŒ ํ”„๋กฌํ”„ํŠธ
1258
+ NP_label = tk.Label(text_frame2, text="๋„ค๊ฑฐํ‹ฐ๋ธŒ\nํ”„๋กฌํ”„ํŠธ", borderwidth=1, relief="solid",height=2)
1259
+ NP_label.grid(row=0,column=0, padx=5, pady=5, sticky='ew')
1260
+ negative_text = tk.Text(text_frame2, width=65, height=3)
1261
+ negative_text.grid(row=0, column=1, padx=5, pady=5, sticky='w')
1262
+
1263
+ auto_hide_frame = tk.Frame(left_frame)
1264
+ auto_hide_frame.grid(row=9, column=0, padx=5, pady=5, sticky='w')
1265
+ auto_hide_frame.columnconfigure(0, weight=2)
1266
+ auto_hide_frame.columnconfigure(1, weight=2)
1267
+ auto_hide_frame.columnconfigure(2, weight=1)
1268
+
1269
+ # ์ž๋™ ์ˆจ๊น€ ํ‚ค์›Œ๋“œ ๋ผ๋ฒจ๊ณผ ์ž…๋ ฅ์ฐฝ ์ถ”๊ฐ€
1270
+ auto_hide_label = tk.Label(auto_hide_frame, text="์ž๋™ ์ˆจ๊น€ ํ‚ค์›Œ๋“œ: keyword1, keyword2, ...")
1271
+ auto_hide_label.grid(row=0, column=0, sticky='w')
1272
+ entry_auto_hide = tk.Entry(auto_hide_frame, width=82)
1273
+ entry_auto_hide.grid(row=1, column=0, columnspan=3, padx=5, pady=5, sticky='ew')
1274
+ # ์ถ”์ฒœ ํ”„๋กฌํ”„ํŠธ ์กฐํšŒ ๋ฒ„ํŠผ ์„ค์ •
1275
+ recommend_prompt_button = tk.Button(auto_hide_frame, text="์ถ”์ฒœ ํ”„๋กฌํ”„ํŠธ", command=open_prompt_window)
1276
+ recommend_prompt_button.grid(row=0, column=2, padx=2, pady=5, sticky='e') # sticky ์˜ต์…˜์„ 'e'๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์˜ค๋ฅธ์ชฝ ์ •๋ ฌ
1277
+
1278
+
1279
+ # ์ฒดํฌ๋ฐ•์Šค๋“ค์„ ํฌํ•จํ•  ํ”„๋ ˆ์ž„ ์ƒ์„ฑ
1280
+ checkbox_frame = tk.Frame(left_frame)
1281
+ checkbox_frame.grid(row=10, column=0, pady=15, sticky='ew')
1282
+ checkbox_frame2 = tk.Frame(left_frame)
1283
+ checkbox_frame2.grid(row=10, column=1, padx=5, pady=15, sticky='ew')
1284
+
1285
+ # ์ฒดํฌ๋ฐ•์Šค ํ”„๋ ˆ์ž„ ๋‚ด์˜ ์—ด ์„ค์ •
1286
+ checkbox_frame.columnconfigure(0, weight=1)
1287
+ checkbox_frame.columnconfigure(1, weight=1)
1288
+ checkbox_frame.columnconfigure(2, weight=1)
1289
+ checkbox_frame.columnconfigure(3, weight=1)
1290
+ checkbox_frame.columnconfigure(4, weight=1)
1291
+ checkbox_frame.columnconfigure(5, weight=1)
1292
+
1293
+
1294
+ # "์ž‘๊ฐ€๋ช… ์ œ๊ฑฐ" ์ฒดํฌ๋ฐ•์Šค
1295
+ remove_artist_var = tk.IntVar() # ์ฒดํฌ๋ฐ•์Šค ์ƒํƒœ๋ฅผ ์ €์žฅํ•  ๋ณ€์ˆ˜
1296
+ check_remove_artist = tk.Checkbutton(checkbox_frame, text="์ž‘๊ฐ€๋ช… ์ œ๊ฑฐ", variable=remove_artist_var)
1297
+ check_remove_artist.grid(row=0, column=0, sticky='ew')
1298
+
1299
+ # "๋žœ๋ค ์ž‘๊ฐ€ ์ถ”๊ฐ€" ์ฒดํฌ๋ฐ•์Šค
1300
+ random_artist_var = tk.IntVar()
1301
+ check_random_artist = tk.Checkbutton(checkbox_frame, text="๋žœ๋ค ์ž‘๊ฐ€ ์ถ”๊ฐ€", variable=random_artist_var)
1302
+ check_random_artist.grid(row=0, column=1, sticky='ew')
1303
+
1304
+ # ๋žœ๋ค์ž‘๊ฐ€ ๊ด€๋ฆฌ
1305
+ random_artist_setting = tk.Button(checkbox_frame, text="๋žœ๋ค ์ž‘๊ฐ€ ๊ด€๋ฆฌ", command=random_artist_management) #output_file_path
1306
+ random_artist_setting.grid(row=0, column=2, sticky='ew')
1307
+
1308
+ # "์บ๋ฆญํ„ฐ ํŠน์ง• ์ œ๊ฑฐ" ์ฒดํฌ๋ฐ•์Šค
1309
+ rm_characteristic_var = tk.IntVar()
1310
+ rm_characteristic_label = tk.Checkbutton(checkbox_frame, text="์บ๋ฆญํ„ฐ ํŠน์ง• ์ œ๊ฑฐ", variable=rm_characteristic_var)
1311
+ rm_characteristic_label.grid(row=0, column=3, sticky='ew')
1312
+
1313
+ # ์™€์ผ๋“œ ์นด๋“œ
1314
+ wildcard_var = tk.IntVar(value= 0)
1315
+ check_wildcard = tk.Checkbutton(checkbox_frame, text="์™€์ผ๋“œ์นด๋“œ(์ž‘๊ฐ€)", variable=wildcard_var, state='disabled')
1316
+ check_wildcard.grid(row=1, column=0, sticky='ew')
1317
+
1318
+ # ์™€์ผ๋“œ ์นด๋“œ2
1319
+ wildcard_var2 = tk.IntVar(value= 0)
1320
+ check_wildcard2 = tk.Checkbutton(checkbox_frame, text="์™€์ผ๋“œ์นด๋“œ(์บ๋ฆญํ„ฐ)", variable=wildcard_var2, state='disabled')
1321
+ check_wildcard2.grid(row=1, column=1, sticky='ew')
1322
+
1323
+ # ์™€์ผ๋“œ ์นด๋“œ ์„ค์ •
1324
+ widldcard_button = tk.Button(checkbox_frame, text="์™€์ผ๋“œ์นด๋“œ ์„ค์ •", command=open_wildcard_setting) #output_file_path
1325
+ widldcard_button.grid(row=1, column=2, sticky='ew')
1326
+
1327
+ #ํด๋” ํ˜ธ์ถœ ๋ฒ„ํŠผ
1328
+ folder_button = tk.Button(checkbox_frame, text="์ €์žฅ ํด๋”", command=open_file_explorer) #output_file_path
1329
+ folder_button.grid(row=1, column=3, padx=5, sticky='ew')
1330
+
1331
+
1332
+ window.bind('<Control-Return>', on_ctrl_enter)
1333
+ window.bind('<Shift-Return>', on_shift_enter)
1334
+
1335
+ NAI_ID = load_settings()
1336
+ if not (entry_keyword.get()): entry_keyword.insert(0, "1girl")
1337
+ if not (entry_fixed_prompt.get()): entry_fixed_prompt.insert(0, '1girl,')
1338
+ if not (entry_fixed_prompt_after.get()): entry_fixed_prompt_after.insert(0, 'great quality, aesthetic, absurdres')
1339
+ if not (entry_auto_hide.get()): entry_auto_hide.insert(0, 'monochrome, doujin cover, bad source, censored, bar censor')
1340
+
1341
+ resolution1_frame = tk.Frame(left_frame)
1342
+ resolution1_frame.grid(row=15, column=0, padx=5, pady=5, sticky='ew')
1343
+ resolution2_frame = tk.Frame(left_frame)
1344
+ resolution2_frame.grid(row=16, column=0, padx=5, pady=5, sticky='ew')
1345
+ selected_resolution = tk.StringVar(value="1024 x 1024")
1346
+ tk.Radiobutton(resolution1_frame, text="1024 x 1024", variable=selected_resolution, value="1024 x 1024").grid(row=0, column=0, sticky='w')
1347
+ tk.Radiobutton(resolution1_frame, text="960 x 1088", variable=selected_resolution, value="960 x 1088").grid(row=0, column=1, sticky='w')
1348
+ tk.Radiobutton(resolution1_frame, text="896 x 1152", variable=selected_resolution, value="896 x 1152").grid(row=0, column=2, sticky='w')
1349
+ tk.Radiobutton(resolution1_frame, text="832 x 1216", variable=selected_resolution, value="832 x 1216").grid(row=0, column=3, sticky='w')
1350
+ tk.Radiobutton(resolution2_frame, text="1088 x 960", variable=selected_resolution, value="1088 x 960").grid(row=0, column=0, sticky='w')
1351
+ tk.Radiobutton(resolution2_frame, text="1152 x 896", variable=selected_resolution, value="1152 x 896").grid(row=0, column=1, sticky='w')
1352
+ tk.Radiobutton(resolution2_frame, text="1216 x 832", variable=selected_resolution, value="1216 x 832").grid(row=0, column=2, sticky='w')
1353
+ selected_resolution.trace_add('write', on_resolution_change)
1354
+
1355
+ sema_button_var = tk.IntVar(value=1)
1356
+ sema_button = tk.Checkbutton(resolution1_frame, text="SEMA", variable=sema_button_var)
1357
+ sema_button.grid(row=0, column=5, sticky='w')
1358
+
1359
+ dyn_button_var = tk.IntVar()
1360
+ dyn_button = tk.Checkbutton(resolution1_frame, text="+DYN", variable=dyn_button_var)
1361
+ dyn_button.grid(row=0, column=6, sticky='w')
1362
+
1363
+ entry_CFG_value = tk.StringVar()
1364
+ entry_CFG_label = tk.Label(resolution2_frame, text=" CFG Scale : ", justify=tk.LEFT)
1365
+ entry_CFG_label.grid(row=0, column=4, sticky='w')
1366
+ entry_CFG_value.set("5.0")
1367
+
1368
+ entry_CFG = tk.Entry(resolution2_frame, width=5, textvariable=entry_CFG_value)
1369
+ entry_CFG.grid(row=0, column=5, sticky='w')
1370
+
1371
+ options = ["k_euler", "k_euler_ancestral", "k_dpmpp_2s_ancestral", "k_dpmpp_sde"]
1372
+ selected_option = tk.StringVar()
1373
+ selected_option.set(options[1])
1374
+ option_menu = tk.OptionMenu(resolution2_frame, selected_option, *options, command=on_option_select)
1375
+ option_menu.grid(row=0, column=6, padx=5, sticky='ew')
1376
+
1377
+
1378
+
1379
+
1380
+
1381
+
1382
+
1383
+ image_label = tk.Label(right_frame, relief='solid', borderwidth=1)
1384
+ image_label.grid(row=0, column=0, rowspan=15, padx=10, pady=10, sticky="n")
1385
+
1386
+ # ์ €๋นˆ๋„ ํ‚ค์›Œ๋“œ ์ž๋™์ถ”๊ฐ€ ๋ฒ„ํŠผ ์ถ”๊ฐ€
1387
+ btn_add_low_freq = tk.Button(right_frame, text="์ด๋ฏธ์ง€๋ฅผ ํด๋ฆฝ๋ณด๋“œ์— ๋ณต์‚ฌ", fg="blue", command=copy_image_to_clipboard)
1388
+ btn_add_low_freq.grid(row=16, column=0, padx=5, pady=5, sticky='ew')
1389
+
1390
+ # ํ•˜์–€์ƒ‰ ์ด๋ฏธ์ง€ ์ƒ์„ฑ
1391
+ white_image = Image.new('RGB', (_size, _size), 'white')
1392
+ white_photo = ImageTk.PhotoImage(white_image)
1393
+
1394
+ # ๋ผ๋ฒจ์— ์ด๋ฏธ์ง€ ์„ค์ •
1395
+ image_label.config(image=white_photo)
1396
+ image_label.image = white_photo
1397
+
1398
+ # ๋ฆฌ์Šค๋„ˆ ์‹œ์ž‘
1399
+ listener = keyboard.Listener(on_press=on_press, on_release=on_release)
1400
+ listener.start()
1401
+
1402
+ # ํ‚ค๋ณด๋“œ ๋ฆฌ์Šค๋„ˆ ์Šค๋ ˆ๋“œ ์‹œ์ž‘
1403
+ listener_thread = threading.Thread(target=listener.join, daemon=True)
1404
+ listener_thread.start()
1405
+
1406
+ window.mainloop()
Danbooru Prompt Selector/tagbag.py ADDED
@@ -0,0 +1 @@
 
 
1
+ bag_of_tags = ['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']
Danbooru Prompt Selector/wlist.py ADDED
The diff for this file is too large to render. See raw diff