From fb987241e848764fa0e44f1781f28a7f8b2e7ea9 Mon Sep 17 00:00:00 2001 From: Hugo Posnic Date: Mon, 6 May 2024 20:12:27 +0200 Subject: [PATCH 1/4] Add a recursive setting - fix #219 --- CHANGELOG.md | 2 ++ data/com.github.huluti.Curtail.gschema.xml | 5 ++++ data/ui/menu.ui | 2 +- data/ui/preferences.ui | 16 +++++++++++-- src/preferences.py | 6 +++++ src/tools.py | 15 ++++++++++-- src/window.py | 28 ++++++++++------------ 7 files changed, 54 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8ad61d..5df1c4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. ## UNRELEASED ### Added +- Add a "Recursive Compression" setting. - Add Bulgarian translation. Thank's to @twlvnn. - Add Hindi translation. Thank's to @Scrambled777. @@ -12,6 +13,7 @@ All notable changes to this project will be documented in this file. ### Fixed - Fix opening files with "Open With...". Thank's to @ARAKHN1D. +- Fix DnD with nested folders (recursive). ## 1.9.1 - 2024-04-12 ### Fixed diff --git a/data/com.github.huluti.Curtail.gschema.xml b/data/com.github.huluti.Curtail.gschema.xml index 7912891..b204e32 100644 --- a/data/com.github.huluti.Curtail.gschema.xml +++ b/data/com.github.huluti.Curtail.gschema.xml @@ -6,6 +6,11 @@ Save into a new file Save the compressed image into a new file. + + true + Enable recursive compression in folders + This setting enable compression in a recursive way in folders. + true Keep metadata diff --git a/data/ui/menu.ui b/data/ui/menu.ui index 1ff216f..0fc545b 100644 --- a/data/ui/menu.ui +++ b/data/ui/menu.ui @@ -3,7 +3,7 @@
- Bulk Compress Directory (Recursive) + Bulk Compress Directory win.convert-dir diff --git a/data/ui/preferences.ui b/data/ui/preferences.ui index a972cec..8b4ed79 100644 --- a/data/ui/preferences.ui +++ b/data/ui/preferences.ui @@ -26,6 +26,18 @@ New File Suffix + + + Recursive Compression + Enable or disable recursive compression through subdirectories + toggle_recursive + + + center + + + + Keep Metadata @@ -76,8 +88,8 @@ - compression - Compression + formats + Formats image-x-generic-symbolic diff --git a/src/preferences.py b/src/preferences.py index 315cffc..a520465 100644 --- a/src/preferences.py +++ b/src/preferences.py @@ -26,6 +26,7 @@ class CurtailPrefsWindow(Adw.PreferencesWindow): __gtype_name__ = 'CurtailPrefsWindow' + toggle_recursive = Gtk.Template.Child() toggle_metadata = Gtk.Template.Child() toggle_file_attributes = Gtk.Template.Child() toggle_new_file = Gtk.Template.Child() @@ -53,6 +54,11 @@ def __init__(self, parent, **kwargs): def build_ui(self): # Compression settings + # Recursive + self.toggle_recursive.set_active(self._settings.get_boolean('recursive')) + self.toggle_recursive.connect('notify::active', self.on_bool_changed, + 'recursive') + # Keep metadata self.toggle_metadata.set_active(self._settings.get_boolean('metadata')) self.toggle_metadata.connect('notify::active', self.on_bool_changed, diff --git a/src/tools.py b/src/tools.py index dd87ff4..af47f9d 100644 --- a/src/tools.py +++ b/src/tools.py @@ -109,15 +109,26 @@ def create_image_from_file(filename, max_width, max_height): return image + def get_image_files_from_folder(folder_path): + images = [] + for file in os.listdir(folder_path): + path = os.path.join(folder_path, file) + if os.path.isfile(path): + if get_file_type(path) is not None: + image_file = Gio.File.new_for_path(path) + images.append(image_file) + return images + + +def get_image_files_from_folder_recursive(folder_path): images = [] for root, dirs, files in os.walk(folder_path): for file in files: path = os.path.join(root, file) - if get_file_type(path) != None: + if get_file_type(path) is not None: image_file = Gio.File.new_for_path(path) images.append(image_file) - return images def debug_infos(): diff --git a/src/window.py b/src/window.py index 0f0f37d..7ef979d 100644 --- a/src/window.py +++ b/src/window.py @@ -197,8 +197,7 @@ def handle_response(dialog, result): filenames = list() for file in files: filenames.append(file.get_uri()) - final_filenames = self.handle_filenames(filenames) - self.compress_filenames(final_filenames) + self.compress_filenames(filenames) dialog.open_multiple(self, None, handle_response) @@ -210,13 +209,8 @@ def on_dir_dialog_response(warn_dialog, response): if response == "compress": filenames = list() for folder in folders: - images = get_image_files_from_folder(folder.get_path()) - - for image in images: - filenames.append(image.get_uri()) - - final_filenames = self.handle_filenames(filenames) - self.compress_filenames(final_filenames) + filenames.append(folder.get_path()) + self.compress_filenames(filenames) try: folders = dialog.select_multiple_folders_finish(result) @@ -261,9 +255,7 @@ def on_dnd_drop(self, drop_target, value, x, y, user_data=None): filenames = [] for file in files: filenames.append(file.get_uri()) - - final_filenames = self.handle_filenames(filenames) - self.compress_filenames(final_filenames) + self.compress_filenames(filenames) def handle_filenames(self, filenames): final_filenames = [] @@ -273,9 +265,13 @@ def handle_filenames(self, filenames): path = Path(filename) if path.is_dir(): - for new_filename in path.rglob("*"): - new_filename = self.clean_filename(new_filename) - final_filenames.append(new_filename) + if self._settings.get_boolean('recursive'): + images = get_image_files_from_folder_recursive(path) + else: + images = get_image_files_from_folder(path) + for image in images: + image = self.clean_filename(image) + final_filenames.append(image) else: final_filenames.append(filename) @@ -307,6 +303,8 @@ def create_new_filename(self, path): return new_filename def compress_filenames(self, filenames): + filenames = self.handle_filenames(filenames) + result_items = [] for filename in filenames: error_message = False From f40437ee6420868b63e908374f54af2930858c39 Mon Sep 17 00:00:00 2001 From: Hugo Posnic Date: Mon, 6 May 2024 20:21:21 +0200 Subject: [PATCH 2/4] Fix an error and updates deps and CI actions --- .github/workflows/pythonapp.yml | 8 ++++---- poetry.lock | 22 +++++++++++----------- pyproject.toml | 2 +- src/window.py | 3 ++- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml index abc0eca..3513b3c 100644 --- a/.github/workflows/pythonapp.yml +++ b/.github/workflows/pythonapp.yml @@ -11,11 +11,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Set up Python 3.8 - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 with: - python-version: 3.8 + python-version: 3.12 - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/poetry.lock b/poetry.lock index d9b86fc..a30c271 100644 --- a/poetry.lock +++ b/poetry.lock @@ -184,18 +184,19 @@ files = [ [[package]] name = "platformdirs" -version = "4.2.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "4.2.1" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, - {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, + {file = "platformdirs-4.2.1-py3-none-any.whl", hash = "sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1"}, + {file = "platformdirs-4.2.1.tar.gz", hash = "sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf"}, ] [package.extras] docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] [[package]] name = "pyflakes" @@ -210,17 +211,16 @@ files = [ [[package]] name = "pygments" -version = "2.17.2" +version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, - {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, ] [package.extras] -plugins = ["importlib-metadata"] windows-terminal = ["colorama (>=0.4.6)"] [[package]] @@ -431,5 +431,5 @@ files = [ [metadata] lock-version = "2.0" -python-versions = "^3.11" -content-hash = "a523c74ca293cffaf6d39247de0de0b45fde628e604843fb98b7916803ca755a" +python-versions = "^3.12" +content-hash = "781935699f342c16e27ee7387cb585275a216129ef8165507c8672e7f9182af2" diff --git a/pyproject.toml b/pyproject.toml index 7765dd0..d479e76 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ license = "GPLv3" readme = "README.md" [tool.poetry.dependencies] -python = "^3.11" +python = "^3.12" [tool.poetry.group.dev.dependencies] pylint = "^2.17.1" diff --git a/src/window.py b/src/window.py index 7ef979d..b90f551 100644 --- a/src/window.py +++ b/src/window.py @@ -23,7 +23,8 @@ from .preferences import CurtailPrefsWindow from .compressor import Compressor from .tools import add_filechooser_filters, get_file_type, \ - create_image_from_file, sizeof_fmt, debug_infos, get_image_files_from_folder + create_image_from_file, sizeof_fmt, debug_infos, \ + get_image_files_from_folder, get_image_files_from_folder_recursive CURTAIL_PATH = '/com/github/huluti/Curtail/' SETTINGS_SCHEMA = 'com.github.huluti.Curtail' From 9071de6972d3b68b8789413fbafa66d99f6b1cbc Mon Sep 17 00:00:00 2001 From: Hugo Posnic Date: Tue, 7 May 2024 09:06:27 +0200 Subject: [PATCH 3/4] Fix uri append --- src/tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools.py b/src/tools.py index af47f9d..80071ba 100644 --- a/src/tools.py +++ b/src/tools.py @@ -117,7 +117,7 @@ def get_image_files_from_folder(folder_path): if os.path.isfile(path): if get_file_type(path) is not None: image_file = Gio.File.new_for_path(path) - images.append(image_file) + images.append(image_file.get_uri()) return images @@ -128,7 +128,7 @@ def get_image_files_from_folder_recursive(folder_path): path = os.path.join(root, file) if get_file_type(path) is not None: image_file = Gio.File.new_for_path(path) - images.append(image_file) + images.append(image_file.get_uri()) return images def debug_infos(): From 464f025f1af5fa1161620c3f2af0cd174626837c Mon Sep 17 00:00:00 2001 From: Hugo Posnic Date: Tue, 7 May 2024 10:38:01 +0200 Subject: [PATCH 4/4] Update pot --- data/ui/preferences.ui | 2 +- po/curtail.pot | 143 +++++++++++++++++++++++------------------ 2 files changed, 81 insertions(+), 64 deletions(-) diff --git a/data/ui/preferences.ui b/data/ui/preferences.ui index 8b4ed79..a0d4329 100644 --- a/data/ui/preferences.ui +++ b/data/ui/preferences.ui @@ -29,7 +29,7 @@ Recursive Compression - Enable or disable recursive compression through subdirectories + Enable or disable compression through subdirectories toggle_recursive diff --git a/po/curtail.pot b/po/curtail.pot index 8cc9227..bbfdb00 100644 --- a/po/curtail.pot +++ b/po/curtail.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: curtail\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-04-13 14:53+0800\n" +"POT-Creation-Date: 2024-05-07 10:37+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -35,10 +35,11 @@ msgid "" msgstr "" #: data/com.github.huluti.Curtail.desktop.in:3 data/ui/window.ui:4 -#: data/ui/window.ui:32 +#: data/ui/window.ui:31 msgid "Curtail" msgstr "" +#. Keywords, do not translate #: data/com.github.huluti.Curtail.desktop.in:15 msgid "compress;optimize;image;photo;" msgstr "" @@ -52,95 +53,103 @@ msgid "Save the compressed image into a new file." msgstr "" #: data/com.github.huluti.Curtail.gschema.xml:11 -msgid "Keep metadata" +msgid "Enable recursive compression in folders" msgstr "" #: data/com.github.huluti.Curtail.gschema.xml:12 +msgid "This setting enable compression in a recursive way in folders." +msgstr "" + +#: data/com.github.huluti.Curtail.gschema.xml:16 +msgid "Keep metadata" +msgstr "" + #: data/com.github.huluti.Curtail.gschema.xml:17 +#: data/com.github.huluti.Curtail.gschema.xml:22 msgid "This setting preserves metadata of images." msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:16 +#: data/com.github.huluti.Curtail.gschema.xml:21 msgid "Preserve file attributes if possible" msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:21 +#: data/com.github.huluti.Curtail.gschema.xml:26 msgid "Enable lossy mode" msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:22 +#: data/com.github.huluti.Curtail.gschema.xml:27 msgid "Use lossy mode to compress images." msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:26 +#: data/com.github.huluti.Curtail.gschema.xml:31 msgid "Suffix to append at end of new file" msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:27 +#: data/com.github.huluti.Curtail.gschema.xml:32 msgid "Suffix to append at end of new file." msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:31 +#: data/com.github.huluti.Curtail.gschema.xml:36 msgid "PNG Lossy Compression Level" msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:32 +#: data/com.github.huluti.Curtail.gschema.xml:37 msgid "Lossy compression level to use for PNG images." msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:36 +#: data/com.github.huluti.Curtail.gschema.xml:41 msgid "PNG Lossless Compression Level" msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:37 +#: data/com.github.huluti.Curtail.gschema.xml:42 msgid "Lossless compression level to use for PNG images." msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:41 +#: data/com.github.huluti.Curtail.gschema.xml:46 msgid "JPG Lossy Compression Level" msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:42 +#: data/com.github.huluti.Curtail.gschema.xml:47 msgid "Lossy compression level to use for JPG images." msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:46 +#: data/com.github.huluti.Curtail.gschema.xml:51 msgid "WebP Lossy Compression Level" msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:47 +#: data/com.github.huluti.Curtail.gschema.xml:52 msgid "Lossy compression level to use for WebP images." msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:51 +#: data/com.github.huluti.Curtail.gschema.xml:56 msgid "WebP Lossless Compression Level" msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:52 +#: data/com.github.huluti.Curtail.gschema.xml:57 msgid "Lossless compression level to use for WebP images." msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:56 +#: data/com.github.huluti.Curtail.gschema.xml:61 msgid "Enable progressive encoding for JPEG images." msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:57 +#: data/com.github.huluti.Curtail.gschema.xml:62 msgid "Optionally encode jpeg images progressively." msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:61 +#: data/com.github.huluti.Curtail.gschema.xml:66 msgid "Enable maximum compression for SVG images." msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:62 +#: data/com.github.huluti.Curtail.gschema.xml:67 msgid "Optionally enable maximum cleaning of SVG images." msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:66 data/ui/preferences.ui:55 +#: data/com.github.huluti.Curtail.gschema.xml:71 data/ui/preferences.ui:67 msgid "Compression Timeout" msgstr "" -#: data/com.github.huluti.Curtail.gschema.xml:67 +#: data/com.github.huluti.Curtail.gschema.xml:72 msgid "Compression timeout for each image." msgstr "" @@ -190,67 +199,75 @@ msgid "New File Suffix" msgstr "" #: data/ui/preferences.ui:31 -msgid "Keep Metadata" +msgid "Recursive Compression" msgstr "" #: data/ui/preferences.ui:32 -msgid "Keep metadata chunks that do not affect rendering" +msgid "Enable or disable compression through subdirectories" msgstr "" #: data/ui/preferences.ui:43 -msgid "Keep File Attributes When Possible" +msgid "Keep Metadata" msgstr "" #: data/ui/preferences.ui:44 +msgid "Keep metadata chunks that do not affect rendering" +msgstr "" + +#: data/ui/preferences.ui:55 +msgid "Keep File Attributes When Possible" +msgstr "" + +#: data/ui/preferences.ui:56 msgid "" "Ensure the new file has the same permissions and timestamps as the original " "file" msgstr "" -#: data/ui/preferences.ui:56 +#: data/ui/preferences.ui:68 msgid "Set the timeout between images" msgstr "" -#: data/ui/preferences.ui:80 -msgid "Compression" +#: data/ui/preferences.ui:92 +msgid "Formats" msgstr "" -#: data/ui/preferences.ui:87 data/ui/preferences.ui:132 -#: data/ui/preferences.ui:169 +#: data/ui/preferences.ui:99 data/ui/preferences.ui:142 +#: data/ui/preferences.ui:178 msgid "Lossy Compression" msgstr "" -#: data/ui/preferences.ui:88 data/ui/preferences.ui:133 -#: data/ui/preferences.ui:170 +#: data/ui/preferences.ui:100 data/ui/preferences.ui:143 +#: data/ui/preferences.ui:179 msgid "Set the quality of the generated image, 100 is the best quality" msgstr "" -#: data/ui/preferences.ui:107 data/ui/preferences.ui:189 +#: data/ui/preferences.ui:118 data/ui/preferences.ui:197 msgid "Lossless Compression Level" msgstr "" -#: data/ui/preferences.ui:108 data/ui/preferences.ui:190 +#: data/ui/preferences.ui:119 data/ui/preferences.ui:198 msgid "Set the level of the compression, 6 is the highest but slowest level" msgstr "" -#: data/ui/preferences.ui:152 +#: data/ui/preferences.ui:161 msgid "Progressive Encode" msgstr "" -#: data/ui/preferences.ui:153 +#: data/ui/preferences.ui:162 msgid "Enable incremental image rendering, going from blurry to clear" msgstr "" -#: data/ui/preferences.ui:214 +#: data/ui/preferences.ui:221 msgid "Maximum Compression Level" msgstr "" -#: data/ui/preferences.ui:215 +#: data/ui/preferences.ui:222 msgid "This can be more destructive for the image" msgstr "" #: data/ui/menu.ui:6 -msgid "Bulk Compress Directory (Recursive)" +msgid "Bulk Compress Directory" msgstr "" #: data/ui/menu.ui:14 @@ -261,39 +278,39 @@ msgstr "" msgid "About Curtail" msgstr "" -#: data/ui/window.ui:18 src/window.py:188 +#: data/ui/window.ui:17 src/window.py:189 msgid "Browse Files" msgstr "" -#: data/ui/window.ui:25 +#: data/ui/window.ui:24 msgid "Clear Results" msgstr "" -#: data/ui/window.ui:39 +#: data/ui/window.ui:38 msgid "Main Menu" msgstr "" -#: data/ui/window.ui:51 +#: data/ui/window.ui:49 msgid "_Change Mode" msgstr "" -#: data/ui/window.ui:52 +#: data/ui/window.ui:50 msgid "Images will be overwritten, proceed carefully" msgstr "" -#: data/ui/window.ui:60 +#: data/ui/window.ui:58 msgid "Drop images here to compress them" msgstr "" -#: data/ui/window.ui:66 +#: data/ui/window.ui:64 msgid "_Browse Files" msgstr "" -#: data/ui/window.ui:85 +#: data/ui/window.ui:83 msgid "Lossless" msgstr "" -#: data/ui/window.ui:97 +#: data/ui/window.ui:95 msgid "Lossy" msgstr "" @@ -329,16 +346,16 @@ msgstr "" msgid "SVG images" msgstr "" -#: src/tools.py:134 src/tools.py:141 src/tools.py:148 src/tools.py:155 -#: src/tools.py:162 src/tools.py:192 +#: src/tools.py:145 src/tools.py:152 src/tools.py:159 src/tools.py:166 +#: src/tools.py:173 src/tools.py:203 msgid "Version not found" msgstr "" -#: src/window.py:175 +#: src/window.py:176 msgid "Safe mode with '{}' suffix" msgstr "" -#: src/window.py:178 +#: src/window.py:179 msgid "Overwrite mode" msgstr "" @@ -346,42 +363,42 @@ msgstr "" msgid "Browse Directories" msgstr "" -#: src/window.py:236 src/window.py:242 +#: src/window.py:231 src/window.py:237 msgid "Are you sure you want to compress images in these directories?" msgstr "" -#: src/window.py:237 +#: src/window.py:232 msgid "" "All of the images in the directories selected and their subdirectories will " "be compressed. The original images will not be modified." msgstr "" -#: src/window.py:243 +#: src/window.py:238 msgid "" "All of the images in the directories selected and their subdirectories will " "be compressed and overwritten!" msgstr "" -#: src/window.py:246 +#: src/window.py:241 msgid "Cancel" msgstr "" -#: src/window.py:247 +#: src/window.py:242 msgid "Compress" msgstr "" -#: src/window.py:317 +#: src/window.py:316 msgid "This file doesn't exist." msgstr "" -#: src/window.py:322 +#: src/window.py:321 msgid "Format of this file is not supported." msgstr "" -#: src/window.py:374 +#: src/window.py:373 msgid "translator-credits" msgstr "" -#: src/window.py:378 +#: src/window.py:377 msgid "Contributors" msgstr ""