Skip to content

Instantly share code, notes, and snippets.

@jvanasco
Created September 11, 2013 20:50
Show Gist options
  • Save jvanasco/6529591 to your computer and use it in GitHub Desktop.
Save jvanasco/6529591 to your computer and use it in GitHub Desktop.
pyramid renderer
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)
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