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 ( 9f3e8d...05150b )
by Dmitry
01:01
created

Imagine.handle_request()   B

Complexity

Conditions 6

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 32
rs 7.5384
cc 6
1
"""
2
Flask Imagine extension.
3
"""
4
import logging
5
6
from flask import current_app, abort, redirect
7
8
from .adapters import ImagineFilesystemAdapter
9
from .filters import AutorotateFilter, ThumbnailFilter
10
from .filters.interface import ImagineFilterInterface
11
from .helpers.regex_route import RegexConverter
12
13
__all__ = ['Imagine', 'imagine_filter']
14
15
LOGGER = logging.getLogger(__file__)
16
17
18
class Imagine(object):
19
    """
20
    Flask Imagine extension
21
    """
22
    filter_sets = {}
23
    adapter = None
24
25
    def __init__(self, app=None):
26
        """
27
        :param app: Flask application
28
        :return:
29
        """
30
        if app is not None:
31
            self.init_app(app)
32
33
    def init_app(self, app):
34
        """
35
        :param app: Flask application
36
        :return:
37
        """
38
        if not hasattr(app, 'extensions'):
39
            app.extensions = {}
40
        app.extensions['imagine'] = self
41
42
        self._set_defaults(app)
43
44
        self._handle_adapter(app)
45
        self._handle_filter_sets(app)
46
47
        self._add_url_rule(app)
48
        self._add_template_filter(app)
49
50
    @classmethod
51
    def _set_defaults(cls, app):
52
        """
53
        Set default configuration parameters
54
        :param app: Flask application
55
        :return:
56
        """
57
        app.config.setdefault('IMAGINE_URL', '/media/cache/resolve')
58
        app.config.setdefault('IMAGINE_NAME', 'imagine')
59
        app.config.setdefault('IMAGINE_THUMBS_PATH', 'cache/')
60
        app.config.setdefault('IMAGINE_CACHE_ENABLED', True)
61
62
        app.config.setdefault('IMAGINE_ADAPTERS', {
63
            'fs': ImagineFilesystemAdapter,
64
        })
65
        app.config.setdefault('IMAGINE_FILTERS', {
66
            'autorotate': AutorotateFilter,
67
            'thumbnail': ThumbnailFilter
68
        })
69
70
        app.config.setdefault('IMAGINE_ADAPTER', {
71
            'name': 'fs',
72
            'source_folder': '/static/',
73
            'cache_folder': '/cache/'
74
        })
75
76
        app.config.setdefault('IMAGINE_FILTER_SETS', {})
77
78
        return app
79
80
    def _handle_adapter(self, app):
81
        """
82
        Handle storage adapter configuration
83
        :param app: Flask application
84
        :return:
85
        """
86
        if 'IMAGINE_ADAPTER' in app.config \
87
                and 'name' in app.config['IMAGINE_ADAPTER'] \
88
                and app.config['IMAGINE_ADAPTER']['name'] in app.config['IMAGINE_ADAPTERS'].keys():
89
            self.adapter = app.config['IMAGINE_ADAPTERS'][app.config['IMAGINE_ADAPTER']['name']](
90
                **app.config['IMAGINE_ADAPTER']
91
            )
92
        else:
93
            raise ValueError('Unknown adapter type')
94
95
    def _handle_filter_sets(self, app):
96
        """
97
        Handle filter sets
98
        :param app: Flask application
99
        :return:
100
        """
101
        if 'IMAGINE_FILTER_SETS' in app.config and isinstance(app.config['IMAGINE_FILTER_SETS'], dict):
102
            for filter_name, filters_settings in app.config['IMAGINE_FILTER_SETS'].iteritems():
103
                filter_set = []
104
                if isinstance(filters_settings, dict) and 'filters' in filters_settings:
105
                    for filter_type, filter_settings in filters_settings['filters'].iteritems():
106
                        if filter_type in app.config['IMAGINE_FILTERS']:
107
                            filter_item = app.config['IMAGINE_FILTERS'][filter_type](**filter_settings)
108
                            if isinstance(filter_item, ImagineFilterInterface):
109
                                filter_set.append(filter_item)
110
                            else:
111
                                raise ValueError('Filter must be implement ImagineFilterInterface')
112
                        else:
113
                            raise ValueError('Unknown filter type: %s' % filter_type)
114
115
                    filter_config = {'filters': filter_set}
116
                    if 'cached' in filters_settings and filters_settings['cached']:
117
                        filter_config['cached'] = True
118
                    else:
119
                        filter_config['cached'] = False
120
121
                    self.filter_sets.update({filter_name: filter_config})
122
                else:
123
                    raise ValueError('Wrong settings for filter: %s' % filter_name)
124
        else:
125
            raise ValueError('Filters configuration does not present')
126
127
    def _add_url_rule(self, app):
128
        """
129
        Add url rule for get filtered images
130
        :param app: Flask application
131
        :return:
132
        """
133
        app.url_map.converters['regex'] = RegexConverter
134
        app.add_url_rule(
135
            app.config['IMAGINE_URL'] + '/<regex("[^\/]+"):filter_name>/<path:path>',
136
            app.config['IMAGINE_NAME'],
137
            self.handle_request
138
        )
139
140
        return app
141
142
    @classmethod
143
    def _add_template_filter(cls, app):
144
        """
145
        Add template filter
146
        :param app: Flask application
147
        :return:
148
        """
149
        if hasattr(app, 'add_template_filter'):
150
            app.add_template_filter(imagine_filter, 'imagine_filter')
151
        else:
152
            ctx = {
153
                'imagine_filter': imagine_filter
154
            }
155
            app.context_processor(lambda: ctx)
156
157
        return app
158
159
    def handle_request(self, filter_name, path):
160
        """
161
        Handle image request
162
        :param filter_name: filter_name
163
        :param path: image_path
164
        :param kwargs:
165
        :return:
166
        """
167
        if filter_name in self.filter_sets:
168
            if self.filter_sets[filter_name]['cached']:
169
                if self.adapter.check_cached_item('%s/%s' % (filter_name, path)):
170
                    return redirect(
171
                        '%s/%s/%s' % (
172
                            self.adapter.source_folder,
173
                            self.adapter.cache_folder,
174
                            '%s/%s' % (filter_name, path)
175
                        )
176
                    )
177
178
            resource = self.adapter.get_item(path)
179
180
            if resource:
181
                for filter_item in self.filter_sets[filter_name]['filters']:
182
                    resource = filter_item.apply(resource)
183
184
                return redirect(self.adapter.create_cached_item('%s/%s' % (filter_name, path), resource))
185
            else:
186
                LOGGER.warning('File "%s" not found.' % path)
187
                abort(404)
188
        else:
189
            LOGGER.warning('Filter "%s" not found.' % filter_name)
190
            abort(404)
191
192
193
def imagine_filter(path, filter_name):
194
    """
195
    Template filter
196
    :param path: image path
197
    :param filter_name: filter_name
198
    :param kwargs:
199
    :return:
200
    """
201
    self = current_app.extensions['imagine']
202
    return self.build_url(path, filter_name)
203