#!/usr/bin/env python3 """ šŸ”„ RESTORE HIERARCHICAL BIOME STRUCTURE Converts ultra-flat assets/slike/ back to hierarchical DLC-pack structure BEFORE (Ultra-Flat): assets/slike/ ā”œā”€ā”€ dinozavri/ │ ā”œā”€ā”€ dino_trex_stylea.png │ ā”œā”€ā”€ dino_trex_styleb.png │ ā”œā”€ā”€ dino_leather_vest_stylea.png # MIXED! │ └── stone_spear_stylea.png # MIXED! AFTER (Hierarchical DLC-Pack): assets/slike/ ā”œā”€ā”€ dinozavri/ │ ā”œā”€ā”€ fauna/ │ │ ā”œā”€ā”€ dino_trex_stylea.png │ │ └── dino_trex_styleb.png │ ā”œā”€ā”€ clothing/ │ │ ā”œā”€ā”€ dino_leather_vest_stylea.png │ │ └── caveman_loincloth_stylea.png │ ā”œā”€ā”€ weapons/ │ │ ā”œā”€ā”€ stone_spear_stylea.png │ │ └── dino_bone_club_stylea.png │ ā”œā”€ā”€ food/ │ ā”œā”€ā”€ materials/ │ ā”œā”€ā”€ terrain/ │ ā”œā”€ā”€ vegetation/ │ ā”œā”€ā”€ props/ │ └── buildings/ """ import shutil from pathlib import Path import re REPO = Path("/Users/davidkotnik/repos/novafarma") ASSETS = REPO / "assets/slike" # Define categorization patterns CATEGORIES = { # FAUNA (dinosaurs, creatures) - specific files first "fauna": [ r"^dino_(trex|alpha_trex_boss|velociraptor|triceratops|brontosaurus|pterodactyl|stegosaurus|ankylosaurus|spinosaurus|dilophosaurus|compsognathus|parasaurolophus|pachycephalosaurus|thunder_raptor_boss|baby_trex|eggs_nest)_(stylea|styleb).*\.png$", ], # CLOTHING & ARMOR "clothing": [ r".*_(vest|loincloth|outfit|helmet|coat|armor|boots|cape|pauldrons)_.*\.png$", r"^(dino_leather_vest|caveman_loincloth|paleontologist_outfit|dino_bone_helmet|pterodactyl_leather_coat|dino_scale_armor|raptor_claw_boots|caveman_fur_cape|bone_plate_pauldrons)_.*\.png$" ], # WEAPONS "weapons": [ r".*_(spear|club|arrow|dagger|sword|mace|axe|bow|knife|blade|shield|necklace_charm)_.*\.png$", r"^(stone_spear|dino_bone_club|pterodactyl_feather_arrows|raptor_claw_dagger|triceratops_horn_sword|ankylosaurus_tail_mace|stone_axe|bone_bow|flint_knife|volcanic_glass_blade|stegosaurus_plate_shield|tooth_necklace_charm)_.*\.png$" ], # CROPS & FOOD "food": [ r".*_(fern|berries|cycad|horsetail|egg_consumable|meat|omelette|salad|tea|spice)_.*\.png$", r"^(prehistoric_fern|ancient_berries|cycad_fruit_tree|horsetail_plant|dino_egg_consumable|roasted_dino_meat|pterodactyl_egg_omelette|ancient_fruit_salad|fern_tea|volcanic_spice)_.*\.png$" ], # MATERIALS & RESOURCES "materials": [ r"^(dino_leather|trex_tooth|pterodactyl_feathers|raptor_claws|dino_bones|volcanic_rock|amber_chunk|fossil)_.*\.png$" ], # TERRAIN "terrain": [ r".*_(tile|crack|pit|springs|ash|grass|mud|path)_.*\.png$", r"^(volcanic_rock_tile|lava_cracks|tar_pit_tile|hot_springs_tile|volcanic_ash_ground|jungle_grass_tile|muddy_ground|rocky_path)_.*\.png$" ], # VEGETATION "vegetation": [ r"^(giant_fern|cycad_tree|horsetail_reed|prehistoric_vines|moss_covered_boulder)_.*\.png$" ], # PROPS "props": [ r".*_(skeleton|fossil_in_rock|amber_chunk_large|steam_vent|lava_pool|footprint|bone_pile|volcanic_boulder|prehistoric_mushroom)_.*\.png$", r"^(dino_skeleton_trex|dino_skeleton_raptor|fossil_in_rock|amber_chunk_large|steam_vent|lava_pool|dino_footprint|bone_pile|volcanic_boulder|prehistoric_mushroom_cluster)_.*\.png$" ], # BUILDINGS "buildings": [ r"^(caveman_hut|stone_altar|dino_pen|bone_fence|volcanic_forge|pterodactyl_roost)_.*\.png$" ] } def categorize_file(filename: str) -> str: """Determine which category a file belongs to""" for category, patterns in CATEGORIES.items(): for pattern in patterns: if re.match(pattern, filename, re.IGNORECASE): return category return None def reorganize_biome(biome_dir: Path): """Reorganize a single biome directory into hierarchical structure""" if not biome_dir.is_dir(): return print(f"\nšŸ“‚ Processing: {biome_dir.name}") # Get all PNG files directly in biome directory files = list(biome_dir.glob("*.png")) if not files: print(f" ā­ļø No files to organize") return stats = {cat: 0 for cat in CATEGORIES.keys()} stats['uncategorized'] = 0 for file in files: category = categorize_file(file.name) if category: # Create category subfolder category_dir = biome_dir / category category_dir.mkdir(exist_ok=True) # Move file target = category_dir / file.name if not target.exists(): shutil.move(str(file), str(target)) stats[category] += 1 print(f" āœ… {file.name} → {category}/") else: stats['uncategorized'] += 1 print(f" āš ļø {file.name} - NO CATEGORY MATCH") # Print stats print(f"\n šŸ“Š Statistics:") for cat, count in stats.items(): if count > 0: print(f" {cat}: {count} files") def main(): print("="*70) print("šŸ”„ RESTORE HIERARCHICAL BIOME STRUCTURE") print("="*70) print("\nConverting ultra-flat to DLC-pack hierarchy...") print("\nProcessing biomes:\n") # Process specific biomes biomes_to_process = [ "dinozavri", # Add more as needed: # "mythical_highlands", # "endless_forest", # "loch_ness", # "egyptian_desert", ] for biome_name in biomes_to_process: biome_dir = ASSETS / biome_name reorganize_biome(biome_dir) print("\n" + "="*70) print("āœ… REORGANIZATION COMPLETE!") print("="*70) print("\nEach biome now has subfolders:") print(" - fauna/") print(" - clothing/") print(" - weapons/") print(" - food/") print(" - materials/") print(" - terrain/") print(" - vegetation/") print(" - props/") print(" - buildings/") if __name__ == "__main__": main()