-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathflask_jsglue.py
62 lines (52 loc) · 1.76 KB
/
flask_jsglue.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
from flask import render_template
from flask import make_response
from flask import url_for
from jinja2 import Markup
import re
import json
JSGLUE_JS_PATH = '/jsglue.js'
JSGLUE_NAMESPACE = 'Flask'
rule_parser = re.compile(r'<(.+?)>')
splitter = re.compile(r'<.+?>')
def get_routes(app):
output = []
for r in app.url_map.iter_rules():
endpoint = r.endpoint
if app.config['APPLICATION_ROOT'] == '/' or\
not app.config['APPLICATION_ROOT']:
rule = r.rule
else:
rule = '{root}{rule}'.format(
root=app.config['APPLICATION_ROOT'],
rule=r.rule
)
rule_args = [x.split(':')[-1] for x in rule_parser.findall(rule)]
rule_tr = splitter.split(rule)
output.append((endpoint, rule_tr, rule_args))
return sorted(output, key=lambda x: len(x[1]), reverse=True)
class JSGlue(object):
def __init__(self, app=None, **kwargs):
self.app = app
if app is not None:
self.init_app(app)
def init_app(self, app):
self.app = app
@app.route(JSGLUE_JS_PATH)
def serve_js():
return make_response(
(self.generate_js(), 200, {'Content-Type': 'text/javascript'})
)
@app.context_processor
def context_processor():
return {'JSGlue': JSGlue}
def generate_js(self):
rules = get_routes(self.app)
# .js files are not autoescaped in flask
return render_template(
'jsglue/js_bridge.js',
namespace=JSGLUE_NAMESPACE,
rules=json.dumps(rules))
@staticmethod
def include():
js_path = url_for('serve_js')
return Markup('<script src="%s" type="text/javascript"></script>') % (js_path,)