import os import shutil import re from PIL import Image # Configuration DEST_ROOT = "MOJE_SLIKE_KONCNA" EXCLUDE_DIRS = {".git", "node_modules", ".agent", ".vscode", DEST_ROOT} SOURCE_DIRS = [ "assets_BACKUP_20260112_064319", # Proven source of 1024px originals "src/assets/library", # My consolidated library "assets", # Current game assets (if not found in backups) "godot" # Old godot assets ] CATEGORIES = { "zombiji": [r"zombie", r"undead", r"mutant"], "liki": [r"kai", r"ana", r"gronk", r"player", r"protagonist"], "teren": [r"grass", r"dirt", r"soil", r"water", r"sand", r"ground", r"terrain", r"tileset"], "okolje": [r"tree", r"stone", r"rock", r"ruin", r"building", r"house", r"wall", r"fence", r"prop", r"bush", r"flower"], "predmeti": [r"tool", r"weapon", r"axe", r"pickaxe", r"sword", r"bow", r"arrow", r"vape", r"food", r"seed", r"crop", r"item", r"resource", r"gem", r"gold"] } def classify_file(filename): fname = filename.lower() for category, patterns in CATEGORIES.items(): for pattern in patterns: if re.search(pattern, fname): return category return "ostalo" # Fail-safe def organize_images(): if os.path.exists(DEST_ROOT): # Don't delete, just merge/update (safer) print(f"📂 Updating existing {DEST_ROOT}...") else: os.makedirs(DEST_ROOT) # 1. Gather all candidate files (Path -> Size) # We prioritize larger files (Originals) as per user request candidates = {} # Key: filename, Value: (path, size_bytes) print("🚀 Scanning for images (Prioritizing High-Res Originals)...") for source_dir in SOURCE_DIRS: if not os.path.exists(source_dir): continue for root, dirs, files in os.walk(source_dir): dirs[:] = [d for d in dirs if d not in EXCLUDE_DIRS] for file in files: if file.lower().endswith(('.png', '.jpg', '.jpeg')): src_path = os.path.join(root, file) try: size = os.path.getsize(src_path) # Logic: If file exists in candidates, keep the BIGGER one if file in candidates: existing_path, existing_size = candidates[file] if size > existing_size: candidates[file] = (src_path, size) # Upgrade to larger version else: candidates[file] = (src_path, size) except Exception as e: print(f"⚠️ Error scanning {src_path}: {e}") print(f"✅ Found {len(candidates)} unique image names. Copying & Organizing...") copied_count = 0 category_counts = {k: 0 for k in CATEGORIES.keys()} category_counts["ostalo"] = 0 for filename, (src_path, size) in candidates.items(): category = classify_file(filename) # Determine Subfolder Logic? # User asked for: zombiji/ (animacije npr. gibanje, napad) # Verify if parent folder has meaningful name? # e.g. "zombie_walk/frame1.png" -> zombiji/walk/frame1.png # Simple approach first: Just category folder dest_dir = os.path.join(DEST_ROOT, category) # Try to preserve immediate parent folder name if it's descriptive (e.g. animation name) parent_name = os.path.basename(os.path.dirname(src_path)).lower() if category in ["zombiji", "liki"]: # For animated chars, create subfolder based on parent directory # e.g. MOJE_SLIKE_KONCNA/zombiji/Attack_Left/ if parent_name not in ["library", "assets", "slike", "zombiji", "liki", "kai", "ana", "gronk", "backup_old_characters"]: dest_dir = os.path.join(dest_dir, parent_name) if not os.path.exists(dest_dir): os.makedirs(dest_dir) dest_path = os.path.join(dest_dir, filename) try: shutil.copy2(src_path, dest_path) copied_count += 1 if category in category_counts: category_counts[category] += 1 else: category_counts["ostalo"] += 1 except Exception as e: print(f"❌ Failed to copy {filename}: {e}") print("\n" + "="*40) print("📊 ORGANIZATION REPORT") print("="*40) print(f"Total Files Organized: {copied_count}") for cat, count in category_counts.items(): print(f" - {cat.upper()}: {count}") print("="*40) print(f"📂 Location: {os.path.abspath(DEST_ROOT)}") if __name__ == "__main__": organize_images()