Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix size on File object after optimizing #3

Merged
merged 1 commit into from
Apr 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ django_optimized_image
django_optimized_image is a simple Django library that allows optimization
of images by using `TinyPNG <https://tinypng.com/>`_ or `Pillow <pillow.readthedocs.io/>`_.

Detailed documentation is in the "docs" directory.

Quick start
-----------

Expand Down
27 changes: 24 additions & 3 deletions optimized_image/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
from factory.fuzzy import FuzzyText
import io
from unittest.mock import patch, Mock

from django.core.files.uploadedfile import InMemoryUploadedFile
from django.test import TestCase
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase, override_settings

from . import factories
from ..utils import optimize_from_buffer, optimize_legacy_images_in_model_fields


class TestOptimizeFromBuffer(TestCase):
"""Test case for the mock_optimize_from_buffer() function."""

@override_settings(OPTIMIZED_IMAGE_METHOD="justtesting")
@patch('optimized_image.utils.is_testing_mode')
def test_changing_size(self, mock_is_testing_mode):
mock_is_testing_mode.return_value = False
TESTFILE = "small_kitten.jpeg"

data = SimpleUploadedFile(name=TESTFILE, content=open(TESTFILE, "rb").read())

initial_size = data.size
optimize_from_buffer(data)
resized_data_size = data.size
data.open()
actual_final_size = len(data.read())
self.assertEqual(actual_final_size, resized_data_size)
self.assertLess(
actual_final_size, initial_size,
msg="Test not valid - image was not reduced"
)

@patch('optimized_image.utils.is_testing_mode')
@patch('optimized_image.utils.Image')
@patch('optimized_image.utils.tinify')
Expand Down Expand Up @@ -86,6 +105,8 @@ def test_settings(self, mock_tinify, mock_pil_image):
"""The OPTIMIZED_IMAGE_METHOD is used to determine whether Pillow or TinyPNG is used."""
generic_model = factories.GenericModelFactory()

mock_tinify.from_buffer.return_value.to_buffer.return_value = b""

with self.subTest(OPTIMIZED_IMAGE_METHOD='pillow'):
with self.settings(
OPTIMIZED_IMAGE_METHOD='pillow',
Expand Down
18 changes: 18 additions & 0 deletions optimized_image/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ def optimize_from_buffer(data):
data.seek(0)
data.file.write(optimized_buffer)
data.file.truncate()
elif settings.OPTIMIZED_IMAGE_METHOD == 'justtesting':
# Make a tiny image and use that instead of the input image.
# (justtesting is NOT a publicly allowed value, it's just for internal testing.)
bytes_io = BytesIO()
Image.new('RGB', (10, 10), "blue").save(bytes_io, format="JPEG")
data.seek(0)
data.file.write(bytes_io.getvalue())
data.file.truncate()
# Else - just don't change it
else:
return data

# We optimized it - fix the computed size
data.size = data.file.tell()
return data


Expand Down Expand Up @@ -122,6 +136,10 @@ def optimize_legacy_images_in_model_fields(list_of_models, verbosity=0):
image_name = os.path.relpath(image_file.name, image_file.field.upload_to)
image_file.save(image_name, content_file)
except:
if is_testing_mode():
# This shouldn't actually happen, so if testing, let the exception continue
# up the call chain so it makes the test fail.
raise
# If the optimization failed for any reason, write this
# to stdout.
sys.stdout.write('\nOptimization failed for {}.'.format(image_file.name))
Expand Down
39 changes: 39 additions & 0 deletions runtests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env python
import sys
import django
from django.conf import settings

if not settings.configured:
settings.configure(
DATABASES={
"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": "test.db",}
},
MIDDLEWARE_CLASSES=(),
INSTALLED_APPS=("optimized_image", "not_optimized"),
SITE_ID=1,
ADMINS=(("Admin", "admin@example.com"),),
OPTIMIZED_IMAGE_METHOD="pillow",
TINYPNG_KEY="versecrettinypngkey",
BASE_DIR="", # tells compatibility checker not to emit warning
TEMPLATES=[
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": ["optimized_image/templates"],
}
],
)


def runtests():
django.setup()
from django.test.utils import get_runner

TestRunner = get_runner(settings)
test_runner = TestRunner(verbosity=1, interactive=True, failfast=True)
failures = test_runner.run_tests(["optimized_image"])
if failures:
sys.exit(1)


if __name__ == "__main__":
runtests()
Binary file added small_kitten.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = {py35,py3,py37}-1.11.X,{py35,py3,py37}-2.0.X,{py35,py3,py37}-2.1.X
envlist = py35,py36,py37

[testenv]
basepython =
Expand Down