Skip to content

Commit

Permalink
added feedback functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Fatih Erikli committed Sep 23, 2012
1 parent 18627ac commit 4aacc1c
Show file tree
Hide file tree
Showing 10 changed files with 186 additions and 82 deletions.
44 changes: 33 additions & 11 deletions api_browser/browser.py
Expand Up @@ -3,33 +3,55 @@
from django.conf.urls import url
from django.shortcuts import render_to_response
from django.template import RequestContext
from settings import API_BROWSER_SCHEMA_PATH

from api_browser.forms import FeedbackForm
from api_browser.settings import API_BROWSER_SCHEMA_PATH


class APIBrowser(object):

index_template = "api_browser/index.html"
feedback_template = "api_browser/submit_feedback.html"
feedback_form = FeedbackForm
schema = None

@property
def urls(self):
return self.get_urls()

def get_urls(self):
return [
url("^$", self.browser_index, name="api_browser_index")
]
def get_deserializer_module(self):
return json

def get_schema(self):
return self.schema if self.schema is not None else self.load_schema()

def load_schema(self):
return self.get_deserializer_module().load(API_BROWSER_SCHEMA_PATH)

# view logic
def get_feedback_form(self):
return self.feedback_form

def browser_index(self, request):
return render_to_response(self.index_template, {
"schema": self.get_schema()
}, context_instance=RequestContext(request))

def get_deserializer_module(self):
return json
def save_feedback_form(self, request, form):
form.save()

def submit_feedback(self, request):
form = self.get_feedback_form()(request.POST or None)
if form.is_valid():
self.save_feedback_form(request, form)
return render_to_response(self.index_template, {
"form": form
}, context_instance=RequestContext(request))


# urls configuration
@property
def urls(self):
return self.get_urls()

def get_urls(self):
return [
url("^$", self.browser_index, name="api_browser_index"),
url("^submit-feedback$", self.submit_feedback, name="api_browser_submit_feedback"),
]
9 changes: 9 additions & 0 deletions api_browser/constants.py
@@ -0,0 +1,9 @@
from django.utils.translation import ugettext_lazy as _

STATUS_OPEN = 0
STATUS_CLOSED = 1

STATUS_CHOICES = (
(STATUS_OPEN, _('Open')),
(STATUS_CLOSED, _('Closed')),
)
8 changes: 8 additions & 0 deletions api_browser/forms.py
@@ -0,0 +1,8 @@
from django import forms

from api_browser.models import Feedback


class FeedbackForm(forms.ModelForm):
class Meta:
model = Feedback
19 changes: 19 additions & 0 deletions api_browser/models.py
@@ -0,0 +1,19 @@
from django.db import models
from django.utils.encoding import smart_unicode

from api_browser.constants import STATUS_CHOICES, STATUS_OPEN


class Feedback(models.Model):
"""
Holds Feedback data.
"""
title = models.CharField(max_length=255)
description = models.TextField(null=True, blank=True)
status = models.IntegerField(choices=STATUS_CHOICES, default=STATUS_OPEN)
duplicate = models.ForeignKey("self", null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)

def __unicode__(self):
return smart_unicode(self.title)
24 changes: 15 additions & 9 deletions api_browser/static/api_browser/css/screen.css
Expand Up @@ -15,13 +15,13 @@ body {

body > header {
margin-top: 70px;
background-color: #ebebeb;
}

body > header h1 {
font-size: 30px;
font-weight: normal;
font-size: 25px;
font-weight: bold;
padding: 5px 15px;
text-align: center;
}

/*
Expand All @@ -48,15 +48,21 @@ section.api-info {
* Resource definitions
*/
section.resource {

margin: 10px;
margin: 10px 0 30px;
}

section.resource header h3 {
font-size: 25px;
font-size: 28px;
margin: 0;
font-weight: normal;
color: black;
color: #636363;
}

section.resource header p {
font-size: 15px;
background-color: #fff;
margin: 0;
padding: 5px 2px;
}

section.resource ul {
Expand All @@ -66,7 +72,7 @@ section.resource {

section.resource ul li {
list-style-type: none;
padding-bottom: 10px;
padding-bottom: 0;
}

section.resource ul li .try-it {
Expand Down Expand Up @@ -126,7 +132,7 @@ section.resource {
float: right;
padding-top: 3px;
padding-right: 5px;
font-size: 19px;
font-size: 15px;
}

/*
Expand Down
64 changes: 64 additions & 0 deletions api_browser/static/api_browser/js/app.js
@@ -0,0 +1,64 @@
var APIBrowser = $.Class.extend({

EMPTY_RESPONSE: "(EMPTY RESPONSE)",
SLIDE_DURATION: 100,

selectors: {
endpoint_form : ".endpoint form",
endpoint_anchor: ".endpoint a",
try_it: ".try-it",
request: ".request",
code: "code",
response_status: ".response-status",
response_headers: ".response-headers",
response_body: ".response-body",
url_parameters: ".url-parameters input"
},

init: function () {
this.load_rest_form();
this.make_expandable(this.selectors.endpoint_anchor,
this.selectors.try_it, this.SLIDE_DURATION);
this.fill_url_parameters(this.selectors.url_parameters, this.selectors.endpoint_form);
},

load_rest_form: function () {
$(this.selectors.endpoint_form).restForm({
"submit": this.submit_form.bind(this),
"complete": this.complete_ajax_request.bind(this)
});
},

"submit_form": function (form, request_headers) {
form.siblings(this.selectors.request).show().
find(this.selectors.code).html(request_headers.join("\n"));
},

"complete_ajax_request": function (form, xhr) {
form.siblings(this.selectors.response_status).show().find(
this.selectors.code).html(xhr.statusText + " (" + xhr.status + ")");

form.siblings(this.selectors.response_headers).show().find(
this.selectors.code).html(xhr.getAllResponseHeaders());

form.siblings(this.selectors.response_body).show().find(
this.selectors.code).text(xhr.responseText || this.EMPTY_RESPONSE);
},

make_expandable: function (click_element, show_element, slide_duration) {
$(click_element).click(function () {
$(this).siblings(show_element).slideToggle(slide_duration || "normal");
return false;
});
},

"fill_url_parameters": function (url_parameters, form_selector) {
$(url_parameters).change(function () {
var form = $(this).parents(form_selector);
var rendered_url = form.data("endpoint-url").replace(
$(this).data("token"), $(this).val());
form.attr("action", rendered_url)
})
}

});
7 changes: 7 additions & 0 deletions api_browser/static/api_browser/js/jquery.class.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 9 additions & 5 deletions api_browser/static/api_browser/js/jquery.rest-form.js
@@ -1,4 +1,5 @@
/*
* restForm
*
* fatiherikli at gmail dot com
* http://fatiherikli.com
Expand All @@ -25,22 +26,25 @@

this.each(function () {
$(this).submit(function () {
var data = $(this).form2json();
var method = $(this).attr("method");
var url = $(this).attr("action");
var form = $(this);
var data = form.form2json();
var method = form.attr("method");
var url = form.attr("action");
var content_type = 'application/json';

options.submit.call(this, build_request_headers(method, url, data,
// firing submit event
options.submit.call(this, form, build_request_headers(method, url, data,
content_type));

// calling api resource
$.ajax({
url: url,
type: method,
data: JSON.stringify(data),
contentType: content_type,
dataType: 'json',
processData: false
}).complete(options.complete.bind(this));
}).complete(options.complete.bind(this, form));

return false;

Expand Down

0 comments on commit 4aacc1c

Please sign in to comment.