|
|
import tkinter as tk
|
|
|
from tkinter import filedialog
|
|
|
from PIL import Image, ImageTk
|
|
|
import json
|
|
|
import base64
|
|
|
import io
|
|
|
import re
|
|
|
|
|
|
from artist_dictionary import artist_dict
|
|
|
|
|
|
class ArtistThumbnailViewer:
|
|
|
def __init__(self, master):
|
|
|
self.master = master
|
|
|
self.master.title("NAIA/WEBUIA 대체용 작가명 태그 미리보기 뷰어, Ctrl+C로 작가명 복사 가능")
|
|
|
self.master.geometry("728x525")
|
|
|
|
|
|
self.artist_data = {}
|
|
|
self.artist_list = []
|
|
|
self.last_search = ""
|
|
|
|
|
|
self.left_frame = tk.Frame(master, width=300)
|
|
|
self.left_frame.pack(side=tk.LEFT, fill=tk.Y)
|
|
|
|
|
|
self.right_frame = tk.Frame(master)
|
|
|
self.right_frame.pack(side=tk.RIGHT, expand=True, fill=tk.BOTH)
|
|
|
|
|
|
self.search_entry = tk.Entry(self.left_frame, font=("Malgun Gothic", 12))
|
|
|
self.search_entry.pack(pady=5)
|
|
|
self.search_entry.bind('<KeyRelease>', self.popup_search)
|
|
|
self.search_entry.bind('<FocusOut>', lambda e: self.popup.withdraw())
|
|
|
|
|
|
self.listbox_frame = tk.Frame(self.left_frame)
|
|
|
self.listbox_frame.pack(pady=5, fill=tk.BOTH, expand=True)
|
|
|
|
|
|
self.scrollbar = tk.Scrollbar(self.listbox_frame)
|
|
|
self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
|
|
|
|
|
|
self.listbox = tk.Listbox(self.listbox_frame, font=("Malgun Gothic", 12), width=20, height=30, yscrollcommand=self.scrollbar.set)
|
|
|
self.listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
|
|
self.scrollbar.config(command=self.listbox.yview)
|
|
|
self.listbox.pack(pady=5)
|
|
|
self.listbox.bind('<<ListboxSelect>>', self.display_image)
|
|
|
|
|
|
self.canvas = tk.Canvas(self.right_frame, bg="white")
|
|
|
self.canvas.pack(expand=True, fill=tk.BOTH)
|
|
|
|
|
|
self.menu = tk.Menu(master)
|
|
|
self.menu.add_command(label="artist_thumbnail 파일 불러오기", command=self.load_json_file)
|
|
|
master.config(menu=self.menu)
|
|
|
|
|
|
|
|
|
self.popup = tk.Toplevel(master)
|
|
|
self.popup.withdraw()
|
|
|
self.popup.overrideredirect(True)
|
|
|
self.plistbox = tk.Listbox(self.popup, font=("Malgun Gothic", 12), width=40, height=11, borderwidth=2, highlightbackground='lightgrey')
|
|
|
self.plistbox.pack()
|
|
|
self.plistbox.bind('<<ListboxSelect>>', self.select_popup_result)
|
|
|
|
|
|
def load_json_file(self):
|
|
|
filepath = filedialog.askopenfilename(filetypes=[("All", "artist_thumb*")])
|
|
|
if not filepath:
|
|
|
return
|
|
|
|
|
|
with open(filepath, 'r', encoding='utf-8') as file:
|
|
|
self.artist_data = json.load(file)
|
|
|
|
|
|
self.artist_list = sorted(
|
|
|
[key for key in self.artist_data if key in artist_dict],
|
|
|
key=lambda k: artist_dict[k], reverse=True
|
|
|
)
|
|
|
self.update_listbox(self.artist_list)
|
|
|
|
|
|
def update_listbox(self, items):
|
|
|
self.listbox.delete(0, tk.END)
|
|
|
for item in items:
|
|
|
self.listbox.insert(tk.END, item)
|
|
|
|
|
|
def display_image(self, event=None):
|
|
|
try:
|
|
|
selected = self.listbox.get(self.listbox.curselection())
|
|
|
except:
|
|
|
return
|
|
|
|
|
|
img_data = self.artist_data.get(selected, [None])[0]
|
|
|
if img_data:
|
|
|
img_bytes = base64.b64decode(img_data)
|
|
|
image = Image.open(io.BytesIO(img_bytes))
|
|
|
image = image.resize((512, 512), Image.LANCZOS)
|
|
|
self.tk_image = ImageTk.PhotoImage(image)
|
|
|
self.canvas.delete("all")
|
|
|
self.canvas.create_image(10, 10, anchor='nw', image=self.tk_image)
|
|
|
else:
|
|
|
self.canvas.delete("all")
|
|
|
|
|
|
def popup_search(self, event=None):
|
|
|
search_text = self.search_entry.get().strip().lower()
|
|
|
self.plistbox.delete(0, tk.END)
|
|
|
|
|
|
results = []
|
|
|
for artist in self.artist_list:
|
|
|
if search_text in artist.lower():
|
|
|
value = artist_dict.get(artist, 0)
|
|
|
results.append((artist, value))
|
|
|
|
|
|
results.sort(key=lambda x: x[1], reverse=True)
|
|
|
results = results[:40]
|
|
|
|
|
|
if results:
|
|
|
for k, v in results:
|
|
|
v_formatted = f"{v:>9}".replace(' ', ' ')
|
|
|
formatted_line = f"{v_formatted} {k}"
|
|
|
self.plistbox.insert(tk.END, formatted_line)
|
|
|
|
|
|
abs_x = self.search_entry.winfo_rootx()
|
|
|
abs_y = self.search_entry.winfo_rooty() + 30
|
|
|
self.popup.geometry(f"+{abs_x}+{abs_y}")
|
|
|
self.popup.deiconify()
|
|
|
else:
|
|
|
self.popup.withdraw()
|
|
|
|
|
|
def select_popup_result(self, event=None):
|
|
|
try:
|
|
|
selection = self.plistbox.get(self.plistbox.curselection())
|
|
|
keyword = re.sub(r'^\s*\d+\s+', '', selection.strip().split(maxsplit=1)[-1])
|
|
|
index = self.artist_list.index(keyword)
|
|
|
self.popup.withdraw()
|
|
|
self.listbox.select_clear(0, tk.END)
|
|
|
self.listbox.select_set(index)
|
|
|
self.listbox.see(index)
|
|
|
self.display_image()
|
|
|
except:
|
|
|
pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
root = tk.Tk()
|
|
|
app = ArtistThumbnailViewer(root)
|
|
|
root.mainloop()
|
|
|
|