thumbnail.py 1.97 KB
Newer Older
1
2
import os

3
4
from django import template
from django.conf import settings
Thom Wiggers's avatar
Thom Wiggers committed
5
from django.db.models.fields.files import ImageFieldFile
6
from django.urls import reverse
7
from django.utils.http import urlquote
8
9
10
11
12

register = template.Library()


@register.simple_tag
13
def thumbnail(path, size, fit=True):
Thom Wiggers's avatar
Thom Wiggers committed
14
15
16
    if isinstance(path, ImageFieldFile):
        path = path.name

17
    size_fit = '{}_{}'.format(size, int(fit))
18
    parts = path.split('/')
19

20
    if parts[0] == 'public':
21
        thumbpath = os.path.join(parts[0], 'thumbnails', size_fit, *parts[1:])
22
    else:
23
        thumbpath = os.path.join('thumbnails', size_fit, path)
24
25
26
27

    full_thumbpath = os.path.join(settings.MEDIA_ROOT, thumbpath)
    full_path = os.path.join(settings.MEDIA_ROOT, path)

28
29
    # Check if we need to generate, then redirect to the generating route,
    # otherwise just return the file path
30
    if (not os.path.isfile(full_thumbpath) or
Joost Rijneveld's avatar
Joost Rijneveld committed
31
            os.path.getmtime(full_path) > os.path.getmtime(full_thumbpath)):
32
33
        pathuri = urlquote(path, safe='')
        thumburi = urlquote(thumbpath, safe='')
34
35
36
        # We provide a URL instead of calling it as a function, so that using
        # it means kicking off a new GET request. If we would generate all
        # thumbnails inline, loading an album overview would have high latency.
37
38
        return reverse('generate-thumbnail',
                       args=[size_fit, pathuri, thumburi])
39

40
    # If we're dealing with an image in media/public/..
41
    if parts[0] == 'public':
42
43
        # We actually want it to end up in media/public/thumbnails/..
        # since those files can be accessed without passing through a view.
Thom Wiggers's avatar
Thom Wiggers committed
44
        return settings.MEDIA_URL + thumbpath
45
46

    # Otherwise simply place it in media/thumbnails.
47
48
49
    # We provide a URL instead of calling it as a function, so that using
    # it means kicking off a new GET request. If we would generate all
    # thumbnails inline, loading an album overview would have high latency.
50
    return reverse('private-thumbnails', args=[size_fit, path])