~widelands-dev/widelands-website/trunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from django.db import models

from django.template.defaultfilters import slugify
from PIL import Image
from PIL.Image import core as _imaging
from cStringIO import StringIO
from django.core.files.uploadedfile import SimpleUploadedFile, UploadedFile
from django.core.files.storage import FileSystemStorage
import os
from django.conf import settings
from django.urls import reverse


# Taken from django snippet 976

class OverwriteStorage(FileSystemStorage):

    def get_available_name(self, name, max_length=None):
        """Returns a filename that's free on the target storage system, and
        available for new content to be written to."""
        # If the filename already exists, remove it as if it was a true file
        # system
        if self.exists(name):
            os.remove(os.path.join(settings.MEDIA_ROOT, name))
        return name


class Category(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255, unique=True, blank=True)

    class Meta:
        ordering = ['-name']

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)

        return super(Category, self).save(*args, **kwargs)

    def __unicode__(self):
        return u"%s" % self.name


def screenshot_path(instance, filename):
    return 'wlscreens/screens/%s/%s.%s' % (
            instance.category, instance.name, filename.rsplit('.', 1)[-1].lower()
            )


def thumbnail_path(instance, filename):
    return 'wlscreens/thumbs/%s/%s.png' % (
            instance.category, instance.name)


class Screenshot(models.Model):
    name = models.CharField(max_length=255)

    screenshot = models.ImageField(
        upload_to=screenshot_path,
        storage=OverwriteStorage(),
    )
    thumbnail = models.ImageField(
        upload_to=thumbnail_path,
        editable=False,
        storage=OverwriteStorage(),
    )
    comment = models.TextField(
        null=True,
        blank=True
    )
    category = models.ForeignKey(
        Category,
        related_name='screenshots'
    )
    position = models.IntegerField(
        null=True,
        blank=True,
        default=0,
        help_text='The position inside the category',
    )

    class Meta:
        unique_together = ('name', 'category')
        ordering = ['-category__name', 'position']

    def save(self, *args, **kwargs):
        # Open original screenshot which we want to thumbnail using PIL's Image
        # object
        try:
            image = Image.open(self.screenshot)
    
            # Convert to RGB if necessary
            if image.mode not in ('L', 'RGB'):
                image = image.convert('RGB')
    
            image.thumbnail(settings.THUMBNAIL_SIZE, Image.ANTIALIAS)
    
            # Save the thumbnail
            temp_handle = StringIO()
            image.save(temp_handle, 'png')
            temp_handle.seek(0)
    
            # Save to the thumbnail field
            suf = SimpleUploadedFile(os.path.split(self.screenshot.name)[-1],
                                     temp_handle.read(), content_type='image/png')
            self.thumbnail.save(suf.name + '.png', suf, save=False)
    
            # Save this photo instance
            super(Screenshot, self).save(*args, **kwargs)
        except IOError:
            # Likely we have a screenshot in the database which didn't exist
            # on the filesystem at the given path. Ignore it.            
            pass


    def __unicode__(self):
        return u"%s:%s" % (self.category.name, self.name)