GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 8b35b9...c5c1a6 )
by Dmitry
01:05
created

ThumbnailFilter.apply()   B

Complexity

Conditions 3

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 3
dl 0
loc 26
rs 8.8571
1
"""
2
This module implement a Thumbnail filter.
3
"""
4
from PIL import Image
5
from .interface import ImagineFilterInterface
6
7
8
class ThumbnailFilter(ImagineFilterInterface):
9
    """
10
    Thumbnail filter
11
    """
12
    modes = ['inset', 'outbound']
13
    mode = 'inset'
14
    width = 0
15
    height = 0
16
17
    def __init__(self, **kwargs):
18
        """
19
        Filter initialization
20
        :param kwargs: parameters
21
        """
22
        if 'mode' in kwargs and kwargs['mode'] in self.modes:
23
            self.mode = kwargs.pop('mode')
24
25
        if 'size' in kwargs and isinstance(kwargs['size'], list) and len(kwargs['size']) == 2:
26
            size = kwargs.pop('size', [0, 0])
27
            self.width = size[0]
28
            self.height = size[1]
29
        else:
30
            raise ValueError('Thumbnail size is not set.')
31
32
    def apply(self, resource):
33
        """
34
        Apply filter to resource
35
        :param resource: Image
36
        :return: Image
37
        """
38
        if not isinstance(resource, Image.Image):
39
            raise ValueError('Unknown resource format')
40
41
        original_width, original_height = resource.size
42
43
        resource_format = resource.format
44
45
        if self.mode == 'outbound':
46
            target_width, target_height = self.outbound_sizes(original_width, original_height, self.width, self.height)
47
            resource = resource.resize((target_width, target_height), Image.ANTIALIAS)
48
49
            crop_sizes = self.crop_sizes(target_width, target_height, self.width, self.height)
50
            resource = resource.crop(crop_sizes)
51
        else:
52
            target_width, target_height = self.inset_sizes(original_width, original_height, self.width, self.height)
53
            resource = resource.resize((target_width, target_height), Image.ANTIALIAS)
54
55
        resource.format = resource_format
56
57
        return resource
58
59
    @classmethod
60
    def inset_sizes(cls, original_width, original_height, target_width, target_height):
61
        """
62
        Calculate new image sizes for inset mode
63
        :param original_width: int
64
        :param original_height: int
65
        :param target_width: int
66
        :param target_height: int
67
        :return: tuple(int, int)
68
        """
69
        if target_width >= original_width and target_height >= original_height:
70
            target_width = float(original_width)
71
            target_height = original_height
72
73
        elif target_width <= original_width and target_height >= original_height:
74
            k = original_width / float(target_width)
75
            target_height = int(original_height / k)
76
77
        elif target_width >= original_width and target_height <= original_height:
78
            k = original_height / float(target_height)
79
            target_width = int(original_width / k)
80
81
        elif target_width < original_width and target_height < original_height:
82
            k = original_width / float(original_height)
83
            k_w = original_width / float(target_width)
84
            k_h = original_height / float(target_height)
85
86
            if k_w >= k_h:
87
                target_height = int(target_width / k)
88
            else:
89
                target_width = int(target_height * k)
90
91
        return target_width, target_height
92
93
    @classmethod
94
    def outbound_sizes(cls, original_width, original_height, target_width, target_height):
95
        """
96
        Calculate new image sizes for outbound mode
97
        :param original_width: int
98
        :param original_height: int
99
        :param target_width: int
100
        :param target_height: int
101
        :return: tuple(int, int)
102
        """
103
        if target_width <= original_width and target_height <= original_height:
104
            k = original_width / float(original_height)
105
            k_w = original_width / float(target_width)
106
            k_h = original_height / float(target_height)
107
108
            if k_w > k_h:
109
                target_width = int(target_height * k)
110
            else:
111
                target_height = int(target_width / k)
112
        else:
113
            target_width = original_width
114
            target_height = original_height
115
116
        return target_width, target_height
117
118
    @classmethod
119
    def crop_sizes(cls, original_width, original_height, target_width, target_height):
120
        """
121
        Calculate crop parameters for outbound mode
122
        :param original_width: int
123
        :param original_height: int
124
        :param target_width: int
125
        :param target_height: int
126
        :return: tuple(int, int, int, int)
127
        """
128
        if target_width < original_width:
129
            left = abs(original_width - target_width) / 2
130
            right = left + target_width
131
        else:
132
            left = 0
133
            right = original_width
134
        if target_height < original_height:
135
            upper = abs(original_height - target_height) / 2
136
            lower = upper + target_height
137
        else:
138
            upper = 0
139
            lower = original_height
140
141
        return left, upper, right, lower
142