238 w = self.write |
238 w = self.write |
239 # 1/ variable declaration if any |
239 # 1/ variable declaration if any |
240 if self.jsvars: |
240 if self.jsvars: |
241 w(u'<script type="text/javascript"><!--//--><![CDATA[//><!--\n') |
241 w(u'<script type="text/javascript"><!--//--><![CDATA[//><!--\n') |
242 for var, value, override in self.jsvars: |
242 for var, value, override in self.jsvars: |
243 vardecl = u'%s = %s;' % (var, dumps(value)) |
243 vardecl = u'%s = %s;' % (var, json.dumps(value)) |
244 if not override: |
244 if not override: |
245 vardecl = (u'if (typeof %s == "undefined") {%s}' % |
245 vardecl = (u'if (typeof %s == "undefined") {%s}' % |
246 (var, vardecl)) |
246 (var, vardecl)) |
247 w(vardecl + u'\n') |
247 w(vardecl + u'\n') |
248 w(u'//--><!]]></script>\n') |
248 w(u'//--><!]]></script>\n') |
337 if not __answer_cache: # first time, not in cache |
337 if not __answer_cache: # first time, not in cache |
338 __answer_cache.append(_pdf_conversion_availability()) |
338 __answer_cache.append(_pdf_conversion_availability()) |
339 return __answer_cache[0] |
339 return __answer_cache[0] |
340 |
340 |
341 try: |
341 try: |
342 try: |
342 # may not be there if cubicweb-web not installed |
343 # may not be there if cubicweb-web not installed |
343 if sys.version_info < (2,6): |
344 from json import dumps, JSONEncoder |
344 import simplejson as json |
345 except ImportError: |
345 else: |
346 from simplejson import dumps, JSONEncoder |
346 import json |
347 except ImportError: |
347 except ImportError: |
348 pass |
348 pass |
349 else: |
349 else: |
350 |
350 |
351 class CubicWebJsonEncoder(JSONEncoder): |
351 class CubicWebJsonEncoder(json.JSONEncoder): |
352 """define a json encoder to be able to encode yams std types""" |
352 """define a json encoder to be able to encode yams std types""" |
353 |
353 |
354 # _iterencode is the only entry point I've found to use a custom encode |
354 # _iterencode is the only entry point I've found to use a custom encode |
355 # hook early enough: .default() is called if nothing else matched before, |
355 # hook early enough: .default() is called if nothing else matched before, |
356 # .iterencode() is called once on the main structure to encode and then |
356 # .iterencode() is called once on the main structure to encode and then |
357 # never gets called again. |
357 # never gets called again. |
358 # For the record, our main use case is in FormValidateController with: |
358 # For the record, our main use case is in FormValidateController with: |
359 # dumps((status, args, entity), cls=CubicWebJsonEncoder) |
359 # json.dumps((status, args, entity), cls=CubicWebJsonEncoder) |
360 # where we want all the entity attributes, including eid, to be part |
360 # where we want all the entity attributes, including eid, to be part |
361 # of the json object dumped. |
361 # of the json object dumped. |
362 # This would have once more been easier if Entity didn't extend dict. |
362 # This would have once more been easier if Entity didn't extend dict. |
363 def _iterencode(self, obj, markers=None): |
363 def _iterencode(self, obj, markers=None): |
364 if hasattr(obj, '__json_encode__'): |
364 if hasattr(obj, '__json_encode__'): |
365 obj = obj.__json_encode__() |
365 obj = obj.__json_encode__() |
366 return JSONEncoder._iterencode(self, obj, markers) |
366 return json.JSONEncoder._iterencode(self, obj, markers) |
367 |
367 |
368 def default(self, obj): |
368 def default(self, obj): |
369 if isinstance(obj, datetime.datetime): |
369 if isinstance(obj, datetime.datetime): |
370 return obj.strftime('%Y/%m/%d %H:%M:%S') |
370 return obj.strftime('%Y/%m/%d %H:%M:%S') |
371 elif isinstance(obj, datetime.date): |
371 elif isinstance(obj, datetime.date): |
375 elif isinstance(obj, datetime.timedelta): |
375 elif isinstance(obj, datetime.timedelta): |
376 return (obj.days * 24 * 60 * 60) + obj.seconds |
376 return (obj.days * 24 * 60 * 60) + obj.seconds |
377 elif isinstance(obj, decimal.Decimal): |
377 elif isinstance(obj, decimal.Decimal): |
378 return float(obj) |
378 return float(obj) |
379 try: |
379 try: |
380 return JSONEncoder.default(self, obj) |
380 return json.JSONEncoder.default(self, obj) |
381 except TypeError: |
381 except TypeError: |
382 # we never ever want to fail because of an unknown type, |
382 # we never ever want to fail because of an unknown type, |
383 # just return None in those cases. |
383 # just return None in those cases. |
384 return None |
384 return None |
385 |
385 |