models.py 6.98 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# -*- coding:utf-8 -*
#
# Copyright 2016,2017
# - Skia <skia@libskia.so>
#
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
# http://ae.utbm.fr.
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License a published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.
#
#

Skia's avatar
Skia committed
25
26
from django.db import models
from django.core.urlresolvers import reverse
Krophil's avatar
Krophil committed
27
from django.conf import settings
28
from django.utils.translation import ugettext_lazy as _
29
from django.utils import timezone
Skia's avatar
Skia committed
30
31
32

from PIL import Image
from io import BytesIO
Sli's avatar
Sli committed
33
import os
Skia's avatar
Skia committed
34
35

from core.models import SithFile, User
Skia's avatar
Skia committed
36
from core.utils import resize_image, exif_auto_rotate
Skia's avatar
Skia committed
37

Sli's avatar
Sli committed
38

Skia's avatar
Skia committed
39
40
41
class SASPictureManager(models.Manager):
    def get_queryset(self):
        return super(SASPictureManager, self).get_queryset().filter(is_in_sas=True,
Sli's avatar
Sli committed
42
43
                                                                    is_folder=False)

Skia's avatar
Skia committed
44
45
46
47

class SASAlbumManager(models.Manager):
    def get_queryset(self):
        return super(SASAlbumManager, self).get_queryset().filter(is_in_sas=True,
Sli's avatar
Sli committed
48
49
                                                                  is_folder=True)

Krophil's avatar
Krophil committed
50

Skia's avatar
Skia committed
51
52
53
54
class Picture(SithFile):
    class Meta:
        proxy = True

Skia's avatar
Skia committed
55
56
    objects = SASPictureManager()

Skia's avatar
Skia committed
57
58
    @property
    def is_vertical(self):
Sli's avatar
Sli committed
59
        with open(os.path.join(settings.MEDIA_ROOT, self.file.name).encode('utf-8'), 'rb') as f:
Skia's avatar
Skia committed
60
61
62
63
            im = Image.open(BytesIO(f.read()))
            (w, h) = im.size
            return (w / h) < 1
        return False
Skia's avatar
Skia committed
64

Skia's avatar
Skia committed
65
    def can_be_edited_by(self, user):
66
        # file = SithFile.objects.filter(id=self.id).first()
Krophil's avatar
Krophil committed
67
        return user.is_in_group(settings.SITH_GROUP_SAS_ADMIN_ID)  # or user.can_edit(file)
Skia's avatar
Skia committed
68
69

    def can_be_viewed_by(self, user):
70
        # file = SithFile.objects.filter(id=self.id).first()
Skia's avatar
Skia committed
71
        return self.can_be_edited_by(user) or (self.is_in_sas and self.is_moderated and
Krophil's avatar
Krophil committed
72
                                               user.was_subscribed)  # or user.can_view(file)
Skia's avatar
Skia committed
73
74
75
76

    def get_download_url(self):
        return reverse('sas:download', kwargs={'picture_id': self.id})

Skia's avatar
Skia committed
77
78
79
80
81
82
    def get_download_compressed_url(self):
        return reverse('sas:download_compressed', kwargs={'picture_id': self.id})

    def get_download_thumb_url(self):
        return reverse('sas:download_thumb', kwargs={'picture_id': self.id})

Skia's avatar
Skia committed
83
84
85
    def get_absolute_url(self):
        return reverse('sas:picture', kwargs={'picture_id': self.id})

86
    def generate_thumbnails(self, overwrite=False):
Skia's avatar
Skia committed
87
88
89
        im = Image.open(BytesIO(self.file.read()))
        try:
            im = exif_auto_rotate(im)
Krophil's avatar
Krophil committed
90
91
        except:
            pass
Skia's avatar
Skia committed
92
93
        file = resize_image(im, max(im.size), self.mime_type.split('/')[-1])
        thumb = resize_image(im, 200, self.mime_type.split('/')[-1])
94
95
96
97
98
        compressed = resize_image(im, 1200, self.mime_type.split('/')[-1])
        if overwrite:
            self.file.delete()
            self.thumbnail.delete()
            self.compressed.delete()
Skia's avatar
Skia committed
99
100
101
102
103
104
105
106
        self.file = file
        self.file.name = self.name
        self.thumbnail = thumb
        self.thumbnail.name = self.name
        self.compressed = compressed
        self.compressed.name = self.name
        self.save()

Skia's avatar
Skia committed
107
108
    def rotate(self, degree):
        for attr in ['file', 'compressed', 'thumbnail']:
Skia's avatar
Skia committed
109
            name = self.__getattribute__(attr).name
Sli's avatar
Sli committed
110
            with open(os.path.join(settings.MEDIA_ROOT, name).encode('utf-8'), 'r+b') as file:
Skia's avatar
Skia committed
111
112
113
114
115
                if file:
                    im = Image.open(BytesIO(file.read()))
                    file.seek(0)
                    im = im.rotate(degree, expand=True)
                    im.save(fp=file, format=self.mime_type.split('/')[-1].upper(), quality=90, optimize=True, progressive=True)
Skia's avatar
Skia committed
116

117
    def get_next(self):
118
119
        if self.is_moderated:
            return self.parent.children.filter(is_moderated=True, asked_for_removal=False, is_folder=False,
Krophil's avatar
Krophil committed
120
                                               id__gt=self.id).order_by('id').first()
121
        else:
Skia's avatar
Skia committed
122
            return Picture.objects.filter(id__gt=self.id, is_moderated=False).order_by('id').first()
123
124

    def get_previous(self):
125
126
        if self.is_moderated:
            return self.parent.children.filter(is_moderated=True, asked_for_removal=False, is_folder=False,
Krophil's avatar
Krophil committed
127
                                               id__lt=self.id).order_by('id').last()
128
        else:
Skia's avatar
Skia committed
129
            return Picture.objects.filter(id__lt=self.id, is_moderated=False).order_by('-id').first()
130

Krophil's avatar
Krophil committed
131

Skia's avatar
Skia committed
132
133
134
135
class Album(SithFile):
    class Meta:
        proxy = True

Skia's avatar
Skia committed
136
137
    objects = SASAlbumManager()

138
139
    @property
    def children_pictures(self):
Skia's avatar
Skia committed
140
        return Picture.objects.filter(parent=self)
141
142
143

    @property
    def children_albums(self):
Skia's avatar
Skia committed
144
        return Album.objects.filter(parent=self)
145

Skia's avatar
Skia committed
146
    def can_be_edited_by(self, user):
147
        # file = SithFile.objects.filter(id=self.id).first()
Krophil's avatar
Krophil committed
148
        return user.is_in_group(settings.SITH_GROUP_SAS_ADMIN_ID)  # or user.can_edit(file)
Skia's avatar
Skia committed
149
150

    def can_be_viewed_by(self, user):
151
        # file = SithFile.objects.filter(id=self.id).first()
Skia's avatar
Skia committed
152
        return self.can_be_edited_by(user) or (self.is_in_sas and self.is_moderated and
Krophil's avatar
Krophil committed
153
                                               user.was_subscribed)  # or user.can_view(file)
Skia's avatar
Skia committed
154
155
156
157

    def get_absolute_url(self):
        return reverse('sas:album', kwargs={'album_id': self.id})

Skia's avatar
Skia committed
158
    def get_download_url(self):
Skia's avatar
Skia committed
159
        return reverse('sas:album_preview', kwargs={'album_id': self.id})
Skia's avatar
Skia committed
160

Skia's avatar
Skia committed
161
162
163
164
165
166
167
168
    def generate_thumbnail(self):
        p = self.children_pictures.order_by('?').first() or self.children_albums.exclude(file=None).exclude(file="").order_by('?').first()
        if p and p.file:
            im = Image.open(BytesIO(p.file.read()))
            self.file = resize_image(im, 200, "jpeg")
            self.file.name = self.name + '/thumb.jpg'
            self.save()

Sli's avatar
Sli committed
169

170
171
172
173
174
175
def sas_notification_callback(notif):
    count = Picture.objects.filter(is_moderated=False).count()
    if count:
        notif.viewed = False
    else:
        notif.viewed = True
Skia's avatar
Skia committed
176
177
    notif.param = "%s" % count
    notif.date = timezone.now()
Krophil's avatar
Krophil committed
178

Sli's avatar
Sli committed
179

180
181
182
183
184
185
186
187
188
189
class PeoplePictureRelation(models.Model):
    """
    The PeoplePictureRelation class makes the connection between User and Picture

    """
    user = models.ForeignKey(User, verbose_name=_('user'), related_name="pictures", null=False, blank=False)
    picture = models.ForeignKey(Picture, verbose_name=_('picture'), related_name="people", null=False, blank=False)

    class Meta:
        unique_together = ['user', 'picture']
Skia's avatar
Skia committed
190
191
192

    def __str__(self):
        return self.user.get_display_name() + " - " + str(self.picture)