diff --git a/dist/renamer-0.7.8-py3-none-any.whl b/dist/renamer-0.7.8-py3-none-any.whl new file mode 100644 index 0000000..71f573c Binary files /dev/null and b/dist/renamer-0.7.8-py3-none-any.whl differ diff --git a/pyproject.toml b/pyproject.toml index 531e1f9..7d4e6ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "renamer" -version = "0.7.7" +version = "0.7.8" 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 f6a0a86..1bbab4f 100644 --- a/renamer/app.py +++ b/renamer/app.py @@ -66,14 +66,15 @@ class AppCommandProvider(Provider): commands = [ ("open", "Open Directory", "Open a directory to browse media files (o)"), - ("scan", "Scan Directory", "Scan current directory for media files (s)"), + ("scan_local", "Scan Node", "Scan current node's directory only (s)"), + ("scan", "Scan Tree", "Scan entire directory tree (Ctrl+S)"), ("refresh", "Refresh File", "Refresh metadata for selected file (f)"), ("rename", "Rename File", "Rename the selected file (r)"), ("convert", "Convert to MKV", "Convert AVI/MPG/MPEG/WebM/MP4 file to MKV container with metadata (c)"), ("delete", "Delete File", "Delete the selected file (d)"), ("toggle_mode", "Toggle Display Mode", "Switch between technical and catalog view (m)"), - ("expand", "Toggle Tree Expansion", "Expand or collapse all tree nodes (p)"), - ("settings", "Settings", "Open settings screen (Ctrl+S)"), + ("expand", "Toggle Tree Expansion", "Expand or collapse all tree nodes (t)"), + ("settings", "Settings", "Open settings screen (p)"), ("help", "Help", "Show keyboard shortcuts and help (h)"), ] @@ -102,15 +103,16 @@ class RenamerApp(App): BINDINGS = [ ("q", "quit", "Quit"), ("o", "open", "Open directory"), - ("s", "scan", "Scan"), + ("s", "scan_local", "Scan Node"), + ("ctrl+s", "scan", "Scan Tree"), ("f", "refresh", "Refresh"), ("r", "rename", "Rename"), ("c", "convert", "Convert to MKV"), ("d", "delete", "Delete"), - ("p", "expand", "Toggle Tree"), + ("t", "expand", "Toggle Tree"), ("m", "toggle_mode", "Toggle Mode"), ("h", "help", "Help"), - ("ctrl+s", "settings", "Settings"), + ("p", "settings", "Settings"), ] # Command palette - extend built-in commands with cache and app commands @@ -298,6 +300,36 @@ class RenamerApp(App): if self.scan_dir: self.scan_files() + async def action_scan_local(self): + """Scan only the current node's directory (refresh node).""" + tree = self.query_one("#file_tree", Tree) + node = tree.cursor_node + + if not node or not node.data: + self.notify("Please select a node first", severity="warning", timeout=3) + return + + # Get the directory to scan + path = node.data + if path.is_file(): + # If it's a file, scan its parent directory + path = path.parent + # Find the parent node in the tree + if node.parent: + node = node.parent + else: + self.notify("Cannot scan root level file", severity="warning", timeout=3) + return + + # Clear the node and rescan + node.remove_children() + self.build_tree(path, node) + + # Expand the node to show new content + node.expand() + + self.notify(f"Rescanned: {path.name}", severity="information", timeout=2) + async def action_refresh(self): tree = self.query_one("#file_tree", Tree) node = tree.cursor_node @@ -384,10 +416,9 @@ By Category:""" proposed_formatter = ProposedFilenameView(extractor) new_name = str(proposed_formatter) logging.info(f"Proposed new name: {new_name!r} for file: {node.data}") - if new_name and new_name != node.data.name: + # Always open rename dialog, even if names are the same (user might want to manually edit) + if new_name: self.push_screen(RenameConfirmScreen(node.data, new_name)) - else: - self.notify("Proposed name is the same as current name; no rename needed.", severity="information", timeout=3) async def action_convert(self): """Convert AVI/MPG/MPEG/WebM/MP4 file to MKV with metadata preservation.""" diff --git a/renamer/screens.py b/renamer/screens.py index 429cf52..7ccab38 100644 --- a/renamer/screens.py +++ b/renamer/screens.py @@ -180,6 +180,12 @@ Do you want to proceed with renaming? def on_button_pressed(self, event): if event.button.id == "rename": + # Check if new name is the same as old name + if self.new_name == self.old_path.name: + self.app.notify("Proposed name is the same as current name; no rename needed.", severity="information", timeout=3) + self.app.pop_screen() + return + try: logging.info(f"Starting rename: old_path={self.old_path}, new_path={self.new_path}") logging.info(f"Old file name: {self.old_path.name}") @@ -495,7 +501,7 @@ class ConvertConfirmScreen(Screen): yield Static(details_text, id="conversion_details", markup=True) yield Static(info_text, id="info_text", markup=True) with Horizontal(id="buttons"): - yield Button("Convert Copy (c)", id="convert_copy", variant="success") + yield Button("Convert Copy (y)", id="convert_copy", variant="success") yield Button("Convert HEVC (e)", id="convert_hevc", variant="primary") yield Button("Cancel (n)", id="cancel", variant="error") @@ -574,7 +580,7 @@ class ConvertConfirmScreen(Screen): self.app.pop_screen() # type: ignore def on_key(self, event): - if event.key == "c": + if event.key == "y": # Copy mode self._do_conversion(encode_hevc=False) elif event.key == "e": diff --git a/uv.lock b/uv.lock index d018a74..46c3ab7 100644 --- a/uv.lock +++ b/uv.lock @@ -462,7 +462,7 @@ wheels = [ [[package]] name = "renamer" -version = "0.7.7" +version = "0.7.8" source = { editable = "." } dependencies = [ { name = "langcodes" },