From cb2610006b2cc71ae182469b1d28199e9f5b5d7f Mon Sep 17 00:00:00 2001
From: Erwan Rouchet <rouchet@teklia.com>
Date: Wed, 29 Jan 2020 16:31:42 +0100
Subject: [PATCH] Remove Pillow from the backend

---
 .gitlab-ci.yml                      |  2 +-
 Dockerfile                          |  2 +-
 arkindex/images/models.py           | 28 ----------------------------
 arkindex/images/tests/test_image.py | 19 -------------------
 base/requirements.txt               |  1 -
 5 files changed, 2 insertions(+), 50 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8e6131e823..3ac73f105d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,4 +1,4 @@
-image: registry.gitlab.com/arkindex/backend:base-0.10.4
+image: registry.gitlab.com/arkindex/backend:base-0.11.1
 stages:
   - test
   - build
diff --git a/Dockerfile b/Dockerfile
index 6c25f6e721..3e04c49d7c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM registry.gitlab.com/arkindex/backend:base-0.10.4
+FROM registry.gitlab.com/arkindex/backend:base-0.11.1
 
 ARG COMMON_BRANCH=master
 ARG COMMON_ID=9855787
diff --git a/arkindex/images/models.py b/arkindex/images/models.py
index bf4a880303..e7ee7b54f8 100644
--- a/arkindex/images/models.py
+++ b/arkindex/images/models.py
@@ -11,8 +11,6 @@ from arkindex.project.models import IndexableModel
 from arkindex.project.fields import StripSlashURLField, LStripTextField, MD5HashField
 from arkindex.project.polygon import PolygonField
 from arkindex.project.aws import S3FileMixin, S3FileModelMixin, S3FileStatus
-from io import BytesIO
-from PIL import Image as PillowImage
 import logging
 import os
 import requests
@@ -306,32 +304,6 @@ class Image(S3FileModelMixin, IndexableModel):
         if save:
             self.save()
 
-    def pillow_open(self, max_width=500):
-        if self.server.is_local:
-            b = BytesIO()
-            self.s3_object.download_fileobj(b)
-            return PillowImage.open(b)
-
-        # PIL.Image.open explicitly requires seek(int) method, that the urllib responses do not provide.
-        # We therefore have to get the whole content and put it back in a file-like object
-        resp = requests.get(
-            self.get_thumbnail_url(max_width=max_width),
-            timeout=settings.IIIF_DOWNLOAD_TIMEOUT,
-        )
-        resp.raise_for_status()
-        return PillowImage.open(BytesIO(resp.content))
-
-    def pillow_save(self, pillow_img, format=None):
-        """
-        Save a PIL.Image instance to S3
-        """
-        assert self.server.is_local, 'Only images on the local server can be saved'
-        logger.debug('Saving {} to S3'.format(self.id))
-        b = BytesIO()
-        pillow_img.save(b, format=format)
-        b.seek(0)
-        self.s3_object.upload_fileobj(b)
-
     def __str__(self):
         return '{} - {}'.format(self.id, self.url)
 
diff --git a/arkindex/images/tests/test_image.py b/arkindex/images/tests/test_image.py
index f380828fc6..6f5cd728ed 100644
--- a/arkindex/images/tests/test_image.py
+++ b/arkindex/images/tests/test_image.py
@@ -1,4 +1,3 @@
-from io import BytesIO
 from unittest.mock import patch, call, MagicMock
 from django.test import override_settings
 from botocore.exceptions import ClientError
@@ -20,24 +19,6 @@ class TestImage(FixtureTestCase):
         self.assertEqual(img.path, '!#%:+/*')
         self.assertEqual(img.url, 'http://server/!#%:+/*')
 
-    @override_settings(LOCAL_IMAGESERVER_ID=-1, IIIF_DOWNLOAD_TIMEOUT=(13, 37))
-    @patch('arkindex.images.models.PillowImage.open')
-    @patch('arkindex.images.models.requests.get')
-    def test_pillow_open_url(self, get_mock, pillow_open_mock):
-        self.assertFalse(self.imgsrv.is_local)
-        img = self.imgsrv.images.create(path='image')
-        get_mock.return_value.content = b'imageblob'
-        self.assertEqual(img.pillow_open(), pillow_open_mock.return_value)
-        self.assertEqual(get_mock.call_count, 1)
-        self.assertEqual(get_mock.call_args, call('http://server/image/full/500,/0/default.jpg', timeout=(13, 37)))
-        self.assertEqual(get_mock().raise_for_status.call_count, 1)
-        self.assertEqual(pillow_open_mock.call_count, 1)
-        args, kwargs = pillow_open_mock.call_args
-        self.assertDictEqual(kwargs, {})
-        self.assertEqual(len(args), 1)
-        self.assertIsInstance(args[0], BytesIO)
-        self.assertEqual(args[0].read(), b'imageblob')
-
     def test_build_url(self):
         self.assertEqual(self.imgsrv.build_url('some/path'), 'http://server/some/path')
         self.assertEqual(self.imgsrv.build_url('/some/path'), 'http://server/some/path')
diff --git a/base/requirements.txt b/base/requirements.txt
index 080fcd2b78..8e3ddda94a 100644
--- a/base/requirements.txt
+++ b/base/requirements.txt
@@ -6,7 +6,6 @@ hiredis==1.0.0
 ijson==2.3
 lxml==4.2.3
 openpyxl==2.4.9
-Pillow==4.3.0
 psycopg2==2.7.3.2
 python-Levenshtein==0.12.0
 Twisted==19.7.0
-- 
GitLab