Completed
Pull Request — master (#394)
by Jace
08:10
created

_secure()   A

Complexity

Conditions 3

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 3.576

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 3
c 3
b 0
f 0
dl 0
loc 6
rs 9.4285
ccs 3
cts 5
cp 0.6
crap 3.576
1 1
import logging
2 1
from urllib.parse import unquote
3
4 1
import requests
5 1
from flask import (Response, url_for, render_template, send_file,
0 ignored issues
show
Configuration introduced by
The import flask could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
6
                   current_app, request)
7
8
9 1
log = logging.getLogger(__name__)
10
11
12 1
def route(*args, **kwargs):
13
    """Unquoted version of Flask's `url_for`."""
14 1
    for key, value in sorted(kwargs.items()):
15 1
        if value is True:
16 1
            kwargs[key] = 'true'
17
18 1
    return _secure(unquote(url_for(*args, **kwargs)))
19
20
21 1
def display(title, path, share=False, raw=False, mimetype='image/jpeg'):
22
    """Render a webpage or raw image based on request."""
23 1
    img = _format_url(request, 'share')
24 1
    img_twitter = _format_url(
25
        request, 'share',
26
        width=current_app.config['TWITTER_IMAGE_WIDTH'],
27
        height=current_app.config['TWITTER_IMAGE_HEIGHT'],
28
    )
29 1
    img_facebook = _format_url(
30
        request, 'share',
31
        width=current_app.config['FACEBOOK_IMAGE_WIDTH'],
32
        height=current_app.config['FACEBOOK_IMAGE_HEIGHT'],
33
    )
34 1
    url = _format_url(request, 'width', 'height')
35
36 1
    if share:
37 1
        log.info("Sharing image on page: %s", img)
38
39 1
        html = render_template(
40
            'share.html',
41
            title=title,
42
            img=_secure(img),
43
            img_twitter=_secure(img_twitter),
44
            img_facebook=_secure(img_facebook),
45
            url=_secure(url),
46
            config=current_app.config,
47
        )
48 1
        return html if raw else _nocache(Response(html))
49
50
    else:
51 1
        log.info("Sending image: %s", path)
52 1
        return send_file(path, mimetype=mimetype)
53
54
55 1
def track(title):
56
    """Log the requested content, server-side."""
57 1
    google_url = current_app.config['GOOGLE_ANALYTICS_URL']
58 1
    google_tid = current_app.config['GOOGLE_ANALYTICS_TID']
59 1
    google_data = dict(
60
        v=1,
61
        tid=google_tid,
62
        cid=request.remote_addr,
63
64
        t='pageview',
65
        dh='memegen.link',
66
        dp=request.full_path,
67
        dt=str(title),
68
69
        uip=request.remote_addr,
70
        ua=request.user_agent.string,
71
    )
72 1
    if google_tid != 'localhost':
73
        response = requests.post(google_url, data=google_data)
74
        params = _format_query(google_data, as_string=True)
75
        log.debug("Tracking POST: %s %s", response.url, params)
76
77 1
    remote_url = current_app.config['REMOTE_TRACKING_URL']
78 1
    remote_data = dict(
79
        text=str(title),
80
        source='memegen.link',
81
        context=unquote(request.url),
82
    )
83 1
    if remote_url:
84
        response = requests.get(remote_url, params=remote_data)
85
        log.debug("Tracking GET: %s", response.url)
86
87
88 1
def _secure(url):
89
    """Ensure HTTPS is used in production."""
90 1
    if current_app.config['ENV'] == 'prod':
91
        if url.startswith('http:'):
92
            url = url.replace('http:', 'https:', 1)
93 1
    return url
94
95
96 1
def _format_url(req, *skip, **add):
97
    """Get a formatted URL with sanitized query parameters."""
98 1
    base = req.base_url
99
100 1
    options = {k: v[0] for k, v in dict(req.args).items() if k not in skip}
101 1
    options.update(add)
102
103 1
    params = _format_query(options)
104
105 1
    if params:
106 1
        return base + "?{}".format("&".join(params))
107
    else:
108 1
        return base
109
110
111 1
def _format_query(options, *, as_string=False):
112 1
    pattern = "{}={!r}" if as_string else "{}={}"
113 1
    pairs = sorted(pattern.format(k, v) for k, v in options.items())
114 1
    if as_string:
115
        return ' '.join(pairs)
116 1
    return pairs
117
118
119 1
def _nocache(response):
120
    """Ensure a response is not cached."""
121
    response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
122
    response.headers['Pragma'] = 'no-cache'
123
    response.headers['Expires'] = '0'
124
    return response
125