From aefe53275f797c7ea121ce096f28b331bee8cffe Mon Sep 17 00:00:00 2001 From: David Kotnik Date: Sun, 4 Jan 2026 19:04:33 +0100 Subject: [PATCH] feat: Visual Asset Management System - Gallery, Organization & Smart Labeling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IMPLEMENTED SYSTEMS: ✅ Thumbnail Grid Gallery (1,166 images, searchable, filterable) ✅ Smart Asset Organizer (auto-categorize, rename, organize into Slovenian folders) ✅ Hover Preview documentation (VS Code integration) ✅ Smart Auto-Labeling (descriptive naming convention) FILES: - tools/asset_gallery.html: Interactive web gallery with modal preview - scripts/smart_asset_organizer.py: Automated organization script - docs/VISUAL_ASSET_SYSTEM.md: Complete documentation FEATURES: - Live search & category filters - Modal image preview - Dry-run mode for safe testing - Slovenian folder structure (liki, biomi, zgradbe, oprema, etc.) - Auto-labeling with {category}_{description}_style32.png format - Organization manifest tracking Asset Count: 1,166 images (576 MB) Ready for ADHD-friendly visual workflow --- docs/VISUAL_ASSET_SYSTEM.md | 300 +++++++++++++++++ scripts/smart_asset_organizer.py | 271 +++++++++++++++ tools/asset_gallery.html | 549 +++++++++++++++++++++++++++++++ 3 files changed, 1120 insertions(+) create mode 100644 docs/VISUAL_ASSET_SYSTEM.md create mode 100755 scripts/smart_asset_organizer.py create mode 100644 tools/asset_gallery.html diff --git a/docs/VISUAL_ASSET_SYSTEM.md b/docs/VISUAL_ASSET_SYSTEM.md new file mode 100644 index 000000000..1c86c3a14 --- /dev/null +++ b/docs/VISUAL_ASSET_SYSTEM.md @@ -0,0 +1,300 @@ +# 🎨 Vizualni Sistem za Preglednost Assetov + +**Status**: ✅ IMPLEMENTIRANO +**Datum**: 2026-01-04 +**Asseti**: 1,166 slik (576 MB) + +--- + +## 🎯 Pregled Sistemov + +Ta dokument opisuje **4 sisteme** za lažjo vizualno preglednost vseh assetov v DolinaSmrti projektu: + +1. **Thumbnail Grid Gallery** - spletna galerija vseh slik +2. **Smart Asset Organization** - avtomatska organizacija v logične folderje +3. **Hover Preview** (zahteva IDE nastavitve) +4. **Smart Auto-Labeling** - avtomatsko poimenovanje po vsebini + +--- + +## 1️⃣ Thumbnail Grid Gallery + +### 📍 Lokacija +`/tools/asset_gallery.html` + +### 🚀 Kako Odpreti + +**Option A: Direktno v brskalniku** +```bash +open tools/asset_gallery.html +``` + +**Option B: Preko lokalnega serverja** +```bash +cd tools +python3 -m http.server 8080 +# Odpri: http://localhost:8080/asset_gallery.html +``` + +### ✨ Funkcionalnosti + +- **Thumbnail Grid**: Pregled vseh 1,166 slik v mreži +- **🔍 Iskanje**: Išči po imenu datoteke +- **📁 Filtri**: Filter po kategorijah (Style 32, animations, NPCs, buildings, itd.) +- **🖼️ Modal Preview**: Klikni na sliko za povečavo +- **📊 Live Stats**: Statistika koliko slik je prikazanih + +### 🎨 Kategorije + +- **Vse (1166)** - vsi asseti +- **Style 32 (344)** - Style 32 Session Jan 04 +- **Slike Folder (817)** - originalni slike folder +- **Animacije (112)** - animation spritesheets +- **Rastline (144)** - plants & vegetation +- **Kreature (271)** - creatures & mutants +- **Predmeti (105)** - items & props +- **Demo Assets (63)** - demo scene assets +- **Buildings** - zgradbe in stavbe +- **NPCs** - character sprites +- **Terrain** - terrain tiles +- **Interior** - interior objects +- **Weapons** - orožje +- **Tools** - orodja + +--- + +## 2️⃣ Smart Asset Organization + +### 📍 Lokacija +`/scripts/smart_asset_organizer.py` + +### 🚀 Kako Uporabiti + +**1. Preveri kaj bi se zgodilo (DRY RUN):** +```bash +python3 scripts/smart_asset_organizer.py +``` + +**2. Prikaži strukturo kategorij:** +```bash +python3 scripts/smart_asset_organizer.py --preview +``` + +**3. DEJANSKO izvedi organizacijo:** +```bash +python3 scripts/smart_asset_organizer.py --execute +``` + +### 📂 Nova Struktura Folderjev + +``` +assets/slike 🟢/ +├── liki/ # Characters +│ ├── gronk/ +│ ├── kai/ +│ ├── ana/ +│ ├── zombiji/ +│ └── npcs/ +├── biomi/ # Biomes +│ ├── desert/ +│ ├── gore/ +│ ├── džungla/ +│ ├── močvirje/ +│ └── arktika/ +├── zgradbe/ # Buildings +│ ├── hiše/ +│ ├── javne/ +│ ├── kmetijske/ +│ └── delavnice/ +├── objekti/ # Props +│ ├── pohištvo/ +│ ├── shranjevanje/ +│ ├── razsvetljava/ +│ └── dekoracije/ +├── narava/ # Nature +│ ├── rastline/ +│ ├── pridelki/ +│ └── živali/ +├── oprema/ # Equipment +│ ├── orožje/ +│ ├── orodja/ +│ └── zaščita/ +├── vmesnik/ # UI +│ ├── gumbi/ +│ ├── ikone/ +│ ├── vrstice/ +│ └── okna/ +├── teren/ # Terrain tiles +├── notranjost/ # Interior objects +├── učinki/ # VFX +└── kreature_mutanti/ # Mutants +``` + +### 🏷️ Smart Naming Convention + +**Format**: `{kategorija}_{podfolder}_{opis}_style32.png` + +**Primeri**: +- `liki_kai_idle_style32.png` +- `zgradbe_javne_church_complete_style32.png` +- `oprema_orožje_sword_weapon_style32.png` +- `narava_živali_cow_farm_animal_style32.png` + +### 📊 Manifest + +Po organizaciji se ustvari `docs/ASSET_ORGANIZATION_MANIFEST.json` z: +- Seznam vseh premakjenih datotek +- Original → Nova lokacija +- Kategorija in podfolder za vsak asset +- Statistika (moved, renamed, skipped) + +--- + +## 3️⃣ Hover Preview (IDE Feature) + +### 🔧 Nastavitve v VS Code + +**1. Namesti razširitev:** +- Install: "Image Preview" by Kiss Tamás + +**2. Aktiviraj hover preview:** +```json +// settings.json +{ + "imagePreview.hoverPreview": true, + "imagePreview.maxHeight": 256, + "imagePreview.maxWidth": 256 +} +``` + +**3. Uporaba:** +- Pridi z miško čez `'path/to/image.png'` v kodi +- Prikaže se preview slike! 🖼️ + +--- + +## 4️⃣ Smart Auto-Labeling + +Auto-labeling je integriran v `smart_asset_organizer.py` script. + +### Kako Deluje + +1. **Scan**: Prebere ime datoteke +2. **Detect**: Zazna kategorijo (buildings, NPCs, tools, itd.) +3. **Generate**: Ustvari novo ime z opisnimi keywords +4. **Rename**: Preimenuje datoteko + +### Pravila Poimenovanja + +- **Odstranjeni**: timestampi (`_1767549405033`) +- **Dodani**: kategorija in podfolder +- **Ohranjen**: original content description +- **Dodano**: `_style32` za Style 32 assete + +--- + +## 🎯 Hitri Začetek + +### Za Pregled Vseh Slik: +```bash +open tools/asset_gallery.html +``` + +### Za Organizacijo Assetov: +```bash +# 1. Preveri najprej (dry run) +python3 scripts/smart_asset_organizer.py + +# 2. Izvrši organizacijo +python3 scripts/smart_asset_organizer.py --execute +``` + +### Za Hover Preview: +1. Odpri VS Code +2. Install "Image Preview" extension +3. Hover čez pot do slike v kodi + +--- + +## 📊 Trenutno Stanje + +- **Skupaj slik**: 1,166 +- **Velikost**: 576 MB +- **Style 32 asseti**: 344 slik +- **Originalni slike folder**: 817 slik +- **Organizirano**: ❌ (čaka na `--execute`) + +--- + +## ⚙️ Napredne Možnosti + +### Dodaj Novo Kategorijo + +Uredi `smart_asset_organizer.py`: + +```python +TARGET_STRUCTURE = { + # ... obstoječe kategorije ... + "nova_kategorija": ["keyword1", "keyword2", "keyword3"] +} +``` + +### Prilagodi Naming Convention + +Uredi funkcijo `generate_smart_name()` v `smart_asset_organizer.py`. + +--- + +## 🚨 Pomembna Opozorila + +⚠️ **BACKUP PRED ORGANIZACIJO!** +```bash +# Backup assetov +cp -r assets/ assets_backup_$(date +%Y%m%d)/ +``` + +⚠️ **DRY RUN NAJPREJ!** +Vedno najprej zaženi brez `--execute` da vidiš kaj se bo zgodilo. + +⚠️ **GIT COMMIT PRED SPREMEMBAMI!** +```bash +git add . +git commit -m "backup: Before asset reorganization" +``` + +--- + +## 🎬 Video Tutorial + +(Coming soon - screen recording kako uporabljati vse sisteme) + +--- + +## 🐛 Troubleshooting + +### Gallery Ne Prikaže Slik? +- Preveri da si v project root direktoriju +- Uporabi local server (`python3 -m http.server`) +- Preveri browser console za napake (F12) + +### Hover Preview Ne Deluje? +- Preveri da imaš "Image Preview" extension nameščen +- Preveri `settings.json` za pravilne nastavitve +- Restart VS Code + +### Organizacija Script Crashne? +- Preveri Python version (3.8+) +- Run z `--preview` za debugging +- Preveri da imaš write permissions na `assets/` folder + +--- + +**Dokumentacija verzija**: 1.0 +**Zadnja posodobitev**: 2026-01-04 +**Maintainer**: Antigravity Agent + +--- + +## 🙏 Credits + +Developed as part of **Mrtva Dolina v1.0 - Director Mode** implementation. diff --git a/scripts/smart_asset_organizer.py b/scripts/smart_asset_organizer.py new file mode 100755 index 000000000..8b245059a --- /dev/null +++ b/scripts/smart_asset_organizer.py @@ -0,0 +1,271 @@ +#!/usr/bin/env python3 +""" +Smart Asset Organization System +Reorganizes all assets into logical folder structure with smart naming +""" + +import os +import shutil +from pathlib import Path +from typing import Dict, List +import json + +# Base directories +PROJECT_ROOT = Path(__file__).parent.parent +ASSETS_DIR = PROJECT_ROOT / "assets" +SLIKE_DIR = ASSETS_DIR / "slike 🟢" +STYLE32_DIR = ASSETS_DIR / "images" / "STYLE_32_SESSION_JAN_04" + +# Target organization structure +TARGET_STRUCTURE = { + "liki": { # Characters + "gronk": ["gronk", "grok"], + "kai": ["kai"], + "ana": ["ana"], + "zombiji": ["zombie"], + "npcs": ["npc", "farmer", "priest", "blacksmith", "merchant", "mayor", "lawyer"] + }, + "biomi": { # Biomes + "desert": ["desert", "sand"], + "gore": ["mountain", "rock", "boulder"], + "džungla": ["jungle", "tropical"], + "močvirje": ["swamp", "mud"], + "arktika": ["arctic", "ice", "snow"] + }, + "zgradbe": { # Buildings + "hiše": ["house", "home", "farmhouse"], + "javne": ["church", "town_hall", "clinic", "bakery", "tavern"], + "kmetijske": ["barn", "silo", "greenhouse", "windmill"], + "delavnice": ["workshop", "blacksmith", "laboratory", "mint"] + }, + "objekti": { # Props + "pohištvo": ["chair", "table", "bed", "sofa", "wardrobe"], + "shranjevanje": ["chest", "barrel", "crate", "shelf"], + "razsvetljava": ["lantern", "torch", "lamp"], + "dekoracije": ["statue", "fountain", "monument", "grave"] + }, + "narava": { # Nature + "rastline": ["plant", "tree", "bush", "flower", "grass"], + "pridelki": ["crop", "wheat", "carrot", "tomato", "potato", "cabbage"], + "živali": ["cow", "sheep", "chicken", "pig", "wolf", "rabbit"] + }, + "oprema": { # Equipment + "orožje": ["sword", "axe", "bow", "spear", "dagger", "mace", "weapon"], + "orodja": ["pickaxe", "shovel", "hoe", "hammer", "saw", "tool"], + "zaščita": ["armor", "shield", "helmet"] + }, + "vmesnik": { # UI + "gumbi": ["button"], + "ikone": ["icon"], + "vrstice": ["bar"], + "okna": ["panel", "window", "dialogue"] + }, + "teren": ["terrain"], # Terrain tiles + "notranjost": ["interior"], # Interior objects + "učinki": ["effect", "particle", "spark", "glow"], # VFX + "kreature_mutanti": ["mutant", "radioactive", "three_eyed", "two_headed"] # Mutants +} + + +def detect_category_and_subfolder(filename: str) -> tuple: + """ + Detect the appropriate category and subfolder for a file based on its name + Returns: (category, subfolder) or (category, None) if no subfolder + """ + lower_name = filename.lower() + + # Check nested categories first + for category, subfolders in TARGET_STRUCTURE.items(): + if isinstance(subfolders, dict): + for subfolder, keywords in subfolders.items(): + if any(keyword in lower_name for keyword in keywords): + return (category, subfolder) + else: + # Simple list of keywords + if any(keyword in lower_name for keyword in subfolders): + return (category, None) + + return ("ostalo", None) # Default: "other" + + +def generate_smart_name(filepath: Path, category: str, subfolder: str = None) -> str: + """ + Generate a smart, descriptive name for an asset + Format: {category}_{content_description}_style32.png (if from Style 32) + """ + filename = filepath.stem + extension = filepath.suffix + + # Check if it's from Style 32 + is_style32 = "STYLE_32" in str(filepath) or "style32" in filename.lower() + + # Clean up existing name + clean_name = filename.lower() + clean_name = clean_name.replace("_style32", "").replace("style32", "") + clean_name = clean_name.replace("interior_", "").replace("terrain_", "") + + # Remove timestamp patterns (e.g., _1767549405033) + import re + clean_name = re.sub(r'_\d{13}', '', clean_name) + + # Build new name + parts = [] + + if category != "ostalo": + parts.append(category) + + if subfolder: + parts.append(subfolder) + + parts.append(clean_name) + + if is_style32: + parts.append("style32") + + new_name = "_".join(parts) + extension + + return new_name + + +def organize_assets(dry_run: bool = True): + """ + Organize all assets into the target structure + + Args: + dry_run: If True, only print what would be done without moving files + """ + print("🗂️ Starting Asset Organization...") + print(f"📁 Source directories:") + print(f" - {SLIKE_DIR}") + print(f" - {STYLE32_DIR}") + print() + + moved_count = 0 + renamed_count = 0 + skipped_count = 0 + + # Create manifest for tracking + manifest = { + "total_processed": 0, + "moved": 0, + "renamed": 0, + "skipped": 0, + "assets": [] + } + + # Process all PNG files in both directories + all_images = [] + all_images.extend(SLIKE_DIR.rglob("*.png")) + all_images.extend(STYLE32_DIR.glob("*.png")) + + print(f"📊 Found {len(all_images)} images to process\n") + + for img_path in all_images: + category, subfolder = detect_category_and_subfolder(img_path.name) + new_name = generate_smart_name(img_path, category, subfolder) + + # Determine target directory + target_dir = SLIKE_DIR / category + if subfolder: + target_dir = target_dir / subfolder + + target_path = target_dir / new_name + + # Check if file already exists at target + if target_path.exists() and target_path != img_path: + print(f"⚠️ SKIP (exists): {img_path.name}") + skipped_count += 1 + continue + + # Create directory if needed + if not dry_run: + target_dir.mkdir(parents=True, exist_ok=True) + + # Show what we're doing + if img_path != target_path: + action = "MOVE" if img_path.parent != target_path.parent else "RENAME" + print(f"✅ {action}: {img_path.name}") + print(f" → {target_path.relative_to(ASSETS_DIR)}") + print() + + if action == "MOVE": + moved_count += 1 + else: + renamed_count += 1 + + # Actually move/rename if not dry run + if not dry_run: + shutil.move(str(img_path), str(target_path)) + + # Add to manifest + manifest["assets"].append({ + "original": str(img_path.relative_to(PROJECT_ROOT)), + "new": str(target_path.relative_to(PROJECT_ROOT)), + "category": category, + "subfolder": subfolder, + "action": action.lower() + }) + + # Update manifest totals + manifest["total_processed"] = len(all_images) + manifest["moved"] = moved_count + manifest["renamed"] = renamed_count + manifest["skipped"] = skipped_count + + # Save manifest + if not dry_run: + manifest_path = PROJECT_ROOT / "docs" / "ASSET_ORGANIZATION_MANIFEST.json" + with open(manifest_path, 'w', encoding='utf-8') as f: + json.dump(manifest, f, indent=2, ensure_ascii=False) + print(f"\n📄 Manifest saved to: {manifest_path}") + + # Print summary + print("\n" + "="*60) + print("📊 ORGANIZATION SUMMARY") + print("="*60) + print(f"Total Processed: {len(all_images)}") + print(f"Moved: {moved_count}") + print(f"Renamed: {renamed_count}") + print(f"Skipped: {skipped_count}") + + if dry_run: + print("\n⚠️ DRY RUN MODE - No files were actually moved") + print(" Run with --execute to apply changes") + else: + print("\n✅ Organization complete!") + + +def print_category_preview(): + """Print a preview of how files would be categorized""" + print("\n📂 CATEGORY STRUCTURE PREVIEW:") + print("="*60) + + for category, subfolders in TARGET_STRUCTURE.items(): + if isinstance(subfolders, dict): + print(f"\n📁 {category.upper()}/") + for subfolder in subfolders.keys(): + print(f" └── {subfolder}/") + else: + print(f"\n📁 {category.upper()}/") + + +if __name__ == "__main__": + import sys + + print("🎨 DolinaSmrti - Smart Asset Organization System") + print("="*60) + + # Check if --execute flag is provided + execute = "--execute" in sys.argv or "-e" in sys.argv + preview_only = "--preview" in sys.argv or "-p" in sys.argv + + if preview_only: + print_category_preview() + else: + print(f"\nMode: {'EXECUTE' if execute else 'DRY RUN'}") + print() + organize_assets(dry_run=not execute) + + if not execute: + print("\n💡 TIP: Run with --execute to actually move files") + print(" Run with --preview to see category structure") diff --git a/tools/asset_gallery.html b/tools/asset_gallery.html new file mode 100644 index 000000000..4e31cfc9c --- /dev/null +++ b/tools/asset_gallery.html @@ -0,0 +1,549 @@ + + + + + + + 🎨 DolinaSmrti Asset Gallery - 1,166 Slik + + + + +
+

🎨 DolinaSmrti Asset Gallery

+
+
+
1,166
+
Skupaj Slik
+
+
+
576 MB
+
Velikost
+
+
+
0
+
Prikazanih
+
+
+
+ +
+ + 🔍 +
+ +
+
📁 Filter po Kategoriji:
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + \ No newline at end of file