Passed
Push — master ( 19a00d...c2a7ba )
by Jace
01:21
created

get_encoded()   D

Complexity

Conditions 8

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 8.0368

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
c 1
b 0
f 0
dl 0
loc 32
rs 4
ccs 22
cts 24
cp 0.9167
crap 8.0368
1 1
from flask import Blueprint, current_app, request, redirect
2
from webargs import fields, flaskparser
3 1
import log
4 1
5
from .. import domain
6 1
7
from ._cache import Cache
8 1
from ._utils import route, track, display
9 1
10
11
blueprint = Blueprint('image', __name__)
12 1
cache_filtered = Cache()
13 1
cache_unfiltered = Cache(filtered=False)
14 1
15 1
PLACEHOLDER = "https://raw.githubusercontent.com/jacebrowning/memegen/master/memegen/static/images/missing.png"
16
OPTIONS = {
17 1
    'alt': fields.Str(missing=None),
18
    'font': fields.Str(missing=None),
19
    'preview': fields.Bool(missing=False),
20
    'share': fields.Bool(missing=False),
21
    'width': fields.Int(missing=None),
22
    'height': fields.Int(missing=None),
23
    'watermark': fields.Str(missing=None),
24
}
25
26
27
@blueprint.route("/latest.jpg")
28 1
@blueprint.route("/latest<int:index>.jpg")
29 1
@flaskparser.use_kwargs({'filtered': fields.Bool(missing=True)})
30 1
def get_latest(index=1, filtered=True):
31 1
    cache = cache_filtered if filtered else cache_unfiltered
32 1
    kwargs = cache.get(index - 1)
33 1
34
    if kwargs:
35 1
        kwargs['preview'] = True
36 1
    else:
37
        kwargs['key'] = 'custom'
38 1
        kwargs['path'] = "your_meme/goes_here"
39 1
        kwargs['alt'] = PLACEHOLDER
40 1
41
    return redirect(route('.get', _external=True, **kwargs))
42 1
43
44
@blueprint.route("/<key>.jpg")
45 1
@flaskparser.use_kwargs(OPTIONS)
46 1
def get_without_text(key, **options):
47
    options.pop('preview')
48 1
    options.pop('share')
49 1
50
    template = current_app.template_service.find(key)
51 1
    text = domain.Text(template.default_path)
52 1
53
    return redirect(route('.get', key=key, path=text.path, **options))
54 1
55
56
@blueprint.route("/<key>.jpeg")
57 1
def get_without_text_jpeg(key):
58
    return redirect(route('.get_without_text', key=key))
59 1
60
61
@blueprint.route("/<key>/<path:path>.jpg", endpoint='get')
62 1
@flaskparser.use_kwargs(OPTIONS)
63 1
def get_with_text(key, path, alt, font, watermark, preview, share, **size):
64
    assert len(size) == 2
65 1
    options = dict(key=key, path=path,
66
                   alt=alt, font=font, watermark=watermark, **size)
67 1
    if preview:
68 1
        options['preview'] = True
69 1
    if share:
70
        options['share'] = True
71
72 1
    text = domain.Text(path)
73 1
    fontfile = current_app.font_service.find(font)
74
75 1
    template = current_app.template_service.find(key, allow_missing=True)
76 1
    if template.key != key:
77 1
        options['key'] = template.key
78 1
        return redirect(route('.get', **options))
79
80 1
    if path != text.path:
81 1
        options['path'] = text.path
82 1
        return redirect(route('.get', **options))
83
84 1
    if alt and "://" in alt and key != 'custom':
85 1
        options['key'] = 'custom'
86 1
        return redirect(route('.get', **options))
87
88 1
    if alt and template.path == template.get_path(alt, download=False):
89 1
        options.pop('alt')
90 1
        return redirect(route('.get', **options))
91
92 1
    if font and not fontfile:
93 1
        options.pop('font')
94 1
        return redirect(route('.get', **options))
95 1
96
    watermark, valid = _get_watermark(request, watermark)
97 1
    if not valid:
98
        options.pop('watermark')
99
        return redirect(route('.get', **options))
100
101
    image = current_app.image_service.create(
102 1
        template, text,
103 1
        style=PLACEHOLDER if alt == 'none' else alt,
104 1
        font=fontfile, size=size, watermark=watermark,
105 1
    )
106
107 1
    if not preview:
108
        cache_filtered.add(key=key, path=path, alt=alt, font=font)
109
        cache_unfiltered.add(key=key, path=path, alt=alt, font=font)
110 1
        track(image.text)
111
112 1
    return display(image.text, image.path, share=share)
113
114
115 1
@blueprint.route("/<key>/<path:path>.jpeg")
116
def get_with_text_jpeg(key, path):
117
    return redirect(route('.get', key=key, path=path))
118 1
119 1
120 1
@blueprint.route("/_<code>.jpg")
121 1
@flaskparser.use_kwargs(OPTIONS)
122
def get_encoded(code, alt, font, watermark, preview, share, **size):
123 1
    assert len(size) == 2
124
    options = dict(code=code, font=font, watermark=watermark, **size)
125 1
    if share:
126
        options['share'] = True
127
128 1
    if alt or preview:
129 1
        return redirect(route('.get_encoded', **options))
130 1
131 1
    key, path = current_app.link_service.decode(code)
132
    template = current_app.template_service.find(key)
133 1
    text = domain.Text(path)
134 1
    fontfile = current_app.font_service.find(font)
135 1
136 1
    if font and not fontfile:
137 1
        options.pop('font')
138 1
        return redirect(route('.get_encoded', **options))
139
140
    watermark, valid = _get_watermark(request, watermark)
141
    if not valid:
142 1
        options.pop('watermark')
143 1
        return redirect(route('.get_encoded', **options))
144 1
145
    image = current_app.image_service.create(
146 1
        template, text, font=fontfile, size=size, watermark=watermark,
147 1
    )
148 1
149
    track(image.text)
150 1
151 1
    return display(image.text, image.path, share=share)
152 1
153
154
def _get_watermark(_request, watermark):
155
    referrer = _request.environ.get('HTTP_REFERER', "").lower()
156
    agent = _request.environ.get('HTTP_USER_AGENT', "").lower()
157
    log.debug("Referrer: %r, Agent: %r", referrer, agent)
158
159
    if watermark == 'none':
160
        for option in current_app.config['WATERMARK_OPTIONS']:
161
            for identity in (referrer, agent):
162
                if option and identity and option in identity:
163
                    log.debug(f"Watermark disabled ({option} in {identity})")
0 ignored issues
show
introduced by
invalid syntax (<string>, line 163)
Loading history...
164
                    return None, True
165
        log.warning("Request does not support unmarked images")
166
        return None, False
167
168
    if watermark and watermark not in current_app.config['WATERMARK_OPTIONS']:
169
        log.warning("Unsupported custom watermark: %r", watermark)
170
        return watermark, False
171
172
    if watermark:
173
        log.debug("Using custom watermark: %r", watermark)
174
        return watermark, True
175
176
    default = current_app.config['WATERMARK_OPTIONS'][0]
177
    log.debug("Using default watermark: %r", default)
178
    return default, True
179