-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy path__init__.py
More file actions
123 lines (110 loc) · 3.14 KB
/
__init__.py
File metadata and controls
123 lines (110 loc) · 3.14 KB
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from __future__ import absolute_import
import collections
import flask
import json as json_
import lupa
import requests
from runtime import base64
from runtime import json
from runtime import http
from runtime import mail
__all__ = """
base64
json
http
mail
""".split()
try:
lua = lupa.LuaRuntime()
except:
pass # for local debugging without lupa
def _export_globals():
d = dict()
for k in __all__:
d[k] = globals()[k]
return d
def make_table(dict):
return lua.eval("""
function(d)
local t = {}
for key, value in python.iterex(d.items()) do
t[key] = value
end
return t
end
""")(lupa.as_attrgetter(dict))
def run(request, source):
try:
app = lua.eval("""
function(globals)
for k,v in python.iterex(globals.items()) do
_G[k] = v
end
{0}
end
""".format(source))
except Exception, e:
raise e
#return "Bad source", 400
globals = _export_globals()
globals['request'] = adapt_request(request)
globals['require'] = lua.eval("""
function(name)
return loadstring(http.load(name))()
end""")
return adapt_response(
app(lupa.as_attrgetter(globals)))
def adapt_request(request):
""" builds a request object for lua from a flask request """
def _default_table(input, filter=None):
""" converts mapping to lua table """
table = {}
for k,v in input.items():
if filter is None:
table[k] = v
else:
table[k] = filter(v)
return make_table(table)
def _file_adaptor(file):
return make_table(dict(
type=file.content_type,
filename=file.filename,
content=file.stream.read()))
class adapted_request:
form = _default_table(request.form)
query = _default_table(request.args)
querystring = request.query_string
files = _default_table(request.files, _file_adaptor)
body = request.data
method = request.method
remote_addr = request.remote_addr
scheme = request.scheme
port = 443 if request.is_secure else 80
path = request.path
headers = _default_table(request.headers)
return adapted_request.__dict__
def adapt_response(response):
""" builds a flask response from lua return value(s) """
if not isinstance(response, tuple):
response = (response,)
status = 200
headers = {"Content-Type": "text/plain"}
body = ""
body_set = False
def _is_mapping(value):
return isinstance(value, lupa._lupa._LuaTable) or \
isinstance(value, dict)
for value in response:
if isinstance(value, basestring):
body = value
body_set = True
elif isinstance(value, int):
status = value
elif not body_set and _is_mapping(value):
body = json_.dumps(value, cls=json.LuaEncoder)
headers['Content-Type'] = 'application/json'
body_set = True
elif body_set and _is_mapping(value):
for header in value:
headers[header] = value[header]
return flask.make_response(body, status, headers)