diff --git a/dist/renamer-0.6.7-py3-none-any.whl b/dist/renamer-0.6.7-py3-none-any.whl new file mode 100644 index 0000000..3d09303 Binary files /dev/null and b/dist/renamer-0.6.7-py3-none-any.whl differ diff --git a/pyproject.toml b/pyproject.toml index ac67466..21c27ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "renamer" -version = "0.6.6" +version = "0.6.7" description = "Terminal-based media file renamer and metadata viewer" readme = "README.md" requires-python = ">=3.11" diff --git a/renamer/app.py b/renamer/app.py index 93287bb..faedb93 100644 --- a/renamer/app.py +++ b/renamer/app.py @@ -465,18 +465,33 @@ By Category:""" tree = self.query_one("#file_tree", Tree) parent_dir = file_path.parent + logging.info(f"Looking for parent directory node: {parent_dir}") + logging.info(f"Scan directory: {self.scan_dir}") - # Find the parent directory node - def find_node(node): - if node.data == parent_dir: - return node - for child in node.children: - found = find_node(child) - if found: - return found - return None + # Check if parent directory is the scan directory (root level) + # If so, the parent node is the tree root itself + parent_node = None + + if self.scan_dir and parent_dir.resolve() == self.scan_dir.resolve(): + logging.info("File is in root scan directory, using tree.root as parent") + parent_node = tree.root + else: + # Find the parent directory node in the tree + def find_node(node, depth=0): + if node.data and isinstance(node.data, Path): + logging.info(f"{' ' * depth}Checking node: data={node.data}") + # Resolve both paths to absolute for comparison + if node.data.resolve() == parent_dir.resolve(): + logging.info(f"{' ' * depth}Found match! node.data={node.data}") + return node + for child in node.children: + found = find_node(child, depth + 1) + if found: + return found + return None + + parent_node = find_node(tree.root) - parent_node = find_node(tree.root) if parent_node: logging.info(f"Found parent node for {parent_dir}, adding file {file_path.name}") @@ -511,6 +526,9 @@ By Category:""" ).start() else: logging.warning(f"No parent node found for {parent_dir}") + logging.warning(f"Rescanning entire tree instead") + # If we can't find the parent node, just rescan the whole tree + self.scan_files() def on_key(self, event): if event.key == "right": diff --git a/renamer/screens.py b/renamer/screens.py index dcc959f..e51a3f8 100644 --- a/renamer/screens.py +++ b/renamer/screens.py @@ -437,32 +437,11 @@ Do you want to proceed with conversion? def on_mount(self): self.set_focus(self.query_one("#convert")) - def _handle_conversion_success(self, mkv_path, message): - """Handle successful conversion - called on main thread.""" - import logging - try: - logging.info(f"_handle_conversion_success called: {mkv_path}") - self.app.notify(f"✓ {message}", severity="information", timeout=5) # type: ignore - logging.info(f"Adding file to tree: {mkv_path}") - self.app.add_file_to_tree(mkv_path) # type: ignore - logging.info("Conversion success handler completed") - except Exception as e: - logging.error(f"Error in _handle_conversion_success: {e}", exc_info=True) - - def _handle_conversion_error(self, message): - """Handle conversion error - called on main thread.""" - import logging - try: - logging.info(f"_handle_conversion_error called: {message}") - self.app.notify(f"✗ {message}", severity="error", timeout=10) # type: ignore - logging.info("Conversion error handler completed") - except Exception as e: - logging.error(f"Error in _handle_conversion_error: {e}", exc_info=True) - def on_button_pressed(self, event): if event.button.id == "convert": # Start conversion - self.app.notify("Starting conversion...", severity="information", timeout=2) # type: ignore + app = self.app # type: ignore + app.notify("Starting conversion...", severity="information", timeout=2) def do_conversion(): from .services.conversion_service import ConversionService @@ -479,23 +458,27 @@ Do you want to proceed with conversion? logging.info(f"Conversion result: success={success}, message={message}") - # Schedule UI updates on the main thread using set_timer + # Schedule UI updates on the main thread mkv_path = self.avi_path.with_suffix('.mkv') + def handle_success(): + logging.info(f"handle_success called: {mkv_path}") + app.notify(f"✓ {message}", severity="information", timeout=5) + logging.info(f"Adding file to tree: {mkv_path}") + app.add_file_to_tree(mkv_path) + logging.info("Conversion success handler completed") + + def handle_error(): + logging.info(f"handle_error called: {message}") + app.notify(f"✗ {message}", severity="error", timeout=10) + logging.info("Conversion error handler completed") + if success: logging.info(f"Conversion successful, scheduling UI update for {mkv_path}") - - # Use app.set_timer to schedule callback on main thread - self.app.set_timer( - 0.1, # Small delay to ensure main thread processes it - lambda: self._handle_conversion_success(mkv_path, message) - ) # type: ignore + app.call_later(handle_success) else: logging.error(f"Conversion failed: {message}") - self.app.set_timer( - 0.1, - lambda: self._handle_conversion_error(message) - ) # type: ignore + app.call_later(handle_error) # Run conversion in background thread import threading diff --git a/renamer/views/media_panel.py b/renamer/views/media_panel.py index d3a8014..bd76907 100644 --- a/renamer/views/media_panel.py +++ b/renamer/views/media_panel.py @@ -37,9 +37,9 @@ class MediaPanelView: self._props.media_year, self._props.media_duration, self._props.media_file_size, + self._props.media_file_extension, self._props.selected_frame_class, self._props.selected_source, - self._props.selected_special_info, self._props.selected_audio_langs, self._props.selected_database_info, self._props.selected_order, diff --git a/renamer/views/media_panel_properties.py b/renamer/views/media_panel_properties.py index 95eeb6a..591ea38 100644 --- a/renamer/views/media_panel_properties.py +++ b/renamer/views/media_panel_properties.py @@ -375,6 +375,15 @@ class MediaPanelProperties: def media_file_size(self) -> str: """Get media file size formatted with label.""" return self._extractor.get("file_size") + + @property + @text_decorators.blue() + @conditional_decorators.wrap("Extension: ") + @text_decorators.green() + @extension_decorators.extension_info() + def media_file_extension(self) -> str: + """Get media file extension formatted with label.""" + return self._extractor.get("extension") @property @text_decorators.blue() diff --git a/uv.lock b/uv.lock index ed5d4d2..6ce70af 100644 --- a/uv.lock +++ b/uv.lock @@ -462,7 +462,7 @@ wheels = [ [[package]] name = "renamer" -version = "0.6.6" +version = "0.6.7" source = { editable = "." } dependencies = [ { name = "langcodes" },