Skip to content

Commit

Permalink
Merge pull request #660 from buzzingwires/thumbnail_save
Browse files Browse the repository at this point in the history
Add thumbnail.save configuration option.
  • Loading branch information
karlch authored Jul 12, 2023
2 parents facb142 + 3f287e8 commit 3ec77f0
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 8 deletions.
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ Added:
the original image. Thanks `@Yutsuten`_ for reviving this!
* Add the ``none`` sorting type for the ``sort.image_order`` and ``sort.directory_order``
options, implemented by `@buzzingwires`_
* Add the ``thumbnail.save`` option, implemented by `@buzzingwires`_

Changed:
^^^^^^^^
Expand Down
23 changes: 23 additions & 0 deletions tests/unit/utils/test_thumbnail_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import pytest

from vimiv.api import settings
from vimiv.utils import thumbnail_manager


Expand All @@ -24,6 +25,28 @@ def manager(qtbot, tmp_path, mocker):
yield thumbnail_manager.ThumbnailManager(None)


def test_thumbnail_save_disabled(monkeypatch, qtbot, tmp_path, manager):
monkeypatch.setattr(settings.thumbnail.save, "value", False)
no_thumbnail_path = str(tmp_path / "no_thumbnail.jpg")
QPixmap(300, 300).save(no_thumbnail_path, "jpg")
manager.create_thumbnails_async([no_thumbnail_path])
check_thumbails_created(qtbot, manager, 0)


def test_thumbnail_save_disabled_no_delete_old(monkeypatch, qtbot, tmp_path, manager):
monkeypatch.setattr(settings.thumbnail.save, "value", True)
has_thumbnail_path = str(tmp_path / "has_thumbnail.jpg")
QPixmap(300, 300).save(has_thumbnail_path, "jpg")
manager.create_thumbnails_async([has_thumbnail_path])
check_thumbails_created(qtbot, manager, 1)

monkeypatch.setattr(settings.thumbnail.save, "value", False)
no_thumbnail_path = str(tmp_path / "no_thumbnail.jpg")
QPixmap(300, 300).save(no_thumbnail_path, "jpg")
manager.create_thumbnails_async([has_thumbnail_path, no_thumbnail_path])
check_thumbails_created(qtbot, manager, 1)


@pytest.mark.parametrize("n_paths", (1, 5))
def test_create_n_thumbnails(qtbot, tmp_path, manager, n_paths):
# Create images to create thumbnails of
Expand Down
5 changes: 5 additions & 0 deletions vimiv/api/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,11 @@ class thumbnail: # pylint: disable=invalid-name
"""Namespace for thumbnail related settings."""

size = ThumbnailSizeSetting("thumbnail.size", 128, desc="Size of thumbnails")
save = BoolSetting(
"thumbnail.save",
True,
desc="Save new thumbnails to the disk in the shared icon cache for later use"
)


class slideshow: # pylint: disable=invalid-name
Expand Down
29 changes: 21 additions & 8 deletions vimiv/utils/thumbnail_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from PyQt5.QtGui import QIcon, QPixmap, QImage

import vimiv
from vimiv import api
from vimiv.utils import xdg, imagereader, Pool


Expand Down Expand Up @@ -131,6 +132,24 @@ def _get_thumbnail_filename(self, path: str) -> str:
def _get_source_mtime(path: str) -> int:
return int(os.path.getmtime(path))

def _save_thumbnail(self, image: QImage, thumbnail_path: str) -> None:
"""Save the thumbnail file to the disk.
Args:
image: The QImage representing the thumbnail.
thumbnail_path: Path to which the thumbnail is stored.
Returns:
None.
"""
# First create temporary file and then move it. This avoids
# problems with concurrent access of the thumbnail cache, since
# "move" is an atomic operation
handle, tmp_filename = tempfile.mkstemp(dir=self._manager.directory)
os.close(handle)
os.chmod(tmp_filename, 0o600)
image.save(tmp_filename, format="png")
os.replace(tmp_filename, thumbnail_path)

def _create_thumbnail(self, path: str, thumbnail_path: str) -> QPixmap:
"""Create thumbnail for an image.
Expand All @@ -153,14 +172,8 @@ def _create_thumbnail(self, path: str, thumbnail_path: str) -> QPixmap:
return self._manager.fail_pixmap
for key, value in attributes.items():
image.setText(key, value)
# First create temporary file and then move it. This avoids
# problems with concurrent access of the thumbnail cache, since
# "move" is an atomic operation
handle, tmp_filename = tempfile.mkstemp(dir=self._manager.directory)
os.close(handle)
os.chmod(tmp_filename, 0o600)
image.save(tmp_filename, format="png")
os.replace(tmp_filename, thumbnail_path)
if api.settings.thumbnail.save:
self._save_thumbnail(image, thumbnail_path)
return QPixmap(image)

def _get_thumbnail_attributes(self, path: str, image: QImage) -> Dict[str, str]:
Expand Down

0 comments on commit 3ec77f0

Please sign in to comment.