2865
by ame (Tiny)
[REF] separating base API to openobject |
1 |
from itertools import izip, islice |
2 |
from inspect import getargspec |
|
3 |
||
3330
by Xavier Morel
[IMP] tentative pretty major reorganization of the validators import in order to try and avoid systemic import failures due to a bunch of undebuggable errors related to Python getting lost in the crap. |
4 |
import cherrypy |
5 |
from formencode.api import Invalid |
|
2865
by ame (Tiny)
[REF] separating base API to openobject |
6 |
|
2874
by ame (Tiny)
[REF] namespace fix |
7 |
from _utils import decorated |
8 |
||
2865
by ame (Tiny)
[REF] separating base API to openobject |
9 |
|
10 |
__all__ = ["validate", "error_handler", "exception_handler"] |
|
11 |
||
12 |
||
13 |
def to_kw(func, args, kw): |
|
14 |
||
15 |
argnames, defaults = getargspec(func)[::3] |
|
16 |
defaults = defaults or [] |
|
17 |
||
18 |
kv = zip(islice(argnames, 0, len(argnames) - len(defaults)), args) |
|
19 |
kw.update(kv) |
|
20 |
||
21 |
return args[len(argnames)-len(defaults):], kw |
|
22 |
||
23 |
def from_kw(func, args, kw): |
|
24 |
||
25 |
argnames, defaults = getargspec(func)[::3] |
|
26 |
defaults = defaults or [] |
|
27 |
||
28 |
newargs = [kw.pop(name) for name in islice(argnames, 0, len(argnames) - len(defaults)) if name in kw] |
|
29 |
newargs.extend(args) |
|
30 |
||
31 |
return newargs, kw |
|
32 |
||
33 |
||
34 |
def validate(form=None, validators=None): |
|
35 |
||
36 |
def validate_wrapper(func): |
|
37 |
||
38 |
if callable(form) and not hasattr(form, "validate"): |
|
39 |
init_form = lambda self: form(self) |
|
40 |
else: |
|
41 |
init_form = lambda self: form |
|
42 |
||
43 |
def func_wrapper(*args, **kw): |
|
44 |
||
45 |
# do not validate a second time if already validated
|
|
46 |
if hasattr(cherrypy.request, 'validation_state'): |
|
47 |
return func(*args, **kw) |
|
48 |
||
49 |
form = init_form(args and args[0] or kw["self"]) |
|
50 |
args, kw = to_kw(func, args, kw) |
|
51 |
||
52 |
errors = {} |
|
53 |
||
54 |
if form: |
|
55 |
value = kw.copy() |
|
56 |
value.pop('self', None) |
|
57 |
try: |
|
58 |
kw.update(form.validate(value, None)) |
|
59 |
except Invalid, e: |
|
60 |
errors = e.unpack_errors() |
|
61 |
cherrypy.request.validation_exception = e |
|
62 |
cherrypy.request.validation_value = value |
|
63 |
cherrypy.request.validated_form = form |
|
64 |
||
65 |
if validators: |
|
66 |
||
67 |
if isinstance(validators, dict): |
|
68 |
for field, validator in validators.iteritems(): |
|
69 |
try: |
|
70 |
kw[field] = validator.to_python( |
|
71 |
kw.get(field, None), None) |
|
72 |
except Invalid, error: |
|
73 |
errors[field] = error |
|
74 |
else: |
|
75 |
try: |
|
76 |
value = kw.copy() |
|
77 |
kw.update(validators.to_python(value, None)) |
|
78 |
except Invalid, e: |
|
79 |
errors = e.unpack_errors() |
|
80 |
cherrypy.request.validation_exception = e |
|
81 |
cherrypy.request.validation_value = value |
|
82 |
||
83 |
cherrypy.request.validation_errors = errors |
|
84 |
cherrypy.request.input_values = kw.copy() |
|
85 |
cherrypy.request.validation_state = True |
|
86 |
||
87 |
args, kw = from_kw(func, args, kw) |
|
88 |
return func(*args, **kw) |
|
89 |
||
2874
by ame (Tiny)
[REF] namespace fix |
90 |
return decorated(func_wrapper, func) |
2865
by ame (Tiny)
[REF] separating base API to openobject |
91 |
|
92 |
return validate_wrapper |
|
93 |
||
94 |
def error_handler(handler): |
|
95 |
||
96 |
def wrapper(func): |
|
97 |
||
98 |
def func_wrapper(*args, **kw): |
|
99 |
||
100 |
tg_errors = getattr(cherrypy.request, 'validation_errors', None) |
|
101 |
if tg_errors: |
|
102 |
kw['tg_errors'] = tg_errors |
|
103 |
return handler(*args, **kw) |
|
104 |
||
105 |
return func(*args, **kw) |
|
106 |
||
2874
by ame (Tiny)
[REF] namespace fix |
107 |
return decorated(func_wrapper, func) |
2865
by ame (Tiny)
[REF] separating base API to openobject |
108 |
|
109 |
return wrapper |
|
110 |
||
111 |
def exception_handler(*args, **kw): |
|
112 |
return lambda f: f |