Fix day filter
[cds-indico.git] / indico / util / json.py
blob467a9852ba073240b559a04542ed640dc1f52eee
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
19 import traceback
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
29 try:
30 import simplejson as _json
31 except ImportError:
32 import json as _json
35 class IndicoJSONEncoder(_json.JSONEncoder):
36 """
37 Custom JSON encoder that supports more types
38 * datetime objects
39 * PersistentDict
40 """
41 def default(self, o):
42 if isinstance(o, _LazyString):
43 return o.value
44 elif isinstance(o, PersistentDict):
45 return dict(o)
46 elif isinstance(o, datetime):
47 return {'date': str(o.date()), 'time': str(o.time()), 'tz': str(o.tzinfo)}
48 elif isinstance(o, date):
49 return str(o)
50 return _json.JSONEncoder.default(self, o)
53 def dumps(obj, **kwargs):
54 """
55 Simple wrapper around json.dumps()
56 """
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('/', '\\/')
62 if textarea:
63 return '<html><head></head><body><textarea>%s</textarea></body></html>' % ret
64 else:
65 return ret
68 def loads(string):
69 """
70 Simple wrapper around json.decode()
71 """
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()
80 else:
81 exception_data = exception.__dict__
82 try:
83 _json.dumps(exception_data)
84 except Exception:
85 exception_data = {}
86 details = {
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(),
97 'result': None,
98 'error': details
99 }), mimetype='application/json', status=status)