Projet

Général

Profil

0001-use-sorl-thumbnail-fixes-15857.patch

Benjamin Dauvergne, 03 avril 2018 15:06

Télécharger (9,01 ko)

Voir les différences:

Subject: [PATCH] use sorl-thumbnail (fixes #15857)

It replaces GraphicsMagick, we do not use the templatetag as the files
are private.
 debian/control                   |  3 +-
 fargo/fargo/admin.py             | 10 +----
 fargo/fargo/models.py            | 80 +++++++++++++++++++++++-----------------
 fargo/fargo/views.py             |  6 +--
 fargo/settings.py                |  3 ++
 fargo/templates/fargo/table.html |  8 +++-
 setup.py                         |  1 +
 7 files changed, 62 insertions(+), 49 deletions(-)
debian/control
13 13
    python-django-filters (>= 1),
14 14
    python-django-filters (<< 2),
15 15
    python-gadjo,
16
    python-magic
16
    python-magic,
17
    python-sorl-thumbnail
17 18
Recommends: python-django-mellon
18 19
Description: Fargo Document Box (Python module)
19 20

  
fargo/fargo/admin.py
14 14
                     'origin__label']
15 15

  
16 16
    def thumbnail(self, instance):
17
        data_url = instance.document.thumbnail_data_url
18
        if data_url:
19
            return format_html('<img src="{0}"/>', data_url)
20
        return ''
17
        return instance.document.thumbnail_img_tag
21 18
    thumbnail.short_description = _('thumbnail')
22 19

  
23 20

  
......
32 29
        return u', '.join(unicode(u) for u in qs)
33 30

  
34 31
    def thumbnail(self, instance):
35
        data_url = instance.thumbnail_data_url
36
        if data_url:
37
            return format_html('<img src="{0}"/>', data_url)
38
        return ''
32
        return instance.thumbnail_img_tag
39 33
    thumbnail.short_description = _('thumbnail')
40 34

  
41 35

  
fargo/fargo/models.py
11 11
from django.utils.translation import ugettext_lazy as _
12 12
from django.utils.text import slugify
13 13
from django.utils.http import urlquote
14
from django.utils.html import format_html
14 15
from django.dispatch import receiver
15 16
from django.db.models.signals import post_save, post_delete
16 17
from django.core.files.storage import default_storage
17 18

  
19
from sorl.thumbnail import get_thumbnail, delete
20
from sorl.thumbnail.conf import settings as thumbnail_settings
21

  
18 22
from jsonfield import JSONField
19 23

  
20 24
from . import utils, managers
......
83 87
    def get_download_url(self):
84 88
        return reverse('download', kwargs={'pk': self.id, 'filename': self.filename_encoded})
85 89

  
86
    def get_thumbnail_url(self):
87
        if self.document.thumbnail:
88
            return reverse('thumbnail', kwargs={'pk': self.id, 'filename': self.filename_encoded})
89
        return ''
90
    @property
91
    def thumbnail_image(self):
92
        thumbnail = self.document.thumbnail
93
        if not thumbnail:
94
            return ''
95
        src = reverse('thumbnail', kwargs={'pk': self.id, 'filename': self.filename_encoded})
96
        return {'src': src, 'width': thumbnail.width, 'height': thumbnail.height}
90 97

  
91 98
    @property
92 99
    def css_classes(self):
......
182 189
            self.mime_type = utils.get_mime_type(self.content.file.name) or ''
183 190
        super(Document, self).save(*args, **kwargs)
184 191

  
185
    @property
186
    def thumbnail_path(self):
187
        name = os.path.basename(self.content.name)
188
        return os.path.join('thumbmails', name + '.png')
189

  
190
    @property
191
    def thumbnail_full_path(self):
192
        return default_storage.path(self.thumbnail_path)
193

  
194 192
    @property
195 193
    def thumbnail(self):
194
        if not (self.mime_type.startswith('image/') or self.mime_type == 'application/pdf'):
195
            return None
196 196
        try:
197
            return default_storage.open(self.thumbnail_path)
198
        except IOError:
197
            thumbnail = get_thumbnail(self.content, '200x200')
198
        except:  # sorl-thumbnail can crash in unexpected ways
199 199
            return None
200
        try:
201
            # check file exists and is readable
202
            default_storage.open(thumbnail.name)
203
            return thumbnail
204
        except IOError:
205
            pass
206
        return None
200 207

  
201 208
    @property
202 209
    def thumbnail_data_url(self):
203
        if self.thumbnail:
204
            return 'data:image/png;base64,%s' % base64.b64encode(self.thumbnail.read())
205
        return None
210
        thumbnail = self.thumbnail
211
        if not thumbnail:
212
            return ''
213

  
214
        mime_type = 'image/' + thumbnail_settings.THUMBNAIL_FORMAT.lower()
215
        return 'data:%s;base64,%s' % (mime_type, base64.b64encode(thumbnail.read()))
216

  
217
    @property
218
    def thumbnail_img_tag(self):
219
        thumbnail = self.thumbnail
220
        if not thumbnail:
221
            return ''
222

  
223
        return format_html('<img width="{}" height="{}" src="{}"/>',
224
                           thumbnail.width,
225
                           thumbnail.height,
226
                           self.thumbnail_data_url)
227

  
228
    @property
229
    def thumbnail_image(self):
230
        thumbnail = self.thumbnail
231
        if not thumbnail:
232
            return ''
233
        return {'src': self.thumbnail_data_url, 'width': thumbnail.width, 'height': thumbnail.height}
206 234

  
207 235
    class Meta:
208 236
        verbose_name = _('document')
......
210 238
        ordering = ('content_hash',)
211 239

  
212 240

  
213
@receiver(post_save, sender=Document)
214
def create_thumbnail(sender, instance, created, **kwargs):
215
    if not created:
216
        return
217

  
218
    def do():
219
        dirpath = os.path.dirname(instance.thumbnail_full_path)
220
        if not os.path.isdir(dirpath):
221
            os.makedirs(dirpath)
222
        subprocess.call(['gm', 'convert', '-geometry', 'x200',
223
                         instance.content.file.name,
224
                         instance.thumbnail_full_path])
225
    threading.Thread(target=do).start()
226

  
227

  
228 241
@receiver(post_delete, sender=Document)
229 242
def delete_file(sender, instance, **kwargs):
230 243
    if instance.content:
231 244
        if os.path.isfile(instance.content.path):
232 245
            os.remove(instance.content.path)
246
    delete(instance.content)
fargo/fargo/views.py
179 179
    def get(self, request, pk, filename):
180 180
        user_document = get_object_or_404(self.get_queryset(), pk=pk,
181 181
                                          user=self.request.user)
182
        return self.return_user_document(user_document)
183

  
184
    def return_user_document(self, user_document):
185 182
        thumbnail = user_document.document.thumbnail
186 183
        if not thumbnail:
187 184
            raise Http404
188
        response = HttpResponse(thumbnail.chunks(), content_type='image/png')
189
        return response
185
        return HttpResponse(thumbnail.chunks(), content_type='image/jpeg')
190 186

  
191 187

  
192 188
class RemoteDownload(Download):
fargo/settings.py
41 41
    'fargo.fargo',
42 42
    'rest_framework',
43 43
    'fargo.oauth2',
44
    'sorl.thumbnail',
44 45
)
45 46

  
46 47
MIDDLEWARE_CLASSES = (
......
226 227

  
227 228
INCLUDE_EDIT_LINK = False
228 229

  
230
THUMBNAIL_ENGINE = 'sorl.thumbnail.engines.convert_engine.Engine'
231

  
229 232
FARGO_CODE_LIFETIME = 300
230 233
FARGO_ACCESS_TOKEN_LIFETIME = 3600
231 234
FARGO_OAUTH2_TEMPFILE_LIFETIME = 86400
fargo/templates/fargo/table.html
31 31
    {% for column, cell in row.items %}
32 32
      <td {{ column.attrs.td.as_html }}>{% if column.localize == None %}{{ cell }}{% else %}{% if column.localize %}{{ cell|localize }}{% else %}{{ cell|unlocalize }}{% endif %}{% endif %}</td>
33 33
    {% endfor %}
34
      {% with url=row.record.get_thumbnail_url %}
35
      <td class="thumbnail" rowspan={{ row.record.description|yesno:"2,1" }}>{% if url %}<img src="{{ url }}"/>{% endif %}</td>
34
      {% with thumbnail=row.record.thumbnail_image %}
35
        <td class="thumbnail" rowspan={{ row.record.description|yesno:"2,1" }}>
36
           {% if thumbnail %}
37
             <img src="{{ thumbnail.src }}" height="{{ thumbnail.height }}" width="{{ thumbnail.width }}"/>
38
           {% endif %}
39
        </td>
36 40
      {% endwith %}
37 41
    <td class="action-column" rowspan={{ row.record.description|yesno:"2,1" }}>
38 42
      {% block action-column %}
setup.py
105 105
        'djangorestframework>=3.3,<3.4',
106 106
        'file-magic',
107 107
        'requests',
108
        'sorl-thumbnail',
108 109
    ],
109 110
    zip_safe=False,
110 111
    cmdclass={
111
-