Last active
July 16, 2025 21:03
-
-
Save Goatghosts/d5d8e9dc1373eb29b3a7a4580b3a9d48 to your computer and use it in GitHub Desktop.
Простой помощник для быстрого создания промптов из содержимого каталога.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import pickle | |
import threading | |
import tkinter as tk | |
from tkinter import filedialog, scrolledtext, messagebox | |
import logging | |
CONFIG_FILE = os.path.join(os.path.dirname(__file__), ".prompt_gui.pkl") | |
logging.basicConfig( | |
level=logging.INFO, | |
format="%(asctime)s [%(levelname)s]: %(message)s", | |
datefmt="%Y-%m-%d %H:%M:%S", | |
) | |
logger = logging.getLogger("prompt_gui") | |
def load_cfg(): | |
if os.path.exists(CONFIG_FILE): | |
with open(CONFIG_FILE, "rb") as f: | |
cfg = pickle.load(f) | |
logger.info(f"Загружена конфигурация: {cfg}") | |
return cfg | |
cfg = {"dir": "", "exts": [".ts", ".svelte"], "bl": []} | |
logger.info(f"Создана новая конфигурация: {cfg}") | |
return cfg | |
def save_cfg(cfg): | |
with open(CONFIG_FILE, "wb") as f: | |
pickle.dump(cfg, f) | |
logger.info(f"Конфигурация сохранена: {cfg}") | |
def generate_prompt(path, exts, bl): | |
output = [] | |
bl_set = set(bl) | |
count_files = 0 | |
for root, dirs, files in os.walk(path): | |
parts = set(os.path.relpath(root, path).replace("\\", "/").split("/")) | |
if parts & bl_set: | |
continue | |
for file in files: | |
if any(file.endswith(ext) for ext in exts): | |
count_files += 1 | |
full_path = os.path.abspath(os.path.join(root, file)).replace("\\", "/") | |
output.append(full_path) | |
output.append("```") | |
try: | |
with open(full_path, encoding="utf-8") as f: | |
for line in f: | |
if not line.lstrip().startswith("//"): | |
output.append(line.rstrip("\n")) | |
except Exception as e: | |
logger.error(f"Ошибка чтения {full_path}: {e}") | |
output.append("```") | |
output.append("") | |
result = "\n".join(output) | |
logger.info(f"Сгенерировано файлов: {count_files}, длина текста: {len(result)} символов") | |
return result | |
class App: | |
def __init__(self, root): | |
self.root = root | |
root.title("Prompt Builder") | |
root.geometry("950x600") | |
logger.info("Запуск приложения") | |
self.cfg = load_cfg() | |
tk.Label(root, text="Директория проекта:").pack(anchor="w", padx=5) | |
self.dir_var = tk.StringVar(value=self.cfg["dir"]) | |
dir_frm = tk.Frame(root) | |
dir_frm.pack(fill="x", padx=5, pady=2) | |
tk.Entry(dir_frm, textvariable=self.dir_var).pack(side="left", fill="x", expand=True) | |
tk.Button(dir_frm, text="📁", command=self.choose_dir).pack(side="left", padx=2) | |
main_frm = tk.Frame(root) | |
main_frm.pack(fill="both", expand=True, padx=5, pady=5) | |
self.exts = self.create_column(main_frm, "Типы файлов", self.cfg["exts"]) | |
self.bl = self.create_column(main_frm, "Чёрный список путей", self.cfg["bl"]) | |
self.text = scrolledtext.ScrolledText(main_frm, wrap="none") | |
self.text.grid(row=0, column=2, sticky="nsew", rowspan=2, padx=(5, 0)) | |
main_frm.columnconfigure(2, weight=3) | |
main_frm.rowconfigure(0, weight=1) | |
btn_frm = tk.Frame(root) | |
btn_frm.pack(fill="x", padx=5, pady=5) | |
tk.Button(btn_frm, text="Сгенерировать", command=self.generate).pack(side="left", expand=True, fill="x") | |
tk.Button(btn_frm, text="Копировать", command=self.copy).pack(side="left", expand=True, fill="x") | |
self.dir_var.trace_add("write", self.autosave) | |
def create_column(self, parent, title, items): | |
frm = tk.Frame(parent) | |
frm.grid(sticky="nswe", padx=2) | |
parent.columnconfigure(parent.grid_size()[0] - 1, weight=1) | |
tk.Label(frm, text=title).pack(anchor="w") | |
list_frm = tk.Frame(frm) | |
list_frm.pack(fill="both", expand=True) | |
lb = tk.Listbox(list_frm) | |
lb.pack(side="left", fill="both", expand=True) | |
sb = tk.Scrollbar(list_frm, command=lb.yview) | |
sb.pack(side="right", fill="y") | |
lb.config(yscrollcommand=sb.set) | |
for i in items: | |
lb.insert("end", i) | |
entry_frm = tk.Frame(frm) | |
entry_frm.pack(fill="x") | |
entry = tk.Entry(entry_frm) | |
entry.pack(side="left", fill="x", expand=True) | |
tk.Button(entry_frm, text="➕", command=lambda: self.add_item(lb, entry)).pack(side="left") | |
tk.Button(frm, text="❌ Удалить выбранное", command=lambda: self.del_item(lb)).pack(fill="x", pady=2) | |
lb.bind("<<ListboxSelect>>", lambda e: self.autosave()) | |
return lb | |
def add_item(self, lb, entry): | |
txt = entry.get().strip() | |
if txt: | |
if lb == self.exts and not txt.startswith("."): | |
txt = "." + txt | |
lb.insert("end", txt) | |
entry.delete(0, "end") | |
logger.info(f"Добавлен элемент: {txt}") | |
self.autosave() | |
def del_item(self, lb): | |
sel = lb.curselection() | |
if sel: | |
txt = lb.get(sel[0]) | |
lb.delete(sel[0]) | |
logger.info(f"Удалён элемент: {txt}") | |
self.autosave() | |
def choose_dir(self): | |
p = filedialog.askdirectory() | |
if p: | |
self.dir_var.set(p) | |
logger.info(f"Выбрана директория: {p}") | |
def generate(self): | |
path = self.dir_var.get() | |
exts = self.exts.get(0, "end") | |
bl = self.bl.get(0, "end") | |
if not path or not os.path.isdir(path): | |
messagebox.showwarning("Ошибка", "Укажите корректный путь") | |
logger.warning("Попытка генерации с некорректным путём") | |
return | |
self.text.delete("1.0", "end") | |
logger.info(f"Запуск генерации для {path}, расширения: {exts}, blacklist: {bl}") | |
threading.Thread(target=self.worker, args=(path, exts, bl), daemon=True).start() | |
def worker(self, p, e, bl): | |
result = generate_prompt(p, e, bl) | |
self.text.after(0, lambda: self.text.insert("end", result)) | |
logger.info("Генерация завершена успешно") | |
def copy(self): | |
txt = self.text.get("1.0", "end") | |
self.root.clipboard_clear() | |
self.root.clipboard_append(txt) | |
logger.info(f"Скопировано {len(txt.strip())} символов") | |
def autosave(self, *a): | |
self.cfg["dir"] = self.dir_var.get() | |
self.cfg["exts"] = self.exts.get(0, "end") | |
self.cfg["bl"] = self.bl.get(0, "end") | |
save_cfg(self.cfg) | |
if __name__ == "__main__": | |
root = tk.Tk() | |
App(root) | |
root.mainloop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment