Created
April 6, 2010 00:42
-
-
Save mitechie/357062 to your computer and use it in GitHub Desktop.
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 logging | |
try: | |
import json | |
except ImportError: | |
import simplejson as json | |
log = logging.getLogger(__name__) | |
class JSONResponse(object): | |
"""JSONResponse provides a standard method of responding to all JSON ajax | |
requests. | |
So that we can determine success/failure, related messages, and any html | |
data payload we wish to send back to the client | |
""" | |
success = False | |
message = "" | |
payload = {} | |
def __init__(self, success=False, message=None, payload=None): | |
"""Create JSONResponse | |
Check for success, message, payload and make sure payload is a dict | |
object | |
""" | |
if success: | |
self.success = True | |
if message is not None: | |
self.message = str(message) | |
else: | |
self.message = "" | |
if payload is not None and isinstance(payload, dict): | |
self.payload = payload | |
else: | |
self.payload = {} | |
def jsonify(self): | |
"""Return a json string of the response """ | |
return json.dumps(self.dict_response()) | |
def json_response(self, response): | |
"""Return a json response with headers set manually | |
If we want to combine a single json/html response in one controller | |
we can't use the jsonify decorator. We need to do the work that the | |
jsonify decorator does in here | |
""" | |
response.headers['Content-Type'] = 'application/json' | |
return self.jsonify() | |
def dict_response(self): | |
"""Build a dictionary of the response object """ | |
return {"success": self.success, | |
"message": self.message, | |
"payload": self.payload} | |
from decorator import decorator | |
def mijson(): | |
"""Action decorator that formats output for JSON | |
Given a function that will return content, this decorator will turn | |
the result into JSON, with a content-type of 'application/json' and | |
output it. | |
adds a method to the controller | |
self.accepts_json() | |
It checks if the request comes in accepting json and returns a JSONResponse | |
object pulling from: | |
self.json.success | |
self.json.message | |
self.json.payload | |
returned html content is placed into json.payload.html | |
Otherwise it just returns the html output returned. | |
A template variable is set so that the template can conditionaly inherit | |
or not | |
c.request_ajax = Bool | |
Sample Controller: | |
@myjson() | |
def pause(self, id): | |
result = SomeObj.pause() | |
if result: | |
self.json.success = True | |
self.json.message = 'Paused' | |
else: | |
self.json.success = False | |
self.json.message = 'Failed' | |
self.json.payload['job_id'] = id | |
return '<h1>Result was: %s</h1>' % message | |
Response: | |
{'success': true, | |
'message': 'Paused', | |
'payload': {'html': '<h1>Result was: Paused</h1>'}} | |
""" | |
def wrapper(func, self, *args, **kwargs): | |
request = self._py_object.request | |
response = self._py_object.response | |
def controller_accepts_json(): | |
return 'application/json' in request.headers.get('accept', '') | |
is_json = False | |
self._py_object.c.request_ajax = False | |
self.accepts_json = controller_accepts_json | |
# go ahead and put this on the controller | |
# but we'll only use it if this is a json request | |
self.json = JSONResponse() | |
self.json.success = False | |
self.json.message = "" | |
self.json.payload = {} | |
if self.accepts_json(): | |
is_json = True | |
# let the template know it's an ajax request | |
self._py_object.c.request_ajax = True | |
html = func(self, *args, **kwargs) | |
if is_json: | |
response.headers['Content-Type'] = 'application/json' | |
# grab the returned html content and place it in the payload under the | |
# key html | |
self.json.payload['html'] = html | |
log.debug("Returning JSON wrapped action output") | |
return self.json.jsonify() | |
else: | |
return html | |
return func(self, *args, **kwargs) | |
return decorator(wrapper) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment