aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/pkgs/development/python-modules/thumbor
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2019-10-05 12:43:18 +0000
committerKatharina Fey <kookie@spacekookie.de>2019-10-05 12:44:52 +0000
commitcf85056ba64caf3267d43255ef4a1243e9c8ee3b (patch)
tree3051519e9c8275b870aac43f80af875715c9d124 /nixpkgs/pkgs/development/python-modules/thumbor
parent1148b1d122bc03e9a3665856c9b7bb96bd4e3994 (diff)
parent2436c27541b2f52deea3a4c1691216a02152e729 (diff)
Add 'nixpkgs/' from commit '2436c27541b2f52deea3a4c1691216a02152e729'
git-subtree-dir: nixpkgs git-subtree-mainline: 1148b1d122bc03e9a3665856c9b7bb96bd4e3994 git-subtree-split: 2436c27541b2f52deea3a4c1691216a02152e729
Diffstat (limited to 'nixpkgs/pkgs/development/python-modules/thumbor')
-rw-r--r--nixpkgs/pkgs/development/python-modules/thumbor/0001-Don-t-use-which-implementation-to-find-required-exec.patch277
-rw-r--r--nixpkgs/pkgs/development/python-modules/thumbor/default.nix90
2 files changed, 367 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/development/python-modules/thumbor/0001-Don-t-use-which-implementation-to-find-required-exec.patch b/nixpkgs/pkgs/development/python-modules/thumbor/0001-Don-t-use-which-implementation-to-find-required-exec.patch
new file mode 100644
index 00000000000..4a2d9df0618
--- /dev/null
+++ b/nixpkgs/pkgs/development/python-modules/thumbor/0001-Don-t-use-which-implementation-to-find-required-exec.patch
@@ -0,0 +1,277 @@
+From bd5a5b58b438ff34d27781e28cd7fab93bfc9f3f Mon Sep 17 00:00:00 2001
+From: Maximilian Bosch <maximilian@mbosch.me>
+Date: Sat, 9 Mar 2019 23:26:30 +0100
+Subject: [PATCH] Don't use `which` implementation to find required executables
+
+Nix specific patch.
+
+Rather than relying on a global state, we set an absolute store path for
+all external dependencies to ensure their functionality.
+---
+ integration_tests/__init__.py | 4 ++--
+ tests/engines/test_gif.py | 2 +-
+ tests/handlers/test_base_handler.py | 30 ++++++++++++++---------------
+ tests/optimizers/test_gifv.py | 2 +-
+ tests/test_server.py | 4 ++++
+ tests/test_utils.py | 3 +++
+ thumbor/server.py | 7 +------
+ 7 files changed, 26 insertions(+), 26 deletions(-)
+
+diff --git a/integration_tests/__init__.py b/integration_tests/__init__.py
+index 9bdd0a3..7d9de8f 100644
+--- a/integration_tests/__init__.py
++++ b/integration_tests/__init__.py
+@@ -15,7 +15,7 @@ class EngineCase(AsyncHTTPTestCase):
+ def get_app(self):
+ cfg = Config(SECURITY_KEY='ACME-SEC')
+ server_params = ServerParameters(None, None, None, None, None, None)
+- server_params.gifsicle_path = which('gifsicle')
++ server_params.gifsicle_path = '@gifsicle@'
+
+ cfg.DETECTORS = [
+ 'thumbor.detectors.face_detector',
+@@ -28,7 +28,7 @@ class EngineCase(AsyncHTTPTestCase):
+ cfg.FILE_LOADER_ROOT_PATH = os.path.join(os.path.dirname(__file__), 'imgs')
+ cfg.ENGINE = getattr(self, 'engine', None)
+ cfg.USE_GIFSICLE_ENGINE = True
+- cfg.FFMPEG_PATH = which('ffmpeg')
++ cfg.FFMPEG_PATH = '@ffmpeg@'
+ cfg.ENGINE_THREADPOOL_SIZE = 10
+ cfg.OPTIMIZERS = [
+ 'thumbor.optimizers.gifv',
+diff --git a/tests/engines/test_gif.py b/tests/engines/test_gif.py
+index c0c8430..ce0cc51 100644
+--- a/tests/engines/test_gif.py
++++ b/tests/engines/test_gif.py
+@@ -44,7 +44,7 @@ class GitEngineTestCase(TestCase):
+ def get_server(self):
+ server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
+ server.security_key = 'ACME-SEC'
+- server.gifsicle_path = which('gifsicle')
++ server.gifsicle_path = '@gifsicle@'
+ return server
+
+ def get_context(self, *args, **kwargs):
+diff --git a/tests/handlers/test_base_handler.py b/tests/handlers/test_base_handler.py
+index 69dc110..4493abe 100644
+--- a/tests/handlers/test_base_handler.py
++++ b/tests/handlers/test_base_handler.py
+@@ -557,7 +557,7 @@ class ImageOperationsWithAutoWebPTestCase(BaseImagingTestCase):
+ server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
+ server.security_key = 'ACME-SEC'
+ ctx = Context(server, cfg, importer)
+- ctx.server.gifsicle_path = which('gifsicle')
++ ctx.server.gifsicle_path = '@gifsicle@'
+ return ctx
+
+ def get_as_webp(self, url):
+@@ -657,7 +657,7 @@ class ImageOperationsWithAutoWebPWithResultStorageTestCase(BaseImagingTestCase):
+ server.security_key = 'ACME-SEC'
+ ctx = Context(server, cfg, importer)
+ ctx.request = self.get_request()
+- ctx.server.gifsicle_path = which('gifsicle')
++ ctx.server.gifsicle_path = '@gifsicle@'
+ return ctx
+
+ @property
+@@ -783,7 +783,7 @@ class ImageOperationsWithGifVTestCase(BaseImagingTestCase):
+ cfg = Config(SECURITY_KEY='ACME-SEC')
+ cfg.LOADER = "thumbor.loaders.file_loader"
+ cfg.FILE_LOADER_ROOT_PATH = self.loader_path
+- cfg.FFMPEG_PATH = which('ffmpeg')
++ cfg.FFMPEG_PATH = '@ffmpeg@'
+ cfg.OPTIMIZERS = [
+ 'thumbor.optimizers.gifv',
+ ]
+@@ -793,7 +793,7 @@ class ImageOperationsWithGifVTestCase(BaseImagingTestCase):
+ server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
+ server.security_key = 'ACME-SEC'
+ ctx = Context(server, cfg, importer)
+- ctx.server.gifsicle_path = which('gifsicle')
++ ctx.server.gifsicle_path = '@gifsicle@'
+ return ctx
+
+ def test_should_convert_animated_gif_to_mp4_when_filter_without_params(self):
+@@ -828,7 +828,7 @@ class ImageOperationsImageCoverTestCase(BaseImagingTestCase):
+ server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
+ server.security_key = 'ACME-SEC'
+ ctx = Context(server, cfg, importer)
+- ctx.server.gifsicle_path = which('gifsicle')
++ ctx.server.gifsicle_path = '@gifsicle@'
+ return ctx
+
+ def test_can_get_image_cover(self):
+@@ -849,7 +849,7 @@ class ImageOperationsWithResultStorageTestCase(BaseImagingTestCase):
+ cfg.RESULT_STORAGE_FILE_STORAGE_ROOT_PATH = self.root_path
+
+ cfg.USE_GIFSICLE_ENGINE = True
+- cfg.FFMPEG_PATH = which('ffmpeg')
++ cfg.FFMPEG_PATH = '@ffmpeg@'
+ cfg.AUTO_WEBP = True
+ cfg.OPTIMIZERS = [
+ 'thumbor.optimizers.gifv',
+@@ -860,7 +860,7 @@ class ImageOperationsWithResultStorageTestCase(BaseImagingTestCase):
+ server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
+ server.security_key = 'ACME-SEC'
+ ctx = Context(server, cfg, importer)
+- ctx.server.gifsicle_path = which('gifsicle')
++ ctx.server.gifsicle_path = '@gifsicle@'
+
+ return ctx
+
+@@ -891,7 +891,7 @@ class ImageOperationsResultStorageOnlyTestCase(BaseImagingTestCase):
+ cfg.RESULT_STORAGE = 'thumbor.result_storages.file_storage'
+ cfg.RESULT_STORAGE_EXPIRATION_SECONDS = 60
+ cfg.RESULT_STORAGE_FILE_STORAGE_ROOT_PATH = self.root_path
+- cfg.FFMPEG_PATH = which('ffmpeg')
++ cfg.FFMPEG_PATH = '@ffmpeg@'
+
+ cfg.USE_GIFSICLE_ENGINE = True
+ cfg.AUTO_WEBP = True
+@@ -904,7 +904,7 @@ class ImageOperationsResultStorageOnlyTestCase(BaseImagingTestCase):
+ server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
+ server.security_key = 'ACME-SEC'
+ ctx = Context(server, cfg, importer)
+- ctx.server.gifsicle_path = which('gifsicle')
++ ctx.server.gifsicle_path = '@gifsicle@'
+
+ return ctx
+
+@@ -1040,7 +1040,7 @@ class ImageOperationsWithMaxPixels(BaseImagingTestCase):
+ server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
+ server.security_key = 'ACME-SEC'
+ ctx = Context(server, cfg, importer)
+- ctx.server.gifsicle_path = which('gifsicle')
++ ctx.server.gifsicle_path = '@gifsicle@'
+ return ctx
+
+ def test_should_error(self):
+@@ -1061,7 +1061,7 @@ class ImageOperationsWithRespectOrientation(BaseImagingTestCase):
+ server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
+ server.security_key = 'ACME-SEC'
+ self.context = Context(server, cfg, importer)
+- self.context.server.gifsicle_path = which('gifsicle')
++ self.context.server.gifsicle_path = '@gifsicle@'
+ return self.context
+
+ def test_should_be_ok_when_orientation_exif(self):
+@@ -1153,7 +1153,7 @@ class ImageOperationsWithJpegtranTestCase(BaseImagingTestCase):
+ cfg = Config(SECURITY_KEY='ACME-SEC')
+ cfg.LOADER = "thumbor.loaders.file_loader"
+ cfg.FILE_LOADER_ROOT_PATH = self.loader_path
+- cfg.JPEGTRAN_PATH = which('jpegtran')
++ cfg.JPEGTRAN_PATH = '@jpegtran@'
+ cfg.PROGRESSIVE_JPEG = True,
+ cfg.RESULT_STORAGE_STORES_UNSAFE = True,
+ cfg.OPTIMIZERS = [
+@@ -1175,9 +1175,7 @@ class ImageOperationsWithJpegtranTestCase(BaseImagingTestCase):
+ f.write(response.body)
+ f.close()
+
+- exiftool = which('exiftool')
+- if not exiftool:
+- raise AssertionError('exiftool was not found. Please install it to run thumbor\'s tests.')
++ exiftool = '@exiftool@'
+
+ command = [
+ exiftool,
+@@ -1221,7 +1219,7 @@ class ImageOperationsWithoutStorage(BaseImagingTestCase):
+ server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
+ server.security_key = 'ACME-SEC'
+ ctx = Context(server, cfg, importer)
+- ctx.server.gifsicle_path = which('gifsicle')
++ ctx.server.gifsicle_path = '@gifsicle@'
+ return ctx
+
+ def test_meta(self):
+diff --git a/tests/optimizers/test_gifv.py b/tests/optimizers/test_gifv.py
+index 229e9cd..066f2d5 100644
+--- a/tests/optimizers/test_gifv.py
++++ b/tests/optimizers/test_gifv.py
+@@ -31,7 +31,7 @@ class GifvOptimizerTest(TestCase):
+ def get_context(self):
+ conf = Config()
+ conf.STATSD_HOST = ''
+- conf.FFMPEG_PATH = which('ffmpeg')
++ conf.FFMPEG_PATH = '@ffmpeg@'
+ ctx = Context(config=conf)
+ ctx.request = RequestParameters()
+ ctx.request.filters.append('gifv')
+diff --git a/tests/test_server.py b/tests/test_server.py
+index 5b31750..c2a65dc 100644
+--- a/tests/test_server.py
++++ b/tests/test_server.py
+@@ -11,6 +11,8 @@
+ from unittest import TestCase
+ import mock
+
++from nose.tools import nottest
++
+ from preggy import expect
+
+ from thumbor.app import ThumborServiceApp
+@@ -118,6 +120,7 @@ class ServerTestCase(TestCase):
+ expect(server_parameters.security_key).to_equal('something')
+
+ @mock.patch.object(thumbor.server, 'which')
++ @nottest
+ def test_validate_gifsicle_path(self, which_mock):
+ server_parameters = mock.Mock(security_key=None)
+ conf = Config(SECURITY_KEY='test', USE_GIFSICLE_ENGINE=True)
+@@ -128,6 +131,7 @@ class ServerTestCase(TestCase):
+ expect(server_parameters.gifsicle_path).to_equal('/usr/bin/gifsicle')
+
+ @mock.patch.object(thumbor.server, 'which')
++ @nottest
+ def test_validate_null_gifsicle_path(self, which_mock):
+ server_parameters = mock.Mock(security_key=None)
+ conf = Config(SECURITY_KEY='test', USE_GIFSICLE_ENGINE=True)
+diff --git a/tests/test_utils.py b/tests/test_utils.py
+index 38cd51b..7dd0b3e 100644
+--- a/tests/test_utils.py
++++ b/tests/test_utils.py
+@@ -10,6 +10,7 @@
+
+ from mock import Mock, patch
+ from unittest import TestCase
++from nose.tools import nottest
+ import logging
+
+ from preggy import expect
+@@ -112,6 +113,7 @@ class UtilsTestCase(TestCase):
+ test_func()
+ mock_warn.assert_called_once_with('Deprecated function test_func: func2')
+
++ @nottest
+ def test_can_which_by_path(self):
+ result = which('/bin/ls')
+ expect(result).to_equal('/bin/ls')
+@@ -119,6 +121,7 @@ class UtilsTestCase(TestCase):
+ result = which('/tmp')
+ expect(result).to_be_null()
+
++ @nottest
+ def test_can_which_by_env(self):
+ result = which('ls')
+ expect(result).to_equal('/bin/ls')
+diff --git a/thumbor/server.py b/thumbor/server.py
+index c75a769..821163b 100644
+--- a/thumbor/server.py
++++ b/thumbor/server.py
+@@ -89,12 +89,7 @@ def validate_config(config, server_parameters):
+ warnings.simplefilter('error', Image.DecompressionBombWarning)
+
+ if config.USE_GIFSICLE_ENGINE:
+- server_parameters.gifsicle_path = which('gifsicle')
+- if server_parameters.gifsicle_path is None:
+- raise RuntimeError(
+- 'If using USE_GIFSICLE_ENGINE configuration to True, the `gifsicle` binary must be in the PATH '
+- 'and must be an executable.'
+- )
++ server_parameters.gifsicle_path = '@gifsicle@'
+
+
+ def get_context(server_parameters, config, importer):
+--
+2.18.1
+
diff --git a/nixpkgs/pkgs/development/python-modules/thumbor/default.nix b/nixpkgs/pkgs/development/python-modules/thumbor/default.nix
new file mode 100644
index 00000000000..720391772b5
--- /dev/null
+++ b/nixpkgs/pkgs/development/python-modules/thumbor/default.nix
@@ -0,0 +1,90 @@
+{ buildPythonPackage, python, tornado, pycrypto, pycurl, pytz
+, pillow, derpconf, python_magic, libthumbor, webcolors
+, piexif, futures, statsd, thumborPexif, fetchFromGitHub, isPy3k, lib
+, mock, raven, nose, yanc, remotecv, pyssim, cairosvg, preggy, opencv3
+, pkgs, coreutils, substituteAll
+}:
+
+buildPythonPackage rec {
+ pname = "thumbor";
+ version = "6.7.0";
+
+ disabled = isPy3k; # see https://github.com/thumbor/thumbor/issues/1004
+
+ # Tests aren't included in PyPI tarball so use GitHub instead
+ src = fetchFromGitHub {
+ owner = pname;
+ repo = pname;
+ rev = version;
+ sha256 = "1qv02jz7ivn38dsywp7nxrlflly86x9pm2pk3yqi8m8myhc7lipg";
+ };
+
+ patches = [
+ (substituteAll {
+ src = ./0001-Don-t-use-which-implementation-to-find-required-exec.patch;
+ gifsicle = "${pkgs.gifsicle}/bin/gifsicle";
+ exiftool = "${pkgs.exiftool}/bin/exiftool";
+ jpegtran = "${pkgs.libjpeg}/bin/jpegtran";
+ ffmpeg = "${pkgs.ffmpeg}/bin/ffmpeg";
+ })
+ ];
+
+ postPatch = ''
+ substituteInPlace "setup.py" \
+ --replace '"argparse",' "" ${lib.optionalString isPy3k ''--replace '"futures",' ""''}
+ sed -i setup.py \
+ -e 's/piexif[^"]*/piexif/;s/Pillow[^"]*/Pillow/'
+ substituteInPlace "tests/test_utils.py" \
+ --replace "/bin/ls" "${coreutils}/bin/ls"
+ substituteInPlace "tests/detectors/test_face_detector.py" \
+ --replace "./thumbor" "$out/lib/${python.libPrefix}/site-packages/thumbor"
+ substituteInPlace "tests/detectors/test_glasses_detector.py" \
+ --replace "./thumbor" "$out/lib/${python.libPrefix}/site-packages/thumbor"
+ '';
+
+ checkInputs = [
+ nose
+ pyssim
+ preggy
+ mock
+ yanc
+ remotecv
+ raven
+ pkgs.redis
+ pkgs.glibcLocales
+ pkgs.gifsicle
+ ];
+
+ propagatedBuildInputs = [
+ tornado
+ pycrypto
+ pycurl
+ pytz
+ pillow
+ derpconf
+ python_magic
+ libthumbor
+ opencv3
+ webcolors
+ piexif
+ statsd
+ cairosvg
+ ] ++ lib.optionals (!isPy3k) [ futures thumborPexif ];
+
+ # Remove the source tree before running nosetests because otherwise nosetests
+ # uses that instead of the installed package. Is there some other way to
+ # achieve this?
+ checkPhase = ''
+ redis-server --port 6668 --requirepass hey_you &
+ rm -r thumbor
+ export LC_ALL="en_US.UTF-8"
+ nosetests -v --with-yanc -s tests/ -e test_redeye_applied
+ '';
+
+ meta = with lib; {
+ description = "A smart imaging service";
+ homepage = https://github.com/thumbor/thumbor/wiki;
+ license = licenses.mit;
+ maintainers = with maintainers; [ ma27 ];
+ };
+}