1 # This file is part of Indico.
2 # Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
4 # Indico is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3 of the
7 # License, or (at your option) any later version.
9 # Indico is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with Indico; if not, see <http://www.gnu.org/licenses/>.
17 from __future__
import absolute_import
20 from datetime
import datetime
, date
22 from flask
import current_app
, session
23 from persistent
.dict import PersistentDict
24 from speaklater
import _LazyString
25 from werkzeug
.exceptions
import Forbidden
27 from indico
.web
.util
import get_request_info
30 import simplejson
as _json
35 class IndicoJSONEncoder(_json
.JSONEncoder
):
37 Custom JSON encoder that supports more types
42 if isinstance(o
, _LazyString
):
44 elif isinstance(o
, PersistentDict
):
46 elif isinstance(o
, datetime
):
47 return {'date': str(o
.date()), 'time': str(o
.time()), 'tz': str(o
.tzinfo
)}
48 elif isinstance(o
, date
):
50 return _json
.JSONEncoder
.default(self
, o
)
53 def dumps(obj
, **kwargs
):
55 Simple wrapper around json.dumps()
57 if kwargs
.pop('pretty', False):
58 kwargs
['indent'] = 4 * ' '
59 textarea
= kwargs
.pop('textarea', False)
60 ret
= _json
.dumps(obj
, cls
=IndicoJSONEncoder
, **kwargs
).replace('/', '\\/')
63 return '<html><head></head><body><textarea>%s</textarea></body></html>' % ret
70 Simple wrapper around json.decode()
72 return _json
.loads(string
)
75 def create_json_error_answer(exception
, status
=200):
76 from indico
.core
.config
import Config
77 from indico
.core
.errors
import IndicoError
, get_error_description
78 if isinstance(exception
, IndicoError
):
79 details
= exception
.toDict()
81 exception_data
= exception
.__dict
__
83 _json
.dumps(exception_data
)
87 'code': type(exception
).__name
__,
88 'type': 'noReport' if not session
.user
and isinstance(exception
, Forbidden
) else 'unknown',
89 'message': unicode(get_error_description(exception
)),
90 'data': exception_data
,
91 'requestInfo': get_request_info(),
92 'inner': traceback
.format_exc()
95 return current_app
.response_class(dumps({
96 'version': Config
.getInstance().getVersion(),
99 }), mimetype
='application/json', status
=status
)