-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
176 lines (146 loc) · 5.01 KB
/
main.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/usr/bin/env python
# webAppWorkshop for Google App Engine.
# Copyright 2011 Sabren Enterprises, Inc. All Rights Reserved.
"""
This is the main dispatcher for http://*.webappworkshop.com/
"""
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from Cookie import SimpleCookie
import os, sys, logging
sys.path.extend([os.path.join(os.path.dirname(__file__), path)
for path in ['lib','sub/workshop']])
import weblib, handy
import ERR, REST, CRUD
class AppEngineEngine(weblib.Engine):
"""
This strips a bunch of CGI-specific junk out of weblib,
so we can use it on App Engine.
"""
# TODO clean Engine up to be fully wsgi-compliant so we don't need this!
def _exec(self, script):
if script:
script(self.request, self.response)
else:
self.response.addHeader("status", "404 Not Found")
self.response.write(handy.trim(
"""
<!doctype html>
<html>
<head>
<title>404 Not Found</title>
</head>
<body>
<h1>404 Not Found</h1>
<p>There is no app at <strong>%s</strong>.</p>
</body>
<html>
""") % self.request.host)
def setPathInfo(self):
self.request.pathInfo = self.request.path
def chdir(self):
pass
def runDotWeblibPy(self):
pass
def weblib_app(environ, start_response):
import pprint
pprint.pprint(environ)
req = weblib.Request(
method = environ["REQUEST_METHOD"],
host = environ["SERVER_NAME"],
path = environ["SCRIPT_NAME"] + environ["PATH_INFO"],
query = weblib.RequestData(environ["QUERY_STRING"]),
form = None,
cookie = SimpleCookie(environ.get("HTTP_COOKIE", "")),
content = environ["wsgi.input"].read(
int(environ.get("CONTENT_LENGTH", 0) or 0)),
remoteAddress = environ["REMOTE_ADDR"],
)
req.ob = webapp.Request(environ)
urls = getAppURLs(req.host)
main = getAppMain(urls, req)
eng = AppEngineEngine(script=main, request=req)
eng.run()
response = eng.response
out = weblib.OutputDecorator(eng)
status = "500 Internal Server Error" if eng.hadProblem() else "200 OK"
headers = [("Content-Type", response.contentType)]
for k,v in response.headers:
if k.lower() == "status":
status = v
else:
headers.append((k,v))
start_response(status, headers)
yield out.getBody()
def getAppURLs(serverName):
"""
:: Str -> []
Given a domain like foo.webappworkshop.com,
this builds a map of the urls.
:param serverName: the SERVER_NAME from wsgi
:return: the imported root module, or None
"""
universal_api = REST.urlMap(
[
(r"/api/g/?$",
{
REST.get: CRUD.list_grids,
REST.post: CRUD.create_grid
}),
(r"/api/g/(?P<table>\w+)/?$",
{
REST.get: CRUD.get_grid_meta,
#put: CRUD.put_grid_meta,
REST.post: CRUD.create_grid_row,
#delete: CRUD.delete_grid
}),
(r"/api/g/(?P<table>\w+)/data/?$",
{
REST.get: CRUD.get_grid_data
}),
(r"/api/g/(?P<table>\w+)/(?P<id>\d+)/?$",
{
REST.get: CRUD.get_grid_row,
REST.put: CRUD.put_grid_row,
REST.delete: CRUD.delete_grid_row
}),
])
if serverName.startswith("localhost"):
res = []
else:
res = universal_api
cut = -1 if serverName.endswith("localhost") else -2
appName = '.'.join(serverName.split('.')[:cut])
logging.debug("appName is %r" % appName)
if os.path.exists("app/%s/%s.py" % (appName, appName)):
modname = 'app.%s.%s' % (appName, appName)
exec 'import %s' % modname
extras = getattr(eval(modname), 'urls', [])
res.extend(extras)
else:
logging.debug("%s is not a valid app" % serverName)
return res
def getAppMain(urlMap, req):
"""
:type urlMap: list of regexp->dict pairs
:type req: weblib.Request
:return:
"""
assert isinstance(req, weblib.Request)
for path, handlers in urlMap:
match = path.match(req.path)
if match:
if handlers.has_key(req.method):
req.pathArgs = match.groupdict()
method = handlers[req.method]
else:
method = ERR.err405MethodNotSupported
break
else:
method = ERR.err404NotFound
logging.info("method is: %s", method.__name__)
return method
if __name__ == '__main__':
if os.environ["SERVER_NAME"].endswith("localhost"):
logging.getLogger().setLevel(logging.DEBUG)
util.run_wsgi_app(weblib_app)