18 # import interfaces |
18 # import interfaces |
19 |
19 |
20 # import packages |
20 # import packages |
21 from pyams_utils.request import check_request, get_request_data, set_request_data |
21 from pyams_utils.request import check_request, get_request_data, set_request_data |
22 from pyams_utils.session import get_session_data, set_session_data |
22 from pyams_utils.session import get_session_data, set_session_data |
|
23 from zope.schema.fieldproperty import FieldProperty |
|
24 |
|
25 |
|
26 class DocFieldProperty(FieldProperty): |
|
27 """Field property with doc |
|
28 |
|
29 This field property class extracts it's docstring from parent field description, if any. |
|
30 It's main purpose is for documentation needs. |
|
31 """ |
|
32 |
|
33 @property |
|
34 def __doc__(self): |
|
35 return self._FieldProperty__field.description or super(FieldProperty, self).__doc__ |
23 |
36 |
24 |
37 |
25 class cached(object): |
38 class cached(object): |
26 """Custom property decorator to define a property or function |
39 """Custom property decorator to define a property or function |
27 which is calculated only once |
40 which is calculated only once |
28 |
41 |
29 When applied on a function, caching is based on input arguments |
42 When applied on a function, caching is based on input arguments |
30 """ |
43 """ |
31 |
44 |
32 def __init__(self, function): |
45 def __init__(self, function): |
33 self._function = function |
46 self._function = function |
63 |
76 |
64 |
77 |
65 _marker = object() |
78 _marker = object() |
66 |
79 |
67 |
80 |
68 def request_property(key): |
81 def request_property(key, prefix=None): |
69 """Define a method decorator used to store result into request's annotations |
82 """Define a method decorator used to store result into current request's annotations |
70 |
83 |
|
84 If not request is currently running, a new one is created. |
71 `key` is a required argument; if None, the key will be the method's object |
85 `key` is a required argument; if None, the key will be the method's object |
72 """ |
86 """ |
73 |
87 |
74 def request_decorator(func): |
88 def request_decorator(func): |
|
89 |
75 def wrapper(obj, key, *args, **kwargs): |
90 def wrapper(obj, key, *args, **kwargs): |
76 request = check_request() |
91 request = check_request() |
77 if callable(key): |
92 if callable(key): |
78 key = key(obj) |
93 key = key(obj) |
79 if not key: |
94 if not key: |
80 key = '{0!r}'.format(obj) |
95 key = '{1}::{0!r}'.format(obj, prefix or func.__name__) |
81 data = get_request_data(request, key, _marker) |
96 data = get_request_data(request, key, _marker) |
82 if data is _marker: |
97 if data is _marker: |
83 data = func |
98 data = func |
84 if callable(data): |
99 if callable(data): |
85 data = data(obj, *args, **kwargs) |
100 data = data(obj, *args, **kwargs) |
86 set_request_data(request, key, data) |
101 set_request_data(request, key, data) |
87 return data |
102 return data |
|
103 |
88 return lambda x: wrapper(x, key=key) |
104 return lambda x: wrapper(x, key=key) |
89 |
105 |
90 return request_decorator |
106 return request_decorator |
91 |
107 |
92 |
108 |
93 def session_property(app, key=None): |
109 def session_property(app, key=None, prefix=None): |
94 """Define a method decorator used to store result into request's session |
110 """Define a method decorator used to store result into request's session |
95 |
111 |
96 `app` is an application identifier used to prefix session keys |
112 If no request is currently running, a new one is created. |
97 `key` is session's value key; if None, the key will be the method's object |
113 |
|
114 @app: application identifier used to prefix session keys |
|
115 @key: session's value key; if None, the key will be the method's object |
98 """ |
116 """ |
99 |
117 |
100 def session_decorator(func): |
118 def session_decorator(func): |
|
119 |
101 def wrapper(obj, app, key, *args, **kwargs): |
120 def wrapper(obj, app, key, *args, **kwargs): |
102 request = check_request() |
121 request = check_request() |
103 if callable(key): |
122 if callable(key): |
104 key = key(obj) |
123 key = key(obj) |
105 if not key: |
124 if not key: |
106 key = '{0!r}'.format(obj) |
125 key = '{1}::{0!r}'.format(obj, prefix or func.__name__) |
107 data = get_session_data(request, app, key, _marker) |
126 data = get_session_data(request, app, key, _marker) |
108 if data is _marker: |
127 if data is _marker: |
109 data = func |
128 data = func |
110 if callable(data): |
129 if callable(data): |
111 data = data(obj, *args, **kwargs) |
130 data = data(obj, *args, **kwargs) |
112 set_session_data(request, app, key, data) |
131 set_session_data(request, app, key, data) |
113 return data |
132 return data |
|
133 |
114 return lambda x: wrapper(x, app=app, key=key) |
134 return lambda x: wrapper(x, app=app, key=key) |
115 |
135 |
116 return session_decorator |
136 return session_decorator |