From 514607eddda6444e6c1006811ff5b6ba027a2fe1 Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Fri, 19 Jun 2026 13:54:32 +0200 Subject: [PATCH] fix: harden export-folder base derivation against a trailing slash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A folder ending in "/" made os.path.basename() return "", so subprofile folders/labels became "_blowjob" instead of "mp4_blowjob" — cluttering the subcategory menu and breaking the marker↔category match. rstrip the trailing separator in _tab_export_folder and the three basename(_txt_folder) sites. Co-Authored-By: Claude Fable 5 --- main.py | 11 +++++++---- tests/test_ui_structure.py | 9 +++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/main.py b/main.py index 0461512..fde58ff 100755 --- a/main.py +++ b/main.py @@ -4991,7 +4991,10 @@ class MainWindow(QMainWindow): def _tab_export_folder(self) -> str: """The export base folder, with the active tab name appended when its per-tab 'Export to tab-named folder' option is enabled.""" - base = self._txt_folder.text() + # rstrip the trailing separator so basename()/suffix logic downstream + # never sees an empty base (a folder like ".../mp4/" → base "" broke + # subprofile naming, e.g. "_blowjob" instead of "mp4_blowjob"). + base = self._txt_folder.text().rstrip("/" + os.sep) pw = self._playlist if pw is not None and getattr(pw, "_tab_folder", False): name = self._active_tab_name() @@ -5872,7 +5875,7 @@ class MainWindow(QMainWindow): self._playlist.set_folder_counts(folder_counts) self._playlist.set_disabled_paths(disabled_paths) # Profile-wide subcategory counts (exclude the main export folder). - base = os.path.basename(self._txt_folder.text()) + base = os.path.basename(self._txt_folder.text().rstrip("/" + os.sep)) self._playlist.set_all_subcat_counts( {f: c for f, c in all_counts.items() if f != base}) @@ -6544,7 +6547,7 @@ class MainWindow(QMainWindow): from PyQt6.QtWidgets import QMenu, QWidgetAction, QCheckBox, QWidget, QVBoxLayout, QPushButton, QHBoxLayout menu = QMenu(self) menu.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose) - base = os.path.basename(self._txt_folder.text()) + base = os.path.basename(self._txt_folder.text().rstrip("/" + os.sep)) counts = self._db.get_all_folder_counts(self._profile) folder_set: set[str] = set() # Subcategories from the current video's markers … @@ -6619,7 +6622,7 @@ class MainWindow(QMainWindow): def _disable_all_subcats(self) -> None: """Disable every enabled subcategory at once (across all videos).""" - base = os.path.basename(self._txt_folder.text()) + base = os.path.basename(self._txt_folder.text().rstrip("/" + os.sep)) counts = self._db.get_all_folder_counts(self._profile) folders = sorted(f for f, c in counts.items() if c and f != base and not f.endswith("_disabled")) diff --git a/tests/test_ui_structure.py b/tests/test_ui_structure.py index 37558e2..5128b0e 100644 --- a/tests/test_ui_structure.py +++ b/tests/test_ui_structure.py @@ -213,3 +213,12 @@ def test_frames_snaps_to_legal(win): win._snap_frames_to_legal() # the editingFinished slot assert win._spn_frames.value() == 97 # nearest 8k+1 to 100 assert (win._spn_frames.value() - 1) % 8 == 0 + + +def test_export_base_name_handles_trailing_slash(win): + # A folder ending in "/" must still yield the real base name, else + # subprofile naming breaks ("_blowjob" instead of "mp4_blowjob"). + win._txt_folder.setText("/x/AlexisCrystal/mp4/") + assert win._export_base_name() == "mp4" + win._txt_folder.setText("/x/AlexisCrystal/mp4") + assert win._export_base_name() == "mp4"