Source code for abilian.web.views.base

# coding=utf-8
"""
"""
from __future__ import absolute_import, print_function, division

from werkzeug.exceptions import HTTPException
from flask import request, g, json, jsonify, render_template_string, redirect
from flask.views import MethodView as BaseView

from ..action import actions


class Redirect(HTTPException):
  pass


[docs]class View(BaseView): """ Base class to use for all class based views. The view instance is accessible in :data:`g <flask.g>` and is set in :meth:`actions context <abilian.web.action.ActionRegistry.context>`. """
[docs] def dispatch_request(self, *args, **kwargs): meth = getattr(self, request.method.lower(), None) # if the request method is HEAD and we don't have a handler for it # retry with GET if meth is None and request.method == 'HEAD': meth = getattr(self, 'get', None) assert meth is not None, 'Unimplemented method %r' % request.method g.view = actions.context['view'] = self try: args, kwargs = self.prepare_args(args, kwargs) return meth(*args, **kwargs) except Redirect as exc: return exc.response
[docs] def prepare_args(self, args, kwargs): """ If view arguments need to be prepared it can be done here. A typical use case is to take an identifier, convert it to an object instance and maybe store it on view instance and/or replace identifier by object in arguments. """ return args, kwargs
[docs] def redirect(self, url): """ Shortcut all call stack and return response. usage: `self.response(url_for(...))` """ raise Redirect(response=redirect(url))
_JSON_HTML = u''' <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="{{ url_for('abilian_static', filename="highlightjs/default.min.css") }}" /> </head> <body> <pre> <code class="json"> {{ content }} </code> </pre> <script src="{{ url_for('abilian_static', filename="highlightjs/highlight.min.js") }}" ></script> <script>hljs.initHighlightingOnLoad();</script> </body> </html> '''
[docs]class JSONView(View): """ Base view for JSON GET. Renders as JSON when requested by Ajax, renders as HTML when requested from browser. """
[docs] def prepare_args(self, args, kwargs): kwargs.update({k: v for k, v in request.args.items()}) return args, kwargs
[docs] def data(self, *args, **kwargs): """ This method should return data to be serialized using JSON """ raise NotImplementedError
[docs] def get(self, *args, **kwargs): data = self.data(*args, **kwargs) best_mime = request.accept_mimetypes.best_match(['text/html', 'application/json']) if best_mime == 'application/json': return jsonify(data) # dev requesting from browser? serve html, let debugtoolbar show up, etc... content = json.dumps(data, indent=2) return render_template_string(_JSON_HTML, content=content)