#!/usr/bin/env python3 """ 🧪 CATEGORY TEST SAMPLES Po 1 stvar iz vsake kategorije - kvalitetni check pred množično generacijo """ import os import sys import json import time import uuid import requests import subprocess from pathlib import Path from datetime import datetime try: from rembg import remove from PIL import Image except ImportError: os.system("pip3 install --user rembg pillow onnxruntime") from rembg import remove from PIL import Image COMFYUI_URL = "http://127.0.0.1:8000" OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/images") REPO_DIR = Path("/Users/davidkotnik/repos/novafarma") STYLE = "2D indie game sprite, cartoon vector style, clean smooth outlines, full body visible, isolated on pure white background" NEGATIVE = "pixel art, pixelated, 3d render, realistic photo, anime, blurry, watermark, text, green background" # 🧪 TEST SAMPLES - Po 1 iz vsake kategorije (BREZ NPCs!) TEST_SAMPLES = [ # Živali ("zivali", "rabbit_white", "white rabbit animal, long ears, fluffy tail, cute, side view"), # Bosses ("bosses", "boss_dragon_ice", "Ice Dragon boss, massive blue dragon, frost breath, ice scales, menacing, full body"), # Items - Tool ("items", "tool_pickaxe_iron", "iron pickaxe tool, metal head, wooden handle, mining equipment"), # Items - Weapon ("items", "weapon_bow_wood", "wooden bow with arrow, hunting weapon, medieval style"), # Items - Magic ("items", "wand_lightning", "lightning magic wand, yellow crystal tip, electric sparks, glowing"), # Items - Potion ("items", "potion_mana", "mana potion, blue liquid in glass bottle, magical glow"), # Items - Food ("items", "food_bread", "bread loaf, fresh baked, brown crust, artisan style"), # Environment - Tree ("environment", "tree_pine", "pine tree, evergreen, cone shaped, forest tree, full tree"), # Environment - Object ("environment", "barrel_wood", "wooden storage barrel, medieval style, brown wood"), # Mutanti ("mutanti", "slime_purple", "purple poison slime monster, bouncing blob, toxic bubbles"), ] def log(msg): ts = datetime.now().strftime("%H:%M:%S") print(f"[{ts}] {msg}") sys.stdout.flush() def git_commit(file_path, category, name): try: rel_path = file_path.relative_to(REPO_DIR) subprocess.run(["git", "add", str(rel_path)], cwd=REPO_DIR, check=True, capture_output=True) subprocess.run(["git", "commit", "-m", f"🧪 Test sample: {category}/{name}"], cwd=REPO_DIR, check=True, capture_output=True) log(f" 📝 Committed") return True except: return False def create_workflow(prompt_text, output_name, size=512): seed = int(time.time() * 1000) % 2147483647 full_prompt = f"{STYLE}, {prompt_text}" return { "1": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "dreamshaper_8.safetensors"}}, "2": {"class_type": "EmptyLatentImage", "inputs": {"width": size, "height": size, "batch_size": 1}}, "3": {"class_type": "CLIPTextEncode", "inputs": {"text": full_prompt, "clip": ["1", 1]}}, "4": {"class_type": "CLIPTextEncode", "inputs": {"text": NEGATIVE, "clip": ["1", 1]}}, "5": { "class_type": "KSampler", "inputs": { "seed": seed, "steps": 30, "cfg": 7.5, "sampler_name": "euler_ancestral", "scheduler": "karras", "denoise": 1.0, "model": ["1", 0], "positive": ["3", 0], "negative": ["4", 0], "latent_image": ["2", 0] } }, "6": {"class_type": "VAEDecode", "inputs": {"samples": ["5", 0], "vae": ["1", 2]}}, "7": {"class_type": "SaveImage", "inputs": {"filename_prefix": output_name, "images": ["6", 0]}} } def queue_prompt(workflow): try: r = requests.post(f"{COMFYUI_URL}/prompt", json={"prompt": workflow, "client_id": f"test_{uuid.uuid4().hex[:8]}"}, timeout=10) return r.json().get("prompt_id") except Exception as e: log(f"❌ {e}") return None def wait_completion(prompt_id, timeout=120): start = time.time() while time.time() - start < timeout: try: r = requests.get(f"{COMFYUI_URL}/history/{prompt_id}", timeout=5) if prompt_id in r.json() and r.json()[prompt_id].get("outputs"): return True except: pass time.sleep(2) return False def download_and_process(prompt_id, output_path): try: h = requests.get(f"{COMFYUI_URL}/history/{prompt_id}").json() for out in h.get(prompt_id, {}).get("outputs", {}).values(): for img in out.get("images", []): r = requests.get(f"{COMFYUI_URL}/view", params={"filename": img["filename"], "subfolder": img.get("subfolder", ""), "type": "output"}) if r.status_code == 200: output_path.parent.mkdir(parents=True, exist_ok=True) from io import BytesIO transparent_img = remove(Image.open(BytesIO(r.content))) transparent_img.save(str(output_path), "PNG") return True return False except Exception as e: log(f"❌ {e}") return False def main(): log("="*70) log("🧪 CATEGORY TEST SAMPLES") log(" Po 1 iz vsake kategorije - kvalitetni check") log(" NPCs IZKLJUČENI iz avtomatike!") log("="*70) try: r = requests.get(f"{COMFYUI_URL}/system_stats", timeout=5) log(f"✅ ComfyUI v{r.json()['system']['comfyui_version']}") except: log("❌ ComfyUI not running!") return log(f"\n🎯 Generating {len(TEST_SAMPLES)} test samples...\n") success = 0 for i, (cat, name, prompt) in enumerate(TEST_SAMPLES, 1): path = OUTPUT_DIR / cat / f"{name}.png" if path.exists(): log(f"[{i}/{len(TEST_SAMPLES)}] ⏭️ {name} - exists") continue log(f"[{i}/{len(TEST_SAMPLES)}] 🎨 {cat}/{name}") size = 768 if cat == "bosses" else 512 wf = create_workflow(prompt, name, size) pid = queue_prompt(wf) if pid and wait_completion(pid) and download_and_process(pid, path): log(f" ✅ Done!") git_commit(path, cat, name) success += 1 # Open image immediately for review os.system(f"open {path}") else: log(f" ❌ Failed") # Brief pause between generations if i < len(TEST_SAMPLES): time.sleep(2) log("\n" + "="*70) log(f"🧪 TEST SAMPLES COMPLETE! ({success}/{len(TEST_SAMPLES)})") log(" Slike so odprte - preverite kakovost!") log("="*70) log("\n💡 Če je kakovost OK → lahko zaženem VSE ostale") log(" (items, environment, animals, bosses, mutants)") log(" NPCs ostanejo ROČNO!") if __name__ == "__main__": main()