Merge pull request #224 from Huluti/recursive-setting

Add a recursive setting - fix #219
This commit is contained in:
Hugo Posnic 2024-05-07 10:42:31 +02:00 committed by GitHub
commit a61e754e4a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 158 additions and 106 deletions

View File

@ -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

View File

@ -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

View File

@ -6,6 +6,11 @@
<summary>Save into a new file</summary>
<description>Save the compressed image into a new file.</description>
</key>
<key type="b" name="recursive">
<default>true</default>
<summary>Enable recursive compression in folders</summary>
<description>This setting enable compression in a recursive way in folders.</description>
</key>
<key type="b" name="metadata">
<default>true</default>
<summary>Keep metadata</summary>

View File

@ -3,7 +3,7 @@
<menu id="window-menu">
<section>
<item>
<attribute name="label" translatable="yes">Bulk Compress Directory (Recursive)</attribute>
<attribute name="label" translatable="yes">Bulk Compress Directory</attribute>
<attribute name="action">win.convert-dir</attribute>
</item>
<item>

View File

@ -26,6 +26,18 @@
<property name="title" translatable="yes">New File Suffix</property>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Recursive Compression</property>
<property name="subtitle" translatable="yes">Enable or disable compression through subdirectories</property>
<property name="activatable-widget">toggle_recursive</property>
<child>
<object class="GtkSwitch" id="toggle_recursive">
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes">Keep Metadata</property>
@ -76,8 +88,8 @@
</child>
<child>
<object class="AdwPreferencesPage">
<property name="name">compression</property>
<property name="title" translatable="yes">Compression</property>
<property name="name">formats</property>
<property name="title" translatable="yes">Formats</property>
<property name="icon-name">image-x-generic-symbolic</property>
<child>
<object class="AdwPreferencesGroup">

View File

@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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
#: data/com.github.huluti.Curtail.gschema.xml:17
msgid "This setting preserves metadata of images."
msgid "This setting enable compression in a recursive way in folders."
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:16
msgid "Preserve file attributes if possible"
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:21
msgid "Enable lossy mode"
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:22
msgid "Use lossy mode to compress images."
msgid "Preserve file attributes if possible"
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:26
msgid "Suffix to append at end of new file"
msgid "Enable lossy mode"
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:27
msgid "Suffix to append at end of new file."
msgid "Use lossy mode to compress images."
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:31
msgid "PNG Lossy Compression Level"
msgid "Suffix to append at end of new file"
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:32
msgid "Lossy compression level to use for PNG images."
msgid "Suffix to append at end of new file."
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:36
msgid "PNG Lossless Compression Level"
msgid "PNG Lossy Compression Level"
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:37
msgid "Lossless compression level to use for PNG images."
msgid "Lossy compression level to use for PNG images."
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:41
msgid "JPG Lossy Compression Level"
msgid "PNG Lossless Compression Level"
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:42
msgid "Lossy compression level to use for JPG images."
msgid "Lossless compression level to use for PNG images."
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:46
msgid "WebP Lossy Compression Level"
msgid "JPG Lossy Compression Level"
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:47
msgid "Lossy compression level to use for WebP images."
msgid "Lossy compression level to use for JPG images."
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:51
msgid "WebP Lossless Compression Level"
msgid "WebP Lossy Compression Level"
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:52
msgid "Lossless compression level to use for WebP images."
msgid "Lossy compression level to use for WebP images."
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:56
msgid "Enable progressive encoding for JPEG images."
msgid "WebP Lossless Compression Level"
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:57
msgid "Optionally encode jpeg images progressively."
msgid "Lossless compression level to use for WebP images."
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:61
msgid "Enable maximum compression for SVG images."
msgid "Enable progressive encoding for JPEG images."
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:62
msgid "Optionally enable maximum cleaning of SVG images."
msgid "Optionally encode jpeg images progressively."
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:66 data/ui/preferences.ui:55
msgid "Compression Timeout"
#: data/com.github.huluti.Curtail.gschema.xml:66
msgid "Enable maximum compression for SVG images."
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:67
msgid "Optionally enable maximum cleaning of SVG images."
msgstr ""
#: data/com.github.huluti.Curtail.gschema.xml:71 data/ui/preferences.ui:67
msgid "Compression Timeout"
msgstr ""
#: 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 ""

22
poetry.lock generated
View File

@ -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"

View File

@ -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"

View File

@ -26,6 +26,7 @@ SETTINGS_SCHEMA = 'com.github.huluti.Curtail'
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 @@ class CurtailPrefsWindow(Adw.PreferencesWindow):
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,

View File

@ -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.get_uri())
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)
images.append(image_file.get_uri())
return images
def debug_infos():

View File

@ -23,7 +23,8 @@ from .resultitem import ResultItem
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'
@ -197,8 +198,7 @@ class CurtailWindow(Adw.ApplicationWindow):
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 +210,8 @@ class CurtailWindow(Adw.ApplicationWindow):
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 +256,7 @@ class CurtailWindow(Adw.ApplicationWindow):
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 +266,13 @@ class CurtailWindow(Adw.ApplicationWindow):
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 +304,8 @@ class CurtailWindow(Adw.ApplicationWindow):
return new_filename
def compress_filenames(self, filenames):
filenames = self.handle_filenames(filenames)
result_items = []
for filename in filenames:
error_message = False