This repository has been archived by the owner on Jul 1, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 14
/
redirects.py
104 lines (80 loc) · 2.98 KB
/
redirects.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# Core
import os
import re
# External
import flask
import yaml
import yamlordereddictloader
class YamlRegexMap:
def __init__(self, filepath):
"""
Given the path to a YAML file of RegEx mappings like:
hello/(?P<person>.*)?: "/say-hello?name={person}"
google/(?P<search>.*)?: "https://google.com/?q={search}"
Return a list of compiled Regex matches and destination strings:
[
(<regex>, "/say-hello?name={person}"),
(<regex>, "https://google.com/?q={search}"),
]
"""
self.matches = []
if os.path.isfile(filepath):
with open(filepath) as redirects_file:
lines = yaml.load(
redirects_file, Loader=yamlordereddictloader.Loader
)
if lines:
for url_match, target_url in lines.items():
if url_match[0] != "/":
url_match = "/" + url_match
self.matches.append(
(re.compile(url_match), target_url)
)
def get_target(self, url_path):
for (match, target) in self.matches:
result = match.fullmatch(url_path)
if result:
parts = {}
for name, value in result.groupdict().items():
parts[name] = value or ""
target_url = target.format(**parts)
if flask.request.query_string:
target_url += "?" + flask.request.query_string.decode(
"utf-8"
)
return target_url
def prepare_redirects(
permanent_redirects_path="permanent-redirects.yaml",
redirects_path="redirects.yaml",
):
"""
Create a regex map from the provided yaml files,
and return a view function "apply_redirects" which encloses
the maps to apply redirect where relevant.
Usage:
import flask
from redirects import prepare_redirects
app = flask.Flask(__name__)
apply_redirects = prepare_redirects(
permanent_redirects_path='permanent-redirects.yaml',
redirects_path='redirects.yaml'
)
app.before_request(apply_redirects)
"""
permanent_redirect_map = YamlRegexMap(permanent_redirects_path)
redirect_map = YamlRegexMap(redirects_path)
def apply_redirects():
"""
Process the two mappings defined above
of permanent and temporary redirects to target URLs,
to send the appropriate redirect responses
"""
permanent_redirect_url = permanent_redirect_map.get_target(
flask.request.path
)
if permanent_redirect_url:
return flask.redirect(permanent_redirect_url, code=301)
redirect_url = redirect_map.get_target(flask.request.path)
if redirect_url:
return flask.redirect(redirect_url)
return apply_redirects