From 8b97dbc58c4fe47062f06c9564f06a52776f9385 Mon Sep 17 00:00:00 2001 From: LemonNexus Date: Wed, 11 Feb 2026 18:00:01 +0000 Subject: [PATCH] fix: standalone extractor - hardcoded path + subfolder support - Hardcoded base path: C:/ProgramData/Entropia Universe/public_users_data/cache/icon - Added version subfolder selector dropdown - Shows icon count per subfolder - "All Folders" option to merge from all subfolders - Checkbox to include ALL subfolders at once - Files list shows folder prefix (e.g., "19.3.2.201024/icon001.tga") - Refresh button to re-scan for subfolders - Auto-scan now properly detects and lists version folders --- standalone_icon_extractor.py | 137 +++++++++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 24 deletions(-) diff --git a/standalone_icon_extractor.py b/standalone_icon_extractor.py index 4048b4f..6017d29 100644 --- a/standalone_icon_extractor.py +++ b/standalone_icon_extractor.py @@ -248,12 +248,16 @@ class IconExtractorWindow(QMainWindow): self.converter = TGAConverter() self.worker: Optional[ConversionWorker] = None self.found_files: List[Path] = [] + self.current_subfolder: Optional[Path] = None + + # Hardcoded base cache path + self.base_cache_path = Path("C:/ProgramData/Entropia Universe/public_users_data/cache/icon") self.settings = QSettings("Lemontropia", "IconExtractor") self._setup_ui() self._load_settings() - self._auto_scan() + self._detect_subfolders() def _setup_ui(self): """Setup the UI.""" @@ -288,10 +292,35 @@ class IconExtractorWindow(QMainWindow): cache_group = QGroupBox("📁 Cache Folder") cache_layout = QVBoxLayout(cache_group) - self.cache_label = QLabel("Not found") + # Base path (hardcoded) + base_label = QLabel("Base Path:") + cache_layout.addWidget(base_label) + + self.cache_label = QLabel(str(self.base_cache_path)) self.cache_label.setStyleSheet("font-family: Consolas; color: #888; padding: 5px; background: #1a1a1a; border-radius: 3px;") cache_layout.addWidget(self.cache_label) + # Subfolder selector + subfolder_layout = QHBoxLayout() + subfolder_layout.addWidget(QLabel("Version Folder:")) + self.subfolder_combo = QComboBox() + self.subfolder_combo.setMinimumWidth(200) + self.subfolder_combo.currentIndexChanged.connect(self._on_subfolder_changed) + subfolder_layout.addWidget(self.subfolder_combo) + + refresh_btn = QPushButton("🔄 Refresh") + refresh_btn.clicked.connect(self._detect_subfolders) + subfolder_layout.addWidget(refresh_btn) + + subfolder_layout.addStretch() + cache_layout.addLayout(subfolder_layout) + + # All subfolders checkbox + self.all_subfolders_check = QCheckBox("Include ALL subfolders (merge everything)") + self.all_subfolders_check.setToolTip("If checked, will find TGA files from ALL version subfolders") + self.all_subfolders_check.stateChanged.connect(self._on_all_subfolders_changed) + cache_layout.addWidget(self.all_subfolders_check) + cache_btn_layout = QHBoxLayout() scan_btn = QPushButton("🔍 Auto-Detect") @@ -456,47 +485,107 @@ class IconExtractorWindow(QMainWindow): self.settings.setValue("canvas_size_index", self.size_combo.currentIndex()) self.settings.setValue("upscale_method_index", self.method_combo.currentIndex()) + def _detect_subfolders(self): + """Detect version subfolders in the cache directory.""" + self.subfolder_combo.clear() + + if not self.base_cache_path.exists(): + self.cache_label.setText(f"❌ Not found: {self.base_cache_path}") + self.status_label.setText("Cache folder not found - check if path is correct") + return + + # Find all subfolders that contain TGA files + subfolders = [] + for item in self.base_cache_path.iterdir(): + if item.is_dir(): + # Check if this folder has TGA files + tga_count = len(list(item.glob("*.tga"))) + if tga_count > 0: + subfolders.append((item.name, tga_count, item)) + + if not subfolders: + self.cache_label.setText(f"⚠️ No subfolders with TGA files in {self.base_cache_path}") + self.status_label.setText("No version folders found") + return + + # Sort by name (version) + subfolders.sort(key=lambda x: x[0]) + + # Add to combo + for name, count, path in subfolders: + self.subfolder_combo.addItem(f"{name} ({count} icons)", str(path)) + + # Add "All folders" option at top + total_icons = sum(s[1] for s in subfolders) + self.subfolder_combo.insertItem(0, f"📁 All Folders ({total_icons} icons)", "all") + self.subfolder_combo.setCurrentIndex(0) + + self.cache_label.setText(f"✅ {self.base_cache_path}") + self.status_label.setText(f"Found {len(subfolders)} version folders") + + # Load files + self._refresh_file_list() + + def _on_subfolder_changed(self): + """Handle subfolder selection change.""" + self._refresh_file_list() + + def _on_all_subfolders_changed(self): + """Handle 'all subfolders' checkbox change.""" + self.subfolder_combo.setEnabled(not self.all_subfolders_check.isChecked()) + self._refresh_file_list() + def _auto_scan(self): - """Auto-detect cache folder.""" - self.status_label.setText("Scanning for cache folder...") - - cache_path = self.converter.find_cache_folder() - - if cache_path: - self.cache_label.setText(str(cache_path)) - self._refresh_file_list(cache_path) - else: - self.cache_label.setText("❌ Not found - click Browse to select manually") - self.status_label.setText("Cache folder not found") + """Auto-detect cache folder - just refreshes subfolder list.""" + self.status_label.setText("Scanning for version folders...") + self._detect_subfolders() def _browse_cache(self): """Browse for cache folder.""" folder = QFileDialog.getExistingDirectory( self, "Select Entropia Universe Cache Folder", - str(Path("C:") / "ProgramData") + str(self.base_cache_path.parent) ) if folder: - path = Path(folder) - self.converter._cache_path = path - self.cache_label.setText(str(path)) - self._refresh_file_list(path) + self.base_cache_path = Path(folder) + self.cache_label.setText(str(self.base_cache_path)) + self._detect_subfolders() - def _refresh_file_list(self, cache_path: Path): - """Refresh the list of found files.""" + def _refresh_file_list(self): + """Refresh the list of found files based on current selection.""" self.files_list.clear() self.found_files = [] - # Search all subfolders for TGA files - tga_files = list(cache_path.rglob("*.tga")) + if not self.base_cache_path.exists(): + return + + # Determine which folders to scan + if self.all_subfolders_check.isChecked(): + # Scan all subfolders + folders_to_scan = [d for d in self.base_cache_path.iterdir() if d.is_dir()] + else: + # Scan selected subfolder + path_data = self.subfolder_combo.currentData() + if path_data == "all" or path_data is None: + folders_to_scan = [d for d in self.base_cache_path.iterdir() if d.is_dir()] + else: + folders_to_scan = [Path(path_data)] + + # Collect TGA files + tga_files = [] + for folder in folders_to_scan: + if folder.exists(): + tga_files.extend(folder.glob("*.tga")) self.files_count_label.setText(f"Found {len(tga_files)} icon files") - self.status_label.setText(f"Found {len(tga_files)} files in {cache_path}") + self.status_label.setText(f"Found {len(tga_files)} files") for tga_file in sorted(tga_files): + # Show folder prefix for clarity try: - rel_path = str(tga_file.relative_to(cache_path)) + rel_path = f"{tga_file.parent.name}/{tga_file.name}" except: rel_path = tga_file.name