-
-
Save lxneng/8a4984ad5217f63e8fd4982667583c0d to your computer and use it in GitHub Desktop.
pyramid renderer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pyramid.config import Configurator | |
from zope.interface.registry import Components | |
import simplejson as json | |
import datetime | |
import decimal | |
from .. import lib | |
def json_renderer_factory(info): | |
def _render(value, system): | |
request = system.get('request') | |
if request is not None: | |
response = request.response | |
ct = response.content_type | |
if ct == response.default_content_type: | |
response.content_type = 'application/json' | |
return lib.utils.utils.py2json(value) | |
return _render | |
def jsonp_renderer_factory(info): | |
def _render(value, system): | |
value = lib.utils.utils.py2json(value) | |
request = system.get('request') | |
if request is None: | |
return value | |
# JSONP is GET only, unless you do some weird shit that doesn't work reliably | |
callback = request.GET.get('callback',None) | |
if callback is None: | |
ct_json = 'application/json' | |
else: | |
ct_json = 'application/javascript' | |
value = '%s(%s)' % (callback, value) | |
response = request.response | |
if response.content_type == response.default_content_type : | |
response.content_type = ct_json | |
return value | |
return _render | |
def gif_renderer_factory(info): | |
def _render(value, system): | |
request = system.get('request') | |
if request is not None: | |
response = request.response | |
ct = response.content_type | |
if ct == response.default_content_type: | |
response.content_type = 'image/gif' | |
return value | |
return _render | |
def png_renderer_factory(info): | |
def _render(value, system): | |
request = system.get('request') | |
if request is not None: | |
response = request.response | |
ct = response.content_type | |
if ct == response.default_content_type: | |
response.content_type = 'image/png' | |
return value | |
return _render | |
def includeme(config): | |
"""Install our JSON renderer, able to deal with datetimes.""" | |
config.add_renderer('json', json_renderer_factory) | |
config.add_renderer('jsonp', jsonp_renderer_factory) | |
config.add_renderer('gif', gif_renderer_factory) | |
config.add_renderer('png', png_renderer_factory) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import base64 | |
import datetime | |
import decimal | |
import hashlib | |
import os | |
import re | |
import simplejson as json | |
import time | |
import types | |
transparent_gif__b64 = "R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" | |
transparent_gif = base64.b64decode(transparent_gif__b64) | |
transparent_png__b64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII==" | |
transparent_png = base64.b64decode(transparent_png__b64) | |
class JsonEncoder(json.JSONEncoder): | |
"""Extends JSONEncoder for date and decimal types.""" | |
def encode_date(self, d): | |
"""Serialize the given datetime.date object to a JSON string.""" | |
# Default is ISO 8601 compatible (standard notation). | |
return "%04d-%02d-%02d" % (d.year, d.month, d.day) | |
def encode_timedelta(self, t): | |
"""Serialize the given datetime.timedelta object to a JSON string.""" | |
days = t.days | |
if days < 0: | |
minus = "-" | |
days = -days - 1 | |
seconds = 24*60*60 - t.seconds | |
else: | |
minus = "" | |
seconds = t.seconds | |
secs = seconds % 60 | |
seconds /= 60 | |
mins = seconds % 60 | |
hours = seconds / 60 | |
return "%s%d:%02d:%02d:%02d" % (minus, days, hours, mins, secs) | |
def encode_time(self, t): | |
"""Serialize the given datetime.time object to a JSON string.""" | |
# Default is ISO 8601 compatible (standard notation). | |
return "%02d:%02d:%02d" % (t.hour, t.minute, t.second) | |
def encode_datetime(self, dt): | |
"""Serialize the given datetime.datetime object to a JSON string.""" | |
# Default is ISO 8601 compatible (standard notation). | |
# Don't use strftime because that can't handle dates before 1900. | |
return ("%04d-%02d-%02dT%02d:%02d:%02d" % | |
(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second)) | |
def default(self, o): | |
# We MUST check for a datetime.datetime instance before datetime.date. | |
# datetime.datetime is a subclass of datetime.date, and therefore | |
# instances of it are also instances of datetime.date. | |
if isinstance(o, datetime.datetime): | |
return self.encode_datetime(o) | |
elif isinstance(o, datetime.date): | |
return self.encode_date(o) | |
elif isinstance(o, datetime.timedelta): | |
return self.encode_timedelta(o) | |
elif isinstance(o, datetime.time): | |
return self.encode_time(o) | |
elif isinstance(o,set): | |
return list(o) | |
elif isinstance(o, decimal.Decimal): | |
return str(o) | |
else: | |
return json.JSONEncoder.default(self, o) | |
RE_value_datetime_1 = re.compile("^(\d){4}-(\d){2}-(\d){2}T(\d){2}:(\d){2}:(\d){2}$") | |
RE_value_datetime_2 = re.compile("^(\d){4}-(\d){2}-(\d){2}T(\d){2}:(\d){2}:(\d){2}\.\d+$") | |
RE_value_time = re.compile("^(\d){2}:(\d){2}:(\d){2}$") | |
def decoder_pair_hook(payload): | |
"""custom decoding of data strutures. | |
""" | |
rval = {} | |
for (k,v) in payload: | |
rval[k] = v | |
if isinstance(v,types.StringTypes): | |
if RE_value_datetime_1.match(v): | |
rval[k] = datetime.datetime.strptime( v , "%Y-%m-%dT%H:%M:%S" ) | |
elif RE_value_datetime_2.match(v): | |
rval[k] = datetime.datetime.strptime( v , "%Y-%m-%dT%H:%M:%S.%f" ) | |
elif RE_value_time.match(v): | |
rval[k] = datetime.datetime.strptime( v , "%H:%M:%S" ) | |
return rval | |
def py2json(payload): | |
return json.dumps(payload, cls=JsonEncoder, separators=(',',':')) | |
def json2py(payload): | |
return json.loads( payload , object_pairs_hook=decoder_pair_hook ) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment