equal
deleted
inserted
replaced
18 """json export views""" |
18 """json export views""" |
19 |
19 |
20 __docformat__ = "restructuredtext en" |
20 __docformat__ = "restructuredtext en" |
21 _ = unicode |
21 _ = unicode |
22 |
22 |
|
23 from cubicweb.uilib import rest_traceback |
|
24 |
23 from cubicweb.utils import json_dumps |
25 from cubicweb.utils import json_dumps |
24 from cubicweb.predicates import any_rset, empty_rset |
26 from cubicweb.predicates import ExpectedValuePredicate, any_rset, empty_rset |
25 from cubicweb.view import EntityView, AnyRsetView |
27 from cubicweb.view import EntityView, AnyRsetView |
26 from cubicweb.web.application import anonymized_request |
28 from cubicweb.web.application import anonymized_request |
27 from cubicweb.web.views import basecontrollers |
29 from cubicweb.web.views import basecontrollers, management |
28 |
30 |
29 class JsonpController(basecontrollers.ViewController): |
31 class JsonpController(basecontrollers.ViewController): |
30 """The jsonp controller is the same as a ViewController but : |
32 """The jsonp controller is the same as a ViewController but : |
31 |
33 |
32 - anonymize request (avoid CSRF attacks) |
34 - anonymize request (avoid CSRF attacks) |
56 return self._get_json_data(rset) |
58 return self._get_json_data(rset) |
57 |
59 |
58 def _get_json_data(self, rset): |
60 def _get_json_data(self, rset): |
59 json_data = super(JsonpController, self).publish(rset) |
61 json_data = super(JsonpController, self).publish(rset) |
60 if 'callback' in self._cw.form: # jsonp |
62 if 'callback' in self._cw.form: # jsonp |
61 json_padding = self._cw.form['callback'] |
63 json_padding = self._cw.form['callback'].encode('ascii') |
62 # use ``application/javascript`` is ``callback`` parameter is |
64 # use ``application/javascript`` if ``callback`` parameter is |
63 # provided, let ``application/json`` otherwise |
65 # provided, keep ``application/json`` otherwise |
64 self._cw.set_content_type('application/javascript') |
66 self._cw.set_content_type('application/javascript') |
65 json_data = '%s(%s)' % (json_padding, json_data) |
67 json_data = b'%s(%s)' % (json_padding, json_data) |
66 return json_data |
68 return json_data |
67 |
69 |
68 |
70 |
69 class JsonMixIn(object): |
71 class JsonMixIn(object): |
70 """mixin class for json views |
72 """mixin class for json views |
117 entity.cw_attr_cache.update({ |
119 entity.cw_attr_cache.update({ |
118 '__cwetype__': entity.cw_etype, |
120 '__cwetype__': entity.cw_etype, |
119 }) |
121 }) |
120 entities.append(entity) |
122 entities.append(entity) |
121 self.wdata(entities) |
123 self.wdata(entities) |
|
124 |
|
125 |
|
126 class _requested_vid(ExpectedValuePredicate): |
|
127 """predicate that checks vid parameter value |
|
128 |
|
129 It differs from ``match_view`` in that it doesn't expect a ``view`` |
|
130 parameter to be given to ``select`` but will rather check |
|
131 ``req.form['vid']`` to match expected vid. |
|
132 """ |
|
133 def __call__(self, cls, req, rset=None, **kwargs): |
|
134 return req.form.get('vid') in self.expected |
|
135 |
|
136 |
|
137 class JsonErrorView(JsonMixIn, management.ErrorView): |
|
138 """custom error view selected when client asks for a json view |
|
139 |
|
140 The returned json object will contain err / traceback informations. |
|
141 """ |
|
142 __select__ = (management.ErrorView.__select__ & |
|
143 _requested_vid('jsonexport', 'ejsonexport')) |
|
144 |
|
145 def call(self): |
|
146 errmsg, exclass, excinfo = self._excinfo() |
|
147 self.wdata({ |
|
148 'errmsg': errmsg, |
|
149 'exclass': exclass, |
|
150 'traceback': rest_traceback(excinfo, errmsg), |
|
151 }) |