import gradio as gr import json import os PASSWORD_FILE = "password.txt" PROMPTS_FILE = "prompts.json" # Cargar prompts desde un archivo JSON si existe def cargar_prompts_desde_archivo(): if os.path.exists(PROMPTS_FILE): with open(PROMPTS_FILE, 'r') as f: return json.load(f) else: # Prompts por defecto return { "secretaria": [ { "name": "Cinemático oficina", "prompt": "Ultra photorealistic full body portrait of a confident blonde businesswoman dressed in an elegant secretary outfit, fitted white blouse, dark pencil skirt, silky black thigh-high stockings, and stilettos. Standing in a modern glass office with city skyline behind. Dramatic cinematic lighting, HDR, depth of field, highly detailed skin texture, professional business atmosphere, 8k, volumetric light --ar 9:16 --v 6 --q 2 --style raw", }, { "name": "Editorial moda", "prompt": "Hyper realistic fashion photography of a blonde woman in a secretary-inspired outfit, high-waisted pencil skirt, white silk blouse slightly unbuttoned, sheer thigh-high stockings with lace tops, black high heels. Studio fashion editorial setting, Vogue magazine style, full body shot, high detail fabric textures, HDRI lighting, cinematic DOF, ray tracing reflections, lifelike colors, soft shadows, 16k render --ar 9:16 --v 6 --q 2", }, { "name": "Oficina futurista", "prompt": "Photorealistic 8k full body portrait of a blonde woman in a sleek secretary-style outfit, fitted blouse, glossy pencil skirt, sheer thigh-high stockings with slight sheen, futuristic office environment with glass walls and neon lights. Global illumination, volumetric fog, reflective floor, cinematic composition, hyper detailed skin pores, realistic light refractions, PBR textures, HDR photograph look --ar 9:16 --v 6 --q 2 --s 800", }, ] } # Guardar prompts en un archivo JSON def guardar_prompts_en_archivo(prompts_lib): with open(PROMPTS_FILE, 'w') as f: json.dump(prompts_lib, f, indent=4) prompts_lib = cargar_prompts_desde_archivo() favorites = [] def guardar_contraseña(pw): if len(pw) != 4 or not pw.isdigit(): return "La contraseña debe tener exactamente 4 dígitos" with open(PASSWORD_FILE, "w") as f: f.write(pw) return "Contraseña guardada correctamente. Ahora úsala para entrar." def cargar_contraseña(): if not os.path.exists(PASSWORD_FILE): return None with open(PASSWORD_FILE, "r") as f: return f.read().strip() def verificar_password(pw): pw_guardada = cargar_contraseña() if pw_guardada is None: return "No hay contraseña registrada. Por favor crea una." if pw == pw_guardada: return "Acceso concedido" else: return "Contraseña incorrecta" def gestionar_password(pw, crear=False): if crear: return guardar_contraseña(pw) else: return verificar_password(pw) def agregar_prompt(categoria, nombre, texto): categoria = categoria.strip().lower() if not categoria: categoria = "sin_categoria" if categoria not in prompts_lib: prompts_lib[categoria] = [] prompts_lib[categoria].append({ "name": nombre if nombre else f"Nuevo {len(prompts_lib[categoria])+1}", "prompt": texto, }) guardar_prompts_en_archivo(prompts_lib) return f"Prompt añadido en '{categoria}'" def mostrar_prompts(categoria, filtro=""): categoria = categoria.strip().lower() prompts = prompts_lib.get(categoria, []) rows = [] for p in prompts: if filtro.lower() in p["prompt"].lower() or filtro.lower() in p["name"].lower(): rows.append([p["name"], p["prompt"]]) return rows def exportar_prompts(categoria): categoria = categoria.strip().lower() prompts = prompts_lib.get(categoria, []) contenido = "" for p in prompts: contenido += f"Nombre: {p['name']}\nPrompt: {p['prompt']}\n\n" return contenido with gr.Blocks(theme=gr.themes.Dark()) as demo: gr.Markdown("# BAT-@talogo_pro") with gr.Tab("Acceso"): estado = gr.Textbox(interactive=False) pass_input = gr.Textbox(label="Contraseña 4 dígitos", type="password", max_lines=1) crear_btn = gr.Button("Crear contraseña (solo la primera vez)") entrar_btn = gr.Button("Entrar") crear_btn.click(fn=lambda pw: gestionar_password(pw, crear=True), inputs=pass_input, outputs=estado) entrar_btn.click(fn=lambda pw: gestionar_password(pw, crear=False), inputs=pass_input, outputs=estado) with gr.Tab("Buscar y visualizar"): categoria_input = gr.Textbox(label="Categoría de outfit", placeholder="Ejemplo: secretaria") filtro_input = gr.Textbox(label="Palabra clave (opcional)", placeholder="Ejemplo: moda, secretaria...") buscar_btn = gr.Button("🔍 Buscar") resultado = gr.Dataframe(headers=["Nombre", "Prompt"]) export_btn = gr.Button("Exportar TXT") output_txt = gr.Textbox(label="Prompts exportados", interactive=False) buscar_btn.click( fn=mostrar_prompts, inputs=[categoria_input, filtro_input], outputs=resultado ) export_btn.click( fn=exportar_prompts, inputs=categoria_input, outputs=output_txt ) with gr.Tab("Edición y agregado", visible=False) as edit_tab: categoria_new = gr.Textbox(label="Categoría nueva o existente", placeholder="Ejemplo: secretaria") nombre_new = gr.Textbox(label="Nombre del prompt", placeholder="Ejemplo: Estilo business moderno") prompt_new = gr.Textbox(label="Prompt (puedes pegar desde portapapeles)", lines=6) agregar_btn = gr.Button("Agregar a catálogo") confirmacion = gr.Textbox(label="", interactive=False) agregar_btn.click( fn=agregar_prompt, inputs=[categoria_new, nombre_new, prompt_new], outputs=confirmacion ) def mostrar_editor(mensaje): return gr.update(visible=(mensaje == "Acceso concedido")) estado.change(fn=mostrar_editor, inputs=estado, outputs=edit_tab) # Lanzar el demo demo.launch()