From 6c257f9671135984028162ec1fa70aeb3fb7b810 Mon Sep 17 00:00:00 2001 From: purpletennisball <212221402+purpletennisball@users.noreply.github.com> Date: Mon, 25 Aug 2025 14:39:21 -0400 Subject: [PATCH] fix: folders with names of unlinked entries are linked (#1027) * fix: render folder entries as unlinked * fix: hide file size for linked folders * fix: linked folders can be revealed in explorer * fix: linked folders can be opened * fix: linked folders can be deleted * fix: skip rendering thumbnails in `ThumbRenderer._render` * fix: skip getting image metadata for folders * fix: conflicts * style: ruff --- src/tagstudio/core/utils/missing_files.py | 2 ++ .../controller/widgets/preview/preview_thumb_controller.py | 4 +++- src/tagstudio/qt/helpers/file_deleter.py | 2 ++ src/tagstudio/qt/helpers/file_opener.py | 6 ++++-- src/tagstudio/qt/widgets/preview/file_attributes.py | 2 +- src/tagstudio/qt/widgets/thumb_renderer.py | 6 +++--- 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/tagstudio/core/utils/missing_files.py b/src/tagstudio/core/utils/missing_files.py index 234129c6..6326a2b9 100644 --- a/src/tagstudio/core/utils/missing_files.py +++ b/src/tagstudio/core/utils/missing_files.py @@ -50,6 +50,8 @@ class MissingRegistry: flags=PATH_GLOB_FLAGS, exclude=ignore_patterns, ): + if path.is_dir(): + continue if path.name == match_entry.path.name: new_path = Path(path).relative_to(self.library.library_dir) matches.append(new_path) diff --git a/src/tagstudio/qt/controller/widgets/preview/preview_thumb_controller.py b/src/tagstudio/qt/controller/widgets/preview/preview_thumb_controller.py index 17b1592f..017d8762 100644 --- a/src/tagstudio/qt/controller/widgets/preview/preview_thumb_controller.py +++ b/src/tagstudio/qt/controller/widgets/preview/preview_thumb_controller.py @@ -39,7 +39,9 @@ class PreviewThumb(PreviewThumbView): stats = FileAttributeData() ext = filepath.suffix.lower() - if MediaCategories.IMAGE_RAW_TYPES.contains(ext, mime_fallback=True): + if filepath.is_dir(): + pass + elif MediaCategories.IMAGE_RAW_TYPES.contains(ext, mime_fallback=True): try: with rawpy.imread(str(filepath)) as raw: rgb = raw.postprocess() diff --git a/src/tagstudio/qt/helpers/file_deleter.py b/src/tagstudio/qt/helpers/file_deleter.py index b384588c..1e264b07 100644 --- a/src/tagstudio/qt/helpers/file_deleter.py +++ b/src/tagstudio/qt/helpers/file_deleter.py @@ -21,6 +21,8 @@ def delete_file(path: str | Path) -> bool: """ _path = Path(path) try: + if _path.is_dir(): + return False logger.info(f"[delete_file] Sending to Trash: {_path}") send2trash(_path) return True diff --git a/src/tagstudio/qt/helpers/file_opener.py b/src/tagstudio/qt/helpers/file_opener.py index 984793a6..972d23af 100644 --- a/src/tagstudio/qt/helpers/file_opener.py +++ b/src/tagstudio/qt/helpers/file_opener.py @@ -109,11 +109,13 @@ class FileOpenerHelper: def open_file(self): """Open the file in the default application.""" - open_file(self.filepath) + if Path(self.filepath).is_file(): + open_file(self.filepath) def open_explorer(self): """Open the file in the default file explorer.""" - open_file(self.filepath, file_manager=True) + if Path(self.filepath).is_file(): + open_file(self.filepath, file_manager=True) class FileOpenerLabel(QLabel): diff --git a/src/tagstudio/qt/widgets/preview/file_attributes.py b/src/tagstudio/qt/widgets/preview/file_attributes.py index 97fc4b63..26e1ce6e 100644 --- a/src/tagstudio/qt/widgets/preview/file_attributes.py +++ b/src/tagstudio/qt/widgets/preview/file_attributes.py @@ -193,7 +193,7 @@ class FileAttributes(QWidget): # Attempt to populate the stat variables ext_display = ext.upper()[1:] or filepath.stem.upper() - if filepath: + if filepath and filepath.is_file(): try: file_size = format_size(filepath.stat().st_size) diff --git a/src/tagstudio/qt/widgets/thumb_renderer.py b/src/tagstudio/qt/widgets/thumb_renderer.py index 3657d3a3..f660a974 100644 --- a/src/tagstudio/qt/widgets/thumb_renderer.py +++ b/src/tagstudio/qt/widgets/thumb_renderer.py @@ -1454,7 +1454,7 @@ class ThumbRenderer(QObject): if not image: image = ( render_unlinked((adj_size, adj_size), pixel_ratio) - if not filepath.exists() + if not filepath.exists() or filepath.is_dir() else render_default((adj_size, adj_size), pixel_ratio) ) render_mask_and_edge = False @@ -1498,7 +1498,7 @@ class ThumbRenderer(QObject): if not image: image = ( render_unlinked((512, 512), 2) - if not filepath.exists() + if not filepath.exists() or filepath.is_dir() else render_default((512, 512), 2) ) render_mask_and_edge = False @@ -1560,7 +1560,7 @@ class ThumbRenderer(QObject): _filepath: Path = Path(filepath) savable_media_type: bool = True - if _filepath: + if _filepath and _filepath.is_file(): try: ext: str = _filepath.suffix.lower() if _filepath.suffix else _filepath.stem.lower() # Images =======================================================