|
|
@@ -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) |