1. murarth
  2. reddish

Source

reddish / reddish / lib / renderers.py

'''
Defines extension-specific render functions

Each renderer takes one or more positional arguments, the last of which is
a dict containing named variables to rendered to the client. Optionally,
a renderer may receive a str as a first parameter, naming a template used
for rendering.

In order to be accessible, a renderer must be declared in the
reddish.lib.middleware type ExtensionMiddleware attribute EXTENSIONS.
'''

import datetime
from pylons import tmpl_context as c
from pylons.controllers.util import abort
from pylons.templating import render_mako
import simplejson as json

from . import mongo, helpers as h
from ..model import Renderable

def render_object(obj, user):
    '''
    Render an object, possibly containing a Renderable, into primitive types
    suitable for serializing to the client.

    obj:
        Object to be serialized

    user:
        Logged-in User requesting object or None
    '''
    if isinstance(obj, dict):
        for k, v in obj.iteritems():
            vv = render_object(v, user)
            if v is not vv:
                obj[k] = vv
    elif isinstance(obj, list):
        for i, v in enumerate(obj):
            vv = render_object(v, user)
            if v is not vv:
                obj[i] = vv
    elif isinstance(obj, mongo.ResultSet):
        return [render_object(i, user) for i in obj]
    elif isinstance(obj, Renderable):
        return obj.render(user)

    return obj

def render_html(*args):
    if len(args) == 2:
        name, obj = args
        return render_mako(name + '.mako', obj)

    # Some controller actions cannot be rendered to HTML and will not be
    # called with a template name. Report these to the client as a 204.
    abort(204)

def json_default(obj):
    if isinstance(obj, datetime.datetime):
        return h.to_timestamp(obj)
    elif isinstance(obj, mongo.ResultSet):
        return list(obj)
    raise TypeError('Cannot serialize to JSON type ' + type(obj).__name__)

def render_json(*args):
    obj = render_object(args[-1], c.user)
    if c.num_items is not None and c.num_items != -1:
        obj['num_items'] = c.num_items
    return json.dumps(obj, default = json_default).replace('/', r'\/')

def render_xml(*args):
    return render_mako('rss.mako', args[-1])