Created
April 6, 2010 00:42
-
-
Save mitechie/357062 to your computer and use it in GitHub Desktop.
Revisions
-
mitechie created this gist
Apr 6, 2010 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,150 @@ 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)