From d9f52e386092dc4c12dc370f8c0d1605838a69f3 Mon Sep 17 00:00:00 2001 From: Stephen McQuay Date: Tue, 23 Apr 2013 22:48:03 -0700 Subject: [PATCH 1/2] added django ajax csrf file --- static/django-csrf.js | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 static/django-csrf.js diff --git a/static/django-csrf.js b/static/django-csrf.js new file mode 100644 index 0000000..4f567b6 --- /dev/null +++ b/static/django-csrf.js @@ -0,0 +1,44 @@ +// using jQuery +function getCookie(name) { + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; +} +var csrftoken = getCookie('csrftoken'); +function csrfSafeMethod(method) { + // these HTTP methods do not require CSRF protection + return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); +} +function sameOrigin(url) { + // test that a given url is a same-origin URL + // url could be relative or scheme relative or absolute + var host = document.location.host; // host + port + var protocol = document.location.protocol; + var sr_origin = '//' + host; + var origin = protocol + sr_origin; + // Allow absolute or scheme relative URLs to same origin + return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || + (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || + // or any other URL that isn't scheme relative or absolute i.e relative. + !(/^(\/\/|http:|https:).*/.test(url)); +} +$.ajaxSetup({ + beforeSend: function(xhr, settings) { + if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) { + // Send the token to same-origin, relative URLs only. + // Send the token only if the method warrants CSRF protection + // Using the CSRFToken value acquired earlier + xhr.setRequestHeader("X-CSRFToken", csrftoken); + } + } +}); From 191ebc3285ee681f7e07df1c3215c758c0646a02 Mon Sep 17 00:00:00 2001 From: Stephen McQuay Date: Tue, 23 Apr 2013 22:48:16 -0700 Subject: [PATCH 2/2] got things basically working --- mmg/urls.py | 3 ++- mmg/views.py | 54 ++++++++++++++++++++++++++++++-------------- static/math.css | 3 +++ static/math.js | 36 +++++++++++++++++++++++++++++ templates/index.html | 23 ++++++++----------- 5 files changed, 88 insertions(+), 31 deletions(-) diff --git a/mmg/urls.py b/mmg/urls.py index 7142081..452715d 100644 --- a/mmg/urls.py +++ b/mmg/urls.py @@ -7,5 +7,6 @@ from django.conf.urls import patterns, url urlpatterns = patterns( '', url(r'^$', 'mmg.views.home', name='home'), - url(r'^answer/$', 'mmg.views.answer', name='answer'), + url(r'^api/v0/attempt/$', 'mmg.views.attempt', name='attempt'), + url(r'^api/v0/problem/$', 'mmg.views.problem', name='problem'), ) diff --git a/mmg/views.py b/mmg/views.py index 0847fab..244b826 100644 --- a/mmg/views.py +++ b/mmg/views.py @@ -1,6 +1,7 @@ +import json import random -from django.http import HttpResponseRedirect +from django.http import HttpResponseRedirect, HttpResponse from django.core.urlresolvers import reverse from django.shortcuts import render @@ -9,7 +10,7 @@ from mmg.forms import NumberForm MAX = 12 -def home(request): +def _generate_problem(): operation = random.choice(['+', '-']) first = random.choice(range(MAX)) if operation == '-': @@ -19,23 +20,42 @@ def home(request): second = random.choice(range(first)) else: second = random.choice(range(MAX)) - form = NumberForm({ + return { 'first': first, 'operation': operation, 'second': second, - }) - return render( - request, - 'index.html', - { - 'form': form, - } - ) + } -def answer(request): - form = NumberForm(request.POST or None) - print(form) - if form.is_valid(): - print(form.cleaned_data) - return HttpResponseRedirect(reverse('mmg.views.home')) +def _validate_solution(a): + print a + f = int(a['first']) + o = a['operation'] + s = int(a['second']) + if a['answer'] == '': + g = 0 + else: + g = int(a['answer']) + r = False + if o == '+': + r = bool(f + s == g) + else: + r = bool(f - s == g) + return r + + +def home(request): + return render(request, 'index.html') + + +def attempt(request): + d = request.POST.dict() + return HttpResponse( + json.dumps({'status': _validate_solution(d)}), + content_type="application/json") + + +def problem(request): + return HttpResponse( + json.dumps(_generate_problem()), + content_type="application/json") diff --git a/static/math.css b/static/math.css index f5d3d70..d64b604 100644 --- a/static/math.css +++ b/static/math.css @@ -16,3 +16,6 @@ padding-top: 30px; } +.wrong { + background: red; +} diff --git a/static/math.js b/static/math.js index e69de29..9d99d22 100644 --- a/static/math.js +++ b/static/math.js @@ -0,0 +1,36 @@ +function update_board(f, o, s) { + $("#first").text(f); + $("#operation").text(o); + $("#second").text(s); +} + +function new_problem() { + $.get("/api/v0/problem/", function(d) { + update_board(d["first"], d["operation"], d["second"]); + $("#answer").val(""); + }) +} + +function deal_with_answer(e) { + var data = { + "first": $("#first").text(), + "operation": $("#operation").text(), + "second": $("#second").text(), + "answer": $("#answer").val(), + }; + console.log(data); + $.post("/api/v0/attempt/", data, function(d) { + if(d["status"]) { + $("#content").removeClass("wrong"); + new_problem(); + } + else { + $("#content").addClass("wrong"); + } + }); +} + +$(function() { + new_problem(); + $("#check").click(deal_with_answer); +}); diff --git a/templates/index.html b/templates/index.html index b991f7d..75bf2aa 100644 --- a/templates/index.html +++ b/templates/index.html @@ -7,21 +7,18 @@
-
- {% csrf_token %} -
- {{ form.first.value }} - {{ form.operation.value }} - {{ form.second.value }} -
- {{ form.first }} - {{ form.operation }} - {{ form.second }} - {{ form.answer }} - -
+
+ 0 + + + 0 +
+
+
+ +
+