Completed
Push — master ( 84e615...a5de1a )
by Johannes
01:08
created

custom_render_variations()   B

Complexity

Conditions 6

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 21
rs 7.8867
cc 6
1
from io import BytesIO
2
3
from django.core.files.base import ContentFile
4
from django.core.files.storage import FileSystemStorage
5
from django.db import models
6
from django.db.models.signals import post_delete, pre_save
7
from PIL import Image
8
9
from stdimage import StdImageField
10
from stdimage.models import StdImageFieldFile
11
from stdimage.utils import (UploadTo, UploadToAutoSlugClassNameDir,
12
                            UploadToUUID, pre_delete_delete_callback,
13
                            pre_save_delete_callback, render_variations)
14
from stdimage.validators import MaxSizeValidator, MinSizeValidator
15
16
17
class SimpleModel(models.Model):
18
    """works as ImageField"""
19
    image = StdImageField(upload_to='img/')
20
21
22
class AdminDeleteModel(models.Model):
23
    """can be deleted through admin"""
24
    image = StdImageField(
25
        upload_to=UploadTo(name='image', path='img'),
26
        blank=True
27
    )
28
29
30
class ResizeModel(models.Model):
31
    """resizes image to maximum size to fit a 640x480 area"""
32
    image = StdImageField(
33
        upload_to=UploadTo(name='image', path='img'),
34
        variations={
35
            'medium': {'width': 400, 'height': 400},
36
            'thumbnail': (100, 75),
37
        }
38
    )
39
40
41
class ResizeCropModel(models.Model):
42
    """resizes image to 640x480 cropping if necessary"""
43
    image = StdImageField(
44
        upload_to=UploadTo(name='image', path='img'),
45
        variations={'thumbnail': (150, 150, True)}
46
    )
47
48
49
class ThumbnailModel(models.Model):
50
    """creates a thumbnail resized to maximum size to fit a 100x75 area"""
51
    image = StdImageField(
52
        upload_to=UploadTo(name='image', path='img'),
53
        blank=True,
54
        variations={'thumbnail': (100, 75)}
55
    )
56
57
58
class MaxSizeModel(models.Model):
59
    image = StdImageField(
60
        upload_to=UploadTo(name='image', path='img'),
61
        validators=[MaxSizeValidator(16, 16)]
62
    )
63
64
65
class MinSizeModel(models.Model):
66
    image = StdImageField(
67
        upload_to=UploadTo(name='image', path='img'),
68
        validators=[MinSizeValidator(200, 200)]
69
    )
70
71
72
class ForceMinSizeModel(models.Model):
73
    """creates a thumbnail resized to maximum size to fit a 100x75 area"""
74
    image = StdImageField(
75
        upload_to=UploadTo(name='image', path='img'),
76
        force_min_size=True,
77
        variations={'thumbnail': (600, 600)}
78
    )
79
80
81
class AutoSlugClassNameDirModel(models.Model):
82
    name = models.CharField(max_length=50)
83
    image = StdImageField(
84
        upload_to=UploadToAutoSlugClassNameDir(populate_from='name')
85
    )
86
87
88
class UUIDModel(models.Model):
89
    image = StdImageField(upload_to=UploadToUUID(path='img'))
90
91
92
class CustomManager(models.Manager):
93
    """Just like Django's default, but a different class."""
94
    pass
95
96
97
class CustomManagerModel(models.Model):
98
    customer_manager = CustomManager()
99
100
    class Meta:
101
        abstract = True
102
103
104
class ManualVariationsModel(CustomManagerModel):
105
    """delays creation of 150x150 thumbnails until it is called manually"""
106
    image = StdImageField(
107
        upload_to=UploadTo(name='image', path='img'),
108
        variations={'thumbnail': (150, 150, True)},
109
        render_variations=False
110
    )
111
112
113
class MyStorageModel(CustomManagerModel):
114
    """delays creation of 150x150 thumbnails until it is called manually"""
115
    image = StdImageField(
116
        upload_to=UploadTo(name='image', path='img'),
117
        variations={'thumbnail': (150, 150, True)},
118
        storage=FileSystemStorage(),
119
    )
120
121
122
def render_job(**kwargs):
123
    render_variations(**kwargs)
124
    return False
125
126
127
class UtilVariationsModel(models.Model):
128
    """delays creation of 150x150 thumbnails until it is called manually"""
129
    image = StdImageField(
130
        upload_to=UploadTo(name='image', path='img'),
131
        variations={'thumbnail': (150, 150, True)},
132
        render_variations=render_job
133
    )
134
135
136
class ThumbnailWithoutDirectoryModel(models.Model):
137
    """Save into a generated filename that does not contain any '/' char"""
138
    image = StdImageField(
139
        upload_to=lambda instance, filename: 'custom.gif',
140
        variations={'thumbnail': {'width': 150, 'height': 150}},
141
    )
142
143
144
def custom_render_variations(file_name, variations, storage, replace=False):
145
    """Resize image to 100x100."""
146
    for _, variation in variations.items():
147
        variation_name = StdImageFieldFile.get_variation_name(
148
            file_name,
149
            variation['name']
150
        )
151
        if storage.exists(variation_name):
152
            storage.delete(variation_name)
153
154
        with storage.open(file_name) as f:
155
            with Image.open(f) as img:
156
                size = 100, 100
157
                img = img.resize(size)
158
159
                with BytesIO() as file_buffer:
160
                    img.save(file_buffer, 'JPEG')
161
                    f = ContentFile(file_buffer.getvalue())
162
                    storage.save(variation_name, f)
163
164
    return False
165
166
167
class CustomRenderVariationsModel(models.Model):
168
    """Use custom render_variations."""
169
170
    image = StdImageField(
171
        upload_to=UploadTo(name='image', path='img'),
172
        variations={'thumbnail': (150, 150)},
173
        render_variations=custom_render_variations,
174
    )
175
176
177
post_delete.connect(pre_delete_delete_callback, sender=SimpleModel)
178
pre_save.connect(pre_save_delete_callback, sender=AdminDeleteModel)
179