Login/Logout and FlyWheel API link in HTML emitter

This commit is contained in:
tom christie tom@tomchristie.com 2011-01-27 21:09:25 +00:00
parent e227c38b33
commit 216baa551f
6 changed files with 109 additions and 74 deletions

View File

@ -1,4 +1,7 @@
# Django settings for src project. # Django settings for src project.
import os
BASE_DIR = os.path.dirname(__file__)
DEBUG = True DEBUG = True
TEMPLATE_DEBUG = DEBUG TEMPLATE_DEBUG = DEBUG
@ -81,6 +84,7 @@ TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows. # Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths. # Don't forget to use absolute paths, not relative paths.
os.path.join(BASE_DIR, 'templates')
) )
INSTALLED_APPS = ( INSTALLED_APPS = (

View File

@ -7,6 +7,8 @@ urlpatterns = patterns('',
(r'pygments-example/', include('pygments_api.urls')), (r'pygments-example/', include('pygments_api.urls')),
(r'^blog-post-example/', include('blogpost.urls')), (r'^blog-post-example/', include('blogpost.urls')),
(r'^object-store-example/', include('objectstore.urls')), (r'^object-store-example/', include('objectstore.urls')),
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
(r'^accounts/logout/$', 'django.contrib.auth.views.logout'),
(r'^admin/doc/', include('django.contrib.admindocs.urls')), (r'^admin/doc/', include('django.contrib.admindocs.urls')),
(r'^admin/', include(admin.site.urls)), (r'^admin/', include(admin.site.urls)),
) )

View File

@ -1,9 +1,10 @@
from django.conf import settings
from django.template import RequestContext, loader from django.template import RequestContext, loader
from django import forms from django import forms
from flywheel.response import NoContent from flywheel.response import NoContent
from utils import dict2xml from utils import dict2xml, url_resolves
import string import string
try: try:
import json import json
@ -12,6 +13,7 @@ except ImportError:
class BaseEmitter(object): class BaseEmitter(object):
media_type = None media_type = None
@ -118,13 +120,22 @@ class DocumentingTemplateEmitter(BaseEmitter):
content = self._get_content(self.resource, output) content = self._get_content(self.resource, output)
form_instance = self._get_form_instance(self.resource) form_instance = self._get_form_instance(self.resource)
if url_resolves(settings.LOGIN_URL) and url_resolves(settings.LOGOUT_URL):
login_url = "%s?next=%s" % (settings.LOGIN_URL, self.resource.request.path)
logout_url = "%s?next=%s" % (settings.LOGOUT_URL, self.resource.request.path)
else:
login_url = None
logout_url = None
template = loader.get_template(self.template) template = loader.get_template(self.template)
context = RequestContext(self.resource.request, { context = RequestContext(self.resource.request, {
'content': content, 'content': content,
'resource': self.resource, 'resource': self.resource,
'request': self.resource.request, 'request': self.resource.request,
'response': self.resource.response, 'response': self.resource.response,
'form': form_instance 'form': form_instance,
'login_url': login_url,
'logout_url': logout_url,
}) })
ret = template.render(context) ret = template.render(context)

View File

@ -7,9 +7,7 @@ from flywheel.response import status, Response, ResponseException
from decimal import Decimal from decimal import Decimal
import re import re
from itertools import chain
# TODO: Display user login in top panel: http://stackoverflow.com/questions/806835/django-redirect-to-previous-page-after-login
# TODO: Figure how out references and named urls need to work nicely # TODO: Figure how out references and named urls need to work nicely
# TODO: POST on existing 404 URL, PUT on existing 404 URL # TODO: POST on existing 404 URL, PUT on existing 404 URL
# #

View File

@ -5,6 +5,11 @@
<head> <head>
<style> <style>
pre {border: 1px solid black; padding: 1em; background: #ffd} pre {border: 1px solid black; padding: 1em; background: #ffd}
body {margin: 0; border:0; padding: 0;}
span.api {margin: 0.5em 1em}
span.auth {float: right; margin-right: 1em}
div.header {margin: 0; border:0; padding: 0.25em 0; background: #ddf}
div.content {margin: 0 1em;}
div.action {border: 1px solid black; padding: 0.5em 1em; margin-bottom: 0.5em; background: #ddf} div.action {border: 1px solid black; padding: 0.5em 1em; margin-bottom: 0.5em; background: #ddf}
ul.accepttypes {float: right; list-style-type: none; margin: 0; padding: 0} ul.accepttypes {float: right; list-style-type: none; margin: 0; padding: 0}
ul.accepttypes li {display: inline;} ul.accepttypes li {display: inline;}
@ -17,14 +22,19 @@
<title>API - {{ resource.name }}</title> <title>API - {{ resource.name }}</title>
</head> </head>
<body> <body>
<div class='header'>
<span class='api'><a href='http://www.thewebhaswon.com/flywheel/'>FlyWheel API</a></span>
<span class='auth'>{% if user.is_active %}Welcome, {{ user }}.{% if logout_url %} <a href='{{ logout_url }}'>Log out</a>{% endif %}{% else %}Not logged in {% if login_url %}<a href='{{ login_url }}'>Log in</a>{% endif %}{% endif %}</span>
</div>
<div class='content'>
<h1>{{ resource.name }}</h1> <h1>{{ resource.name }}</h1>
<p>{{ resource.description|linebreaksbr }}</p> <p>{{ resource.description|linebreaksbr }}</p>
<pre><b>{{ response.status }} {{ response.status_text }}</b>{% autoescape off %} <pre><b>{{ response.status }} {{ response.status_text }}</b>{% autoescape off %}
{% for key, val in response.headers.items %}<b>{{ key }}:</b> {{ val|urlize_quoted_links }} {% for key, val in response.headers.items %}<b>{{ key }}:</b> {{ val|urlize_quoted_links }}
{% endfor %} {% endfor %}
{{ content|urlize_quoted_links }} </pre>{% endautoescape %} {{ content|urlize_quoted_links }}</pre>{% endautoescape %}
{% if 'GET' in resource.allowed_methods %} {% if 'GET' in resource.allowed_methods %}
<div class='action'> <div class='action'>
<a href='{{ request.path }}'>GET</a> <a href='{{ request.path }}'>GET</a>
<ul class="accepttypes"> <ul class="accepttypes">
@ -36,14 +46,14 @@
</ul> </ul>
<div class="clearing"></div> <div class="clearing"></div>
</div> </div>
{% endif %} {% endif %}
{% comment %} *** Only display the POST/PUT/DELETE forms if we have a bound form, and if method *** {% comment %} *** Only display the POST/PUT/DELETE forms if we have a bound form, and if method ***
*** tunneling via POST forms is enabled. *** *** tunneling via POST forms is enabled. ***
*** (We could display only the POST form if method tunneling is disabled, but I think *** *** (We could display only the POST form if method tunneling is disabled, but I think ***
*** the user experience would be confusing, so we simply turn all forms off. *** {% endcomment %} *** the user experience would be confusing, so we simply turn all forms off. *** {% endcomment %}
{% if resource.METHOD_PARAM and form %} {% if resource.METHOD_PARAM and form %}
{% if 'POST' in resource.allowed_methods %} {% if 'POST' in resource.allowed_methods %}
<div class='action'> <div class='action'>
<form action="{{ request.path }}" method="post"> <form action="{{ request.path }}" method="post">
@ -92,7 +102,7 @@
</form> </form>
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}
</div>
</body> </body>
</html> </html>

View File

@ -2,11 +2,21 @@ import re
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from django.utils.encoding import smart_unicode from django.utils.encoding import smart_unicode
from django.utils.xmlutils import SimplerXMLGenerator from django.utils.xmlutils import SimplerXMLGenerator
from django.core.urlresolvers import resolve
try: try:
import cStringIO as StringIO import cStringIO as StringIO
except ImportError: except ImportError:
import StringIO import StringIO
def url_resolves(url):
"""Return True if the given URL is mapped to a view in the urlconf, False otherwise."""
try:
resolve(url)
except:
return False
return True
# From piston # From piston
def coerce_put_post(request): def coerce_put_post(request):
""" """