-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathobjectpub.py
53 lines (44 loc) · 1.71 KB
/
objectpub.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
from paste.request import parse_formvars
class ObjectPublisher(object):
def __init__(self, root):
self.root = root
def __call__(self, environ, start_response):
fields = parse_formvars(environ)
obj = self.find_object(self.root, environ)
response_body = "as per usual"
if obj:
try:
response_body = obj(**fields.mixed())
start_response('200 OK', [('content-type', 'text/html')])
except:
start_response('400 Bad Request', [('content-type', 'text/html')])
else:
start_response('400 Bad Request', [('content-type', 'text/html')])
return response_body
def find_object(self, obj, environ):
path_info = environ.get('PATH_INFO', '')
if not path_info or path_info == '/':
# We've arrived!
return obj
# PATH_INFO always starts with a /, so we'll get rid of it:
path_info = path_info.lstrip('/')
# Then split the path into the "next" chunk, and everything after it
# ("rest"):
parts = path_info.split('/', 1)
next = parts[0]
if len(parts) == 1:
rest = ''
else:
rest = '/' + parts[1]
# Hide private methods/attributes:
assert not next.startswith('_')
# Now we get the attribute; getattr(a, 'b') is equivalent to a.b...
try:
next_obj = getattr(obj, next)
except:
return None
# Now fix up SCRIPT_NAME and PATH_INFO...
environ['SCRIPT_NAME'] += '/' + next
environ['PATH_INFO'] = rest
# and now parse the remaining part of the URL...
return self.find_object(next_obj, environ)