~openerp-dev/openobject-client-web/6.0-opw-598313-msh

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