[Python-modules-commits] [sorl-thumbnail] 02/17: Import sorl-thumbnail_12.3.orig.tar.gz
Wolfgang Borgert
debacle at moszumanska.debian.org
Wed Jan 6 21:05:25 UTC 2016
This is an automated email from the git hooks/post-receive script.
debacle pushed a commit to branch master
in repository sorl-thumbnail.
commit 42b81892242e6ae4979e886c38f92a113aa58721
Author: W. Martin Borgert <debacle at debian.org>
Date: Fri Jan 1 18:06:40 2016 +0100
Import sorl-thumbnail_12.3.orig.tar.gz
---
.gitignore | 5 +
.travis.yml | 136 ++--
AUTHORS | 5 +-
README.rst | 36 +-
docs/management.rst | 6 +-
docs/reference/settings.rst | 2 +-
docs/template.rst | 2 +-
setup.py | 8 +-
sorl/__init__.py | 6 +-
sorl/thumbnail/base.py | 3 +-
sorl/thumbnail/compat.py | 65 +-
sorl/thumbnail/engines/base.py | 26 +-
sorl/thumbnail/engines/convert_engine.py | 9 +-
sorl/thumbnail/engines/pil_engine.py | 9 +-
sorl/thumbnail/engines/wand_engine.py | 10 +-
sorl/thumbnail/fields.py | 2 +-
sorl/thumbnail/helpers.py | 7 +-
sorl/thumbnail/images.py | 12 +-
sorl/thumbnail/kvstores/base.py | 8 +-
sorl/thumbnail/kvstores/cached_db_kvstore.py | 11 +-
sorl/thumbnail/kvstores/dbm_kvstore.py | 2 +
sorl/thumbnail/management/commands/thumbnail.py | 6 +-
sorl/thumbnail/migrations/0001_initial.py | 20 +
sorl/thumbnail/migrations/__init__.py | 0
sorl/thumbnail/templatetags/thumbnail.py | 2 +-
tests/runalltests.sh | 6 -
tests/runtests.py | 74 --
tests/settings/default.py | 24 +-
tests/thumbnail_tests/compat.py | 9 +
.../test_alternative_resolutions.py | 58 ++
tests/thumbnail_tests/test_backends.py | 141 ++++
tests/thumbnail_tests/test_commands.py | 68 ++
tests/thumbnail_tests/test_engines.py | 363 +++++++++
tests/thumbnail_tests/test_filters.py | 48 ++
tests/thumbnail_tests/test_kvstore.py | 23 +
tests/thumbnail_tests/test_parsers.py | 36 +
tests/thumbnail_tests/test_storage.py | 52 ++
tests/thumbnail_tests/test_templatetags.py | 146 ++++
tests/thumbnail_tests/tests.py | 892 ---------------------
tests/thumbnail_tests/urls.py | 2 +-
tests/thumbnail_tests/utils.py | 95 ++-
tox.ini | 389 +--------
42 files changed, 1341 insertions(+), 1483 deletions(-)
diff --git a/.gitignore b/.gitignore
index 2775572..4df9375 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,3 +54,8 @@ docs/_build/
# Virtualenv
.env/
+
+# dbm stuff
+tests/thumbnail_kvstore
+tests/thumbnail_kvstore.db
+tests/thumbnail_kvstore.lock
diff --git a/.travis.yml b/.travis.yml
index 72f4a8d..1597464 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,87 +1,93 @@
language: python
python:
- - "2.7"
- - "3.3"
+ - "3.4"
-env:
- - DJANGO_VERSION=">=1.5,<1.6" SETTINGS=pil APT='libjpeg62 libjpeg62-dev zlib1g-dev'
- - DJANGO_VERSION=">=1.5,<1.6" SETTINGS=imagemagick APT=imagemagick
- - DJANGO_VERSION=">=1.5,<1.6" SETTINGS=graphicsmagick APT=graphicsmagick
- - DJANGO_VERSION=">=1.5,<1.6" SETTINGS=wand APT=libmagickwand-dev PIP=wand
- - DJANGO_VERSION=">=1.5,<1.6" SETTINGS=redis PIP=redis
-
- - DJANGO_VERSION=">=1.6,<1.7" SETTINGS=pil APT='libjpeg62 libjpeg62-dev zlib1g-dev'
- - DJANGO_VERSION=">=1.6,<1.7" SETTINGS=imagemagick APT=imagemagick
- - DJANGO_VERSION=">=1.6,<1.7" SETTINGS=graphicsmagick APT=graphicsmagick
- - DJANGO_VERSION=">=1.6,<1.7" SETTINGS=wand APT=libmagickwand-dev PIP=wand
- - DJANGO_VERSION=">=1.6,<1.7" SETTINGS=redis PIP=redis
-
- - DJANGO_VERSION=">=1.7,<1.8" SETTINGS=pil APT='libjpeg62 libjpeg62-dev zlib1g-dev'
- - DJANGO_VERSION=">=1.7,<1.8" SETTINGS=imagemagick APT=imagemagick
- - DJANGO_VERSION=">=1.7,<1.8" SETTINGS=graphicsmagick APT=graphicsmagick
- - DJANGO_VERSION=">=1.7,<1.8" SETTINGS=wand APT=libmagickwand-dev PIP=wand
- - DJANGO_VERSION=">=1.7,<1.8" SETTINGS=redis PIP=redis
-
-matrix:
- include:
- - python: "2.7"
- env:
- - DJANGO_VERSION=">=1.4,<1.5" SETTINGS=pil APT='libjpeg62 libjpeg62-dev zlib1g-dev'
-
- - python: "2.7"
- env:
- - DJANGO_VERSION=">=1.4,<1.5" SETTINGS=imagemagick APT=imagemagick
-
- - python: "2.7"
- env:
- - DJANGO_VERSION=">=1.4,<1.5" SETTINGS=graphicsmagick APT=graphicsmagick
+cache:
+ pip:
+ apt:
+ directories:
+ - .tox
- - python: "2.7"
- env:
- - DJANGO_VERSION=">=1.4,<1.5" SETTINGS=wand APT=libmagickwand-dev PIP=wand
-
- - python: "2.7"
- env:
- - DJANGO_VERSION=">=1.4,<1.5" SETTINGS=redis PIP=redis
-
- - python: "2.7"
- env:
- - DJANGO_VERSION=">=1.4,<1.5" SETTINGS=pgmagick APT='libgraphicsmagick++-dev libboost-python-dev libboost-thread-dev'
- - PIP=pgmagick
-
- - python: "2.7"
- env:
- - DJANGO_VERSION=">=1.5,<1.6" SETTINGS=pgmagick APT='libgraphicsmagick++-dev libboost-python-dev libboost-thread-dev'
- - PIP=pgmagick
-
- - python: "2.7"
- env:
- - DJANGO_VERSION=">=1.6,<1.7" SETTINGS=pgmagick APT='libgraphicsmagick++-dev libboost-python-dev libboost-thread-dev'
- - PIP=pgmagick
+env:
+ - TOX_ENV=py27-django14-pil APT='libjpeg62 libjpeg62-dev zlib1g-dev'
+ - TOX_ENV=py27-django14-imagemagick APT=imagemagick
+ - TOX_ENV=py27-django14-graphicsmagick APT=graphicsmagick
+ - TOX_ENV=py27-django14-redis
+ - TOX_ENV=py27-django14-wand
+ - TOX_ENV=py27-django14-pgmagick APT='libgraphicsmagick++1-dev libboost-python-dev'
+ - TOX_ENV=py27-django14-dbm
+ - TOX_ENV=py27-django15-pil APT='libjpeg62 libjpeg62-dev zlib1g-dev'
+ - TOX_ENV=py27-django15-imagemagick APT=imagemagick
+ - TOX_ENV=py27-django15-graphicsmagick APT=graphicsmagick
+ - TOX_ENV=py27-django15-redis
+ - TOX_ENV=py27-django15-wand
+ - TOX_ENV=py27-django15-pgmagick APT='libgraphicsmagick++1-dev libboost-python-dev'
+ - TOX_ENV=py27-django15-dbm
+ - TOX_ENV=py27-django16-pil APT='libjpeg62 libjpeg62-dev zlib1g-dev'
+ - TOX_ENV=py27-django16-imagemagick APT=imagemagick
+ - TOX_ENV=py27-django16-graphicsmagick APT=graphicsmagick
+ - TOX_ENV=py27-django16-redis
+ - TOX_ENV=py27-django16-wand
+ - TOX_ENV=py27-django16-pgmagick APT='libgraphicsmagick++1-dev libboost-python-dev'
+ - TOX_ENV=py27-django16-dbm
+ - TOX_ENV=py27-django17-pil APT='libjpeg62 libjpeg62-dev zlib1g-dev'
+ - TOX_ENV=py27-django17-imagemagick APT=imagemagick
+ - TOX_ENV=py27-django17-graphicsmagick APT=graphicsmagick
+ - TOX_ENV=py27-django17-redis
+ - TOX_ENV=py27-django17-wand
+ - TOX_ENV=py27-django17-pgmagick APT='libgraphicsmagick++1-dev libboost-python-dev'
+ - TOX_ENV=py27-django17-dbm
+ - TOX_ENV=py27-django18-pil APT='libjpeg62 libjpeg62-dev zlib1g-dev'
+ - TOX_ENV=py27-django18-imagemagick APT=imagemagick
+ - TOX_ENV=py27-django18-graphicsmagick APT=graphicsmagick
+ - TOX_ENV=py27-django18-redis
+ - TOX_ENV=py27-django18-wand
+ - TOX_ENV=py27-django18-pgmagick APT='libgraphicsmagick++1-dev libboost-python-dev'
+ - TOX_ENV=py27-django18-dbm
+ - TOX_ENV=py34-django15-pil APT='libjpeg62 libjpeg62-dev zlib1g-dev'
+ - TOX_ENV=py34-django15-imagemagick APT=imagemagick
+ - TOX_ENV=py34-django15-graphicsmagick APT=graphicsmagick
+ - TOX_ENV=py34-django15-redis
+ - TOX_ENV=py34-django15-wand
+ - TOX_ENV=py34-django15-dbm
+ - TOX_ENV=py34-django16-pil APT='libjpeg62 libjpeg62-dev zlib1g-dev'
+ - TOX_ENV=py34-django16-imagemagick APT=imagemagick
+ - TOX_ENV=py34-django16-graphicsmagick APT=graphicsmagick
+ - TOX_ENV=py34-django16-redis
+ - TOX_ENV=py34-django16-wand
+ - TOX_ENV=py34-django16-dbm
+ - TOX_ENV=py34-django17-pil APT='libjpeg62 libjpeg62-dev zlib1g-dev'
+ - TOX_ENV=py34-django17-imagemagick APT=imagemagick
+ - TOX_ENV=py34-django17-graphicsmagick APT=graphicsmagick
+ - TOX_ENV=py34-django17-redis
+ - TOX_ENV=py34-django17-wand
+ - TOX_ENV=py34-django17-dbm
+ - TOX_ENV=py34-django18-pil APT='libjpeg62 libjpeg62-dev zlib1g-dev'
+ - TOX_ENV=py34-django18-imagemagick APT=imagemagick
+ - TOX_ENV=py34-django18-graphicsmagick APT=graphicsmagick
+ - TOX_ENV=py34-django18-redis
+ - TOX_ENV=py34-django18-wand
+ - TOX_ENV=py34-django18-dbm
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq $APT
after_failure:
- - pip freeze
- cat /home/travis/.pip/pip.log
after_success:
- - pip freeze
- coveralls
install:
- - pip install -U pip
- - pip install -q coveralls
- - pip install -q Pillow $PIP
- - pip install -q Django$DJANGO_VERSION
- - pip install flake8
+ - pip install pip wheel
+ - pip install -q coveralls flake8 tox
script:
- - cd tests && coverage run --source=sorl runtests.py --settings=settings.$SETTINGS
- - cd .. && flake8 --show-source sorl/
+ - env | sort
+ - tox -e $TOX_ENV
+ - flake8 --show-source sorl/
services:
- redis-server
diff --git a/AUTHORS b/AUTHORS
index 4122e8d..adbc7e8 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -3,5 +3,6 @@ sorl-thumbnail was originally created in 2010 at Aino.se by Mikko Hellsing
The PRIMARY AUTHORS are (and/or have been):
* Mikko Hellsing
- * Mario César Señoranis Ayala
- * Rolf Erik Lekang
\ No newline at end of file
+ * M. César Señoranis
+ * Rolf Erik Lekang
+ * Frankie Robertson
\ No newline at end of file
diff --git a/README.rst b/README.rst
index 43e106f..37d5525 100644
--- a/README.rst
+++ b/README.rst
@@ -5,8 +5,8 @@ Thumbnails for Django.
Features at a glance
====================
-- Support for Django 1.4, 1.5, 1.6 and 1.7
-- Python 3 support (for Django 1.5, 1.6, 1.7)
+- Support for Django 1.4, 1.5, 1.6, 1.7 and 1.8
+- Python 3 support (for Django 1.5, 1.6, 1.7, 1.8)
- Storage support
- Pluggable Engine support for `Pillow`_, `ImageMagick`_, `PIL`_, `Wand`_ and `pgmagick`_
- Pluggable Key Value Store support (cached db, redis)
@@ -26,18 +26,26 @@ Developers
==========
Feel free to create a new Pull request if you want to propose a new feature.
-If you need development support or want to discuss with other developers
+If you need development support or want to discuss with other developers
join us in the channel #sorl-thumnbnail at freenode.net or Gitter.
For releases updates and more in deep development discussion use our mailing list
in Google Groups.
- IRC Channel: irc://irc.freenode.net/#sorl-thumbnail
-
+
- Gitter: https://gitter.im/mariocesar/sorl-thumbnail
- Mailing List: sorl-thumbnail at googlegroups.com https://groups.google.com/d/forum/sorl-thumbnail
+Tests
+-----
+The tests should run with tox and pytest. Running `tox` will run all tests for all environments.
+However, it is possible to run a certain environment with `tox -e <env>`, a list of all environments
+can be found with `tox -l`. These tests require the dependencies of the different engines defined in
+the documentation. It is possible to install these dependencies into a vagrant image with the
+Vagrantfile in the repo.
+
User Support
============
@@ -75,7 +83,7 @@ your project's settings. ::
Templates Usage
-----------------
+---------------
All of the examples assume that you first load the thumbnail template tag in
your template.::
@@ -118,6 +126,22 @@ You can use the 'get_thumbnail'::
See more examples in the section `Low level API examples`_ in the Documentation
+--------------------------
+Frequently asked questions
+--------------------------
+
+Is so slow in Amazon S3 !
+-------------------------
+
+Posible related to the implementation of your Amazon S3 Backend, see the issue `#351`_
+due the storage backend reviews if there is an existing thumbnail when tries to
+generate the thumbnail that makes an extensive use of the S3 API
+
+A fast workaround if you are not willing to tweak your storage backend is to set
+the `THUMBNAIL_FORCE_OVERWRITE` setting to `True` by default is `False`, so it will
+avoid to overly query the S3 API
+
+
.. |travis| image:: https://secure.travis-ci.org/mariocesar/sorl-thumbnail.png?branch=master
@@ -127,7 +151,6 @@ See more examples in the section `Low level API examples`_ in the Documentation
.. |coveralls| image:: https://coveralls.io/repos/mariocesar/sorl-thumbnail/badge.png?branch=master
:target: https://coveralls.io/r/mariocesar/sorl-thumbnail?branch=master
-
.. _`Pillow`: http://pillow.readthedocs.org/en/latest/
.. _`ImageMagick`: http://www.imagemagick.org/script/index.php
.. _`PIL`: http://www.pythonware.com/products/pil/
@@ -137,3 +160,4 @@ See more examples in the section `Low level API examples`_ in the Documentation
.. _`Template examples`: http://sorl-thumbnail.readthedocs.org/en/latest/examples.html#template-examples
.. _`Model examples`: http://sorl-thumbnail.readthedocs.org/en/latest/examples.html#model-examples
.. _`Low level API examples`: http://sorl-thumbnail.readthedocs.org/en/latest/examples.html#low-level-api-examples
+.. _ `#351`: https://github.com/mariocesar/sorl-thumbnail/issues/351
\ No newline at end of file
diff --git a/docs/management.rst b/docs/management.rst
index 5919704..26fe4e7 100644
--- a/docs/management.rst
+++ b/docs/management.rst
@@ -32,7 +32,7 @@ you're switching Key Value Store backend.
.. _thumbnail-clear-delete-referenced:
thumbnail clear_delete_referenced
-===============
+=================================
``python manage.py thumbnail clear_delete_referenced``
Equivalent to to ``clear`` but first it will delete all thumbnail files
@@ -42,10 +42,10 @@ long as all the original images still exist this will trigger a regeneration of
all the thumbnails the Key Value Store knows about.
-.. _thumbnail-clear:
+.. _thumbnail-clear-delete-all:
thumbnail clear_delete_all
-===============
+==========================
``python manage.py thumbnail clear_delete_all``
Equivalent to to ``clear`` but afterwards it will delete all thumbnail files
diff --git a/docs/reference/settings.rst b/docs/reference/settings.rst
index 247b2db..e109766 100644
--- a/docs/reference/settings.rst
+++ b/docs/reference/settings.rst
@@ -298,7 +298,7 @@ options.
``THUMBNAIL_ORIENTATION``
-========================
+=========================
- Default: ``True``
diff --git a/docs/template.rst b/docs/template.rst
index ae05632..aa4846b 100644
--- a/docs/template.rst
+++ b/docs/template.rst
@@ -175,7 +175,7 @@ Images are not padded by default, but this can be changed by setting
``padding_color``
^^^^^^^^^^^^^^^^^
This is the color to use for padding the image. It defaults to ``#ffffff`` and
-can be globally set with the setting ``THUBMNAIL_PADDING_COLOR``.
+can be globally set with the setting ``THUMBNAIL_PADDING_COLOR``.
``options``
diff --git a/setup.py b/setup.py
index 05793f1..6cd7202 100644
--- a/setup.py
+++ b/setup.py
@@ -27,7 +27,7 @@ setup(
platforms='any',
zip_safe=False,
classifiers=[
- 'Development Status :: 4 - Beta',
+ 'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
@@ -35,9 +35,15 @@ setup(
'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.3',
+ 'Programming Language :: Python :: 3.4',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
'Topic :: Multimedia :: Graphics',
'Framework :: Django',
+ 'Framework :: Django :: 1.4',
+ 'Framework :: Django :: 1.5',
+ 'Framework :: Django :: 1.6',
+ 'Framework :: Django :: 1.7',
+ 'Framework :: Django :: 1.8',
],
cmdclass={"test": TestCommand},
)
diff --git a/sorl/__init__.py b/sorl/__init__.py
index 518b407..5af7ec6 100644
--- a/sorl/__init__.py
+++ b/sorl/__init__.py
@@ -5,10 +5,10 @@ import logging
__author__ = "Mikko Hellsing"
__license__ = "BSD"
-__version__ = '12.2'
+__version__ = '12.3'
__maintainer__ = "Mario César Señoranis Ayala"
-__email__ = "mariocesar at creat1va.com"
-__status__ = "Beta"
+__email__ = "mariocesar at humanzilla.com"
+__status__ = "Production/Stable"
class NullHandler(logging.Handler):
diff --git a/sorl/thumbnail/base.py b/sorl/thumbnail/base.py
index 9dbd01e..b826fed 100644
--- a/sorl/thumbnail/base.py
+++ b/sorl/thumbnail/base.py
@@ -101,7 +101,8 @@ class ThumbnailBackend(object):
if not thumbnail.exists():
try:
source_image = default.engine.get_image(source)
- except IOError:
+ except IOError as e:
+ logger.exception(e)
if settings.THUMBNAIL_DUMMY:
return DummyImageFile(geometry_string)
else:
diff --git a/sorl/thumbnail/compat.py b/sorl/thumbnail/compat.py
index 5a7c4e8..30e5c63 100644
--- a/sorl/thumbnail/compat.py
+++ b/sorl/thumbnail/compat.py
@@ -1,8 +1,8 @@
from __future__ import unicode_literals
import sys
-import django
+import django
__all__ = [
'json',
@@ -12,13 +12,19 @@ __all__ = [
'quote',
'quote_plus',
'URLError',
+ 'get_cache',
'force_unicode', 'text_type'
]
-PY2 = sys.version_info[0] == 2
-PY3 = sys.version_info[0] == 3
+PythonVersion = sys.version_info[0]
+
+PY2 = PythonVersion == 2
+PY3 = PythonVersion == 3
+
+# -- import_module
+from importlib import import_module
-# Django version
+# -- Related to django 1.5 incompatibility
if django.VERSION < (1, 5):
from django.utils import simplejson as json
@@ -27,16 +33,36 @@ else:
import json
from django.utils.encoding import force_text as force_unicode
+# -- Cache
+
+if django.VERSION >= (1, 7):
+ from django.core.cache import caches
+
+ get_cache = lambda cache_name: caches[cache_name]
+else:
+ from django.core.cache import get_cache
+
+# -- Text
+
try:
from django.utils.encoding import smart_text
except ImportError:
from django.utils.encoding import smart_unicode as smart_text
-# Python 2 and 3
+# -- Ordered Dict
+
+try:
+ from collections import OrderedDict
+except ImportError:
+ from django.utils.datastructures import SortedDict as OrderedDict
+
+
+# -- Python 2 and 3
if PY3:
from urllib.error import URLError
- from urllib.request import urlopen
+ from urllib.request import Request
+ from urllib.request import urlopen as _urlopen
from urllib.parse import quote, quote_plus
import urllib.parse as urlparse
@@ -46,17 +72,23 @@ if PY3:
text_type = str
string_type = str
+
+ def b(s):
+ return s.encode("latin-1")
+
+
def encode(value, charset='utf-8', errors='ignore'):
if isinstance(value, bytes):
return value
return value.encode(charset, errors)
+
def urlsplit(url):
return urlparse.urlsplit(url.decode('ascii', 'ignore'))
elif PY2:
- from urllib2 import URLError
- from urllib2 import urlopen
+ from urllib2 import URLError, Request
+ from urllib2 import urlopen as _urlopen
from urllib import quote, quote_plus
import urlparse
@@ -67,7 +99,24 @@ elif PY2:
string_type = basestring
urlsplit = urlparse.urlsplit
+
+ def b(s):
+ return s
+
+
def encode(value, charset='utf-8', errors='ignore'):
if isinstance(value, unicode):
return value.encode(charset, errors)
return unicode(value, errors=errors).encode(charset)
+
+
+# -- Urlopen with a proper default user agent
+
+def urlopen(url):
+ from sorl.thumbnail.conf import settings
+
+ req = Request(
+ url,
+ headers={'User-Agent': "python-urllib%s/0.6" % PythonVersion}
+ )
+ return _urlopen(req, timeout=settings.THUMBNAIL_URL_TIMEOUT)
diff --git a/sorl/thumbnail/engines/base.py b/sorl/thumbnail/engines/base.py
index 3aa9f94..b8e2a9f 100644
--- a/sorl/thumbnail/engines/base.py
+++ b/sorl/thumbnail/engines/base.py
@@ -172,19 +172,19 @@ class EngineBase(object):
"""
Returns the backend image objects from an ImageFile instance
"""
- raise NotImplemented()
+ raise NotImplementedError()
def get_image_size(self, image):
"""
Returns the image width and height as a tuple
"""
- raise NotImplemented()
+ raise NotImplementedError()
def is_valid_image(self, raw_data):
"""
Checks if the supplied raw data is valid image data
"""
- raise NotImplemented()
+ raise NotImplementedError()
def _orientation(self, image):
"""
@@ -200,51 +200,51 @@ class EngineBase(object):
RGB, GRAY
"""
- raise NotImplemented()
+ raise NotImplementedError()
def _remove_border(self, image, image_width, image_height):
"""
Remove borders around images
"""
- raise NotImplemented()
+ raise NotImplementedError()
def _entropy_crop(self, image, geometry_width, geometry_height, image_width, image_height):
"""
Crop the image to the correct aspect ratio
by removing the lowest entropy parts
"""
- raise NotImplemented()
+ raise NotImplementedError()
def _scale(self, image, width, height):
"""
Does the resizing of the image
"""
- raise NotImplemented()
+ raise NotImplementedError()
def _crop(self, image, width, height, x_offset, y_offset):
"""
Crops the image
"""
- raise NotImplemented()
+ raise NotImplementedError()
def _get_raw_data(self, image, format_, quality, image_info=None, progressive=False):
"""
Gets raw data given the image, format and quality. This method is
called from :meth:`write`
"""
- raise NotImplemented()
+ raise NotImplementedError()
def _padding(self, image, geometry, options):
"""
Pads the image
"""
- raise NotImplemented()
+ raise NotImplementedError()
def _cropbox(self, image, x, y, x2, y2):
- raise NotImplemented()
+ raise NotImplementedError()
def _rounded(self, image, r):
- raise NotImplemented()
+ raise NotImplementedError()
def _blur(self, image, radius):
- raise NotImplemented()
+ raise NotImplementedError()
diff --git a/sorl/thumbnail/engines/convert_engine.py b/sorl/thumbnail/engines/convert_engine.py
index f8c6888..6926aba 100644
--- a/sorl/thumbnail/engines/convert_engine.py
+++ b/sorl/thumbnail/engines/convert_engine.py
@@ -2,14 +2,15 @@ from __future__ import unicode_literals, with_statement
import re
import os
import subprocess
-from tempfile import NamedTemporaryFile
-from django.utils.datastructures import SortedDict
from django.utils.encoding import smart_str
+from django.core.files.temp import NamedTemporaryFile
from sorl.thumbnail.base import EXTENSIONS
+from sorl.thumbnail.compat import b
from sorl.thumbnail.conf import settings
from sorl.thumbnail.engines.base import EngineBase
+from sorl.thumbnail.compat import OrderedDict
size_re = re.compile(r'^(?:.+) (?:[A-Z]+) (?P<x>\d+)x(?P<y>\d+)')
@@ -69,7 +70,7 @@ class Engine(EngineBase):
"""
with NamedTemporaryFile(mode='wb', delete=False) as fp:
fp.write(source.read())
- return {'source': fp.name, 'options': SortedDict(), 'size': None}
+ return {'source': fp.name, 'options': OrderedDict(), 'size': None}
def get_image_size(self, image):
"""
@@ -108,7 +109,7 @@ class Engine(EngineBase):
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.wait()
result = p.stdout.read().strip()
- if result and result != 'unknown':
+ if result and result != b('unknown'):
result = int(result)
options = image['options']
if result == 2:
diff --git a/sorl/thumbnail/engines/pil_engine.py b/sorl/thumbnail/engines/pil_engine.py
index 5cff1e4..db77187 100644
--- a/sorl/thumbnail/engines/pil_engine.py
+++ b/sorl/thumbnail/engines/pil_engine.py
@@ -69,7 +69,7 @@ class Engine(EngineBase):
def _orientation(self, image):
try:
exif = image._getexif()
- except (AttributeError, IOError, KeyError, IndexError):
+ except:
exif = None
if exif:
@@ -97,7 +97,12 @@ class Engine(EngineBase):
if image.mode == 'RGBA':
return image # RGBA is just RGB + Alpha
if image.mode == 'LA' or (image.mode == 'P' and 'transparency' in image.info):
- return image.convert('RGBA')
+ newimage = image.convert('RGBA')
+ transparency = image.info.get('transparency')
+ if transparency is not None:
+ mask = Image.new('L', image.size, color=transparency)
+ newimage.putalpha(mask)
+ return newimage
return image.convert('RGB')
if colorspace == 'GRAY':
return image.convert('L')
diff --git a/sorl/thumbnail/engines/wand_engine.py b/sorl/thumbnail/engines/wand_engine.py
index 955c2c7..189e2ef 100644
--- a/sorl/thumbnail/engines/wand_engine.py
+++ b/sorl/thumbnail/engines/wand_engine.py
@@ -50,9 +50,15 @@ class Engine(EngineBase):
def _colorspace(self, image, colorspace):
if colorspace == 'RGB':
- image.type = 'truecolor'
+ if image.alpha_channel:
+ image.type = 'truecolormatte'
+ else:
+ image.type = 'truecolor'
elif colorspace == 'GRAY':
- image.type = 'grayscale'
+ if image.alpha_channel:
+ image.type = 'grayscalematte'
+ else:
+ image.type = 'grayscale'
else:
return image
return image
diff --git a/sorl/thumbnail/fields.py b/sorl/thumbnail/fields.py
index ce4c309..af4cd0c 100644
--- a/sorl/thumbnail/fields.py
+++ b/sorl/thumbnail/fields.py
@@ -47,7 +47,7 @@ class ImageField(models.ImageField):
return (cls_name, args, kwargs)
-class ImageFormField(forms.ImageField):
+class ImageFormField(forms.FileField):
default_error_messages = {
'invalid_image': _("Upload a valid image. The file you uploaded was "
"either not an image or a corrupted image."),
diff --git a/sorl/thumbnail/helpers.py b/sorl/thumbnail/helpers.py
index 24d360d..800e4e2 100644
--- a/sorl/thumbnail/helpers.py
+++ b/sorl/thumbnail/helpers.py
@@ -1,11 +1,10 @@
from __future__ import unicode_literals
-import math
+
import hashlib
+import math
from django.core.exceptions import ImproperlyConfigured
-from django.utils.importlib import import_module
-
-from sorl.thumbnail.compat import json, encode, smart_text
+from sorl.thumbnail.compat import encode, json, smart_text, import_module
class ThumbnailError(Exception):
diff --git a/sorl/thumbnail/images.py b/sorl/thumbnail/images.py
index 3ed9991..22fc887 100644
--- a/sorl/thumbnail/images.py
+++ b/sorl/thumbnail/images.py
@@ -7,7 +7,6 @@ import re
from django.core.files.base import File, ContentFile
from django.core.files.storage import Storage, default_storage
from django.utils.functional import LazyObject, empty
-
from sorl.thumbnail import default
from sorl.thumbnail.conf import settings
from sorl.thumbnail.compat import (json, urlopen, urlparse, urlsplit,
@@ -16,7 +15,6 @@ from sorl.thumbnail.compat import (json, urlopen, urlparse, urlsplit,
from sorl.thumbnail.helpers import ThumbnailError, tokey, get_module_class, deserialize
from sorl.thumbnail.parsers import parse_geometry
-
url_pat = re.compile(r'^(https?|ftp):\/\/')
@@ -48,7 +46,7 @@ class BaseImageFile(object):
size = []
def exists(self):
- raise NotImplemented()
+ raise NotImplementedError()
@property
def width(self):
@@ -71,7 +69,7 @@ class BaseImageFile(object):
@property
def url(self):
- raise NotImplemented()
+ raise NotImplementedError()
src = url
@@ -203,11 +201,7 @@ class UrlStorage(Storage):
return urlparse.urlunsplit((scheme, netloc, path, qs, anchor))
def open(self, name, mode='rb'):
- return urlopen(
- self.normalize_url(name),
- None,
- settings.THUMBNAIL_URL_TIMEOUT
- )
+ return urlopen(self.normalize_url(name))
def exists(self, name):
try:
diff --git a/sorl/thumbnail/kvstores/base.py b/sorl/thumbnail/kvstores/base.py
index 763cd8a..dad35e1 100644
--- a/sorl/thumbnail/kvstores/base.py
+++ b/sorl/thumbnail/kvstores/base.py
@@ -184,7 +184,7 @@ class KVStoreBase(object):
"""
Gets the value from keystore, returns `None` if not found.
"""
- raise NotImplemented()
+ raise NotImplementedError()
def _set_raw(self, key, value):
"""
@@ -192,16 +192,16 @@ class KVStoreBase(object):
chars. Value is a ``unicode`` object with an unknown (reasonable)
length.
"""
- raise NotImplemented()
+ raise NotImplementedError()
def _delete_raw(self, *keys):
"""
Deletes the keys. Silent failure for missing keys.
"""
- raise NotImplemented()
+ raise NotImplementedError()
def _find_keys_raw(self, prefix):
"""
Finds all keys with prefix
"""
- raise NotImplemented()
+ raise NotImplementedError()
diff --git a/sorl/thumbnail/kvstores/cached_db_kvstore.py b/sorl/thumbnail/kvstores/cached_db_kvstore.py
index 8dedaea..3ad238b 100644
--- a/sorl/thumbnail/kvstores/cached_db_kvstore.py
+++ b/sorl/thumbnail/kvstores/cached_db_kvstore.py
@@ -1,4 +1,5 @@
-from django.core.cache import cache, get_cache, InvalidCacheBackendError
+from django.core.cache import cache, InvalidCacheBackendError
+from sorl.thumbnail.compat import get_cache
from sorl.thumbnail.kvstores.base import KVStoreBase
from sorl.thumbnail.conf import settings
from sorl.thumbnail.models import KVStore as KVStoreModel
@@ -11,10 +12,14 @@ class EMPTY_VALUE(object):
class KVStore(KVStoreBase):
def __init__(self):
super(KVStore, self).__init__()
+
+ @property
+ def cache(self):
try:
- self.cache = get_cache(settings.THUMBNAIL_CACHE)
+ kv_cache = get_cache(settings.THUMBNAIL_CACHE)
except InvalidCacheBackendError:
- self.cache = cache
+ kv_cache = cache
+ return kv_cache
def clear(self, delete_thumbnails=False):
"""
diff --git a/sorl/thumbnail/kvstores/dbm_kvstore.py b/sorl/thumbnail/kvstores/dbm_kvstore.py
index 629f5e6..8a645b6 100644
--- a/sorl/thumbnail/kvstores/dbm_kvstore.py
+++ b/sorl/thumbnail/kvstores/dbm_kvstore.py
@@ -7,6 +7,8 @@ from sorl.thumbnail.conf import settings
try:
import anydbm as dbm
+except KeyError:
+ import dbm
except ImportError:
# Python 3, hopefully
import dbm
diff --git a/sorl/thumbnail/management/commands/thumbnail.py b/sorl/thumbnail/management/commands/thumbnail.py
index b344d66..2218c2d 100644
--- a/sorl/thumbnail/management/commands/thumbnail.py
+++ b/sorl/thumbnail/management/commands/thumbnail.py
@@ -4,17 +4,17 @@ from __future__ import unicode_literals, print_function
import sys
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import LabelCommand, CommandError
from sorl.thumbnail import default
from sorl.thumbnail.images import delete_all_thumbnails
-class Command(BaseCommand):
+class Command(LabelCommand):
help = (
'Handles thumbnails and key value store'
)
- args = '[cleanup, clear clear_delete_referenced clear_delete_all]'
+ missing_args_message = 'Enter one of [cleanup, clear clear_delete_referenced clear_delete_all]'
def handle(self, *labels, **options):
verbosity = int(options.get('verbosity'))
diff --git a/sorl/thumbnail/migrations/0001_initial.py b/sorl/thumbnail/migrations/0001_initial.py
new file mode 100644
index 0000000..7e4c226
--- /dev/null
+++ b/sorl/thumbnail/migrations/0001_initial.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='KVStore',
+ fields=[
+ ('key', models.CharField(serialize=False, db_column='key', max_length=200, primary_key=True)),
+ ('value', models.TextField()),
+ ],
+ ),
+ ]
diff --git a/sorl/thumbnail/migrations/__init__.py b/sorl/thumbnail/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/sorl/thumbnail/templatetags/thumbnail.py b/sorl/thumbnail/templatetags/thumbnail.py
index fd35eef..31b1794 100644
--- a/sorl/thumbnail/templatetags/thumbnail.py
+++ b/sorl/thumbnail/templatetags/thumbnail.py
@@ -86,7 +86,7 @@ class ThumbnailNodeBase(Node):
return self.nodelist_empty.render(context)
def _render(self, context):
- raise NotImplemented()
+ raise NotImplementedError()
class ThumbnailNode(ThumbnailNodeBase):
diff --git a/tests/runalltests.sh b/tests/runalltests.sh
deleted file mode 100755
index 3682ed3..0000000
--- a/tests/runalltests.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#/bin/bash
-
-for name in pil pgmagick imagemagick graphicsmagick wand redis dbm
-do
- ./runtests.py --settings=settings.$name;
-done
diff --git a/tests/runtests.py b/tests/runtests.py
deleted file mode 100755
index bdbd8bd..0000000
--- a/tests/runtests.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env python
-from __future__ import unicode_literals
-import os
-import sys
-from os.path import abspath, dirname, join as pjoin
-
-import django
-from django.conf import settings
-
... 2555 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/sorl-thumbnail.git
More information about the Python-modules-commits
mailing list