models.py 2.73 KB
Newer Older
1
from django.urls import reverse
2
3
from django.conf import settings
from django.utils.functional import cached_property
4
from django.db import models
5

6
7
from PIL import Image

8
import hashlib
9
10
11
12
13
14
import os
import random

COVER_FILENAME = 'cover.jpg'


15
16
17
18
19
20
21
def photo_uploadto(instance, filename):
    return os.path.join(Album.photosdir, instance.album.dirname, filename)


class Photo(models.Model):
    album = models.ForeignKey('Album', on_delete=models.CASCADE)
    file = models.ImageField(upload_to=photo_uploadto)
Joost Rijneveld's avatar
Joost Rijneveld committed
22
23
24
25
26
    rotation = models.IntegerField(
        default=0,
        choices=((x, x) for x in (0, 90, 180, 270)),
        help_text="This does not modify the original image file.",
    )
27
    hidden = models.BooleanField(default=False)
28

29
30
31
32
33
34
35
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.file:
            self._orig_file = self.file.path
        else:
            self._orig_file = ""

36
37
38
    def __str__(self):
        return self.file.name

39
40
41
    def save(self, *args, **kwargs):
        super(Photo, self).save(*args, **kwargs)

42
        if self._orig_file != self.file.path:
43
            image_path = self.file.path
44
            image = Image.open(image_path)
45
            # Image.thumbnail does not upscale an image that is smaller
46
47
            image.thumbnail(settings.PHOTO_UPLOAD_SIZE, Image.ANTIALIAS)
            image.save(image_path, "JPEG")
48
            self._orig_file = self.file.path
49

50

51
52
53
54
class Album(models.Model):
    title = models.CharField(max_length=200)
    dirname = models.CharField(max_length=200)
    date = models.DateField()
55
    slug = models.SlugField()
56
    hidden = models.BooleanField(default=False)
57
58
    _cover = models.OneToOneField(Photo, on_delete=models.SET_NULL, blank=True,
                                  null=True, related_name='covered_album')
59
    shareable = models.BooleanField(default=False)
60
61
62
63
64
65

    photosdir = 'photos'
    photospath = os.path.join(settings.MEDIA_ROOT, photosdir)

    @cached_property
    def cover(self):
66
67
        if self._cover is not None:
            return self._cover
68
69
        else:
            random.seed(self.dirname)
70
71
            cover = random.choice(self.photo_set.all())
        return cover
72

73
74
75
76
    def __str__(self):
        return '{} {}'.format(self.date.strftime('%Y-%m-%d'), self.title)

    def get_absolute_url(self):
77
        return reverse('photos:album', args=[str(self.slug)])
78
79

    def save(self, *args, **kwargs):
80
81
82
83
        # dirname is only set for new objects, to avoid ever changing it
        if self.pk is None:
            self.dirname = self.slug
        super(Album, self).save(*args, **kwargs)
84
85
86
87
88

    @property
    def access_token(self):
        return hashlib.sha256('{}album{}'.format(settings.SECRET_KEY, self.pk)
                              .encode('utf-8')).hexdigest()