Commit ee3c4813 by interrogator

basic json working

parent 3d48c11b
from django.shortcuts import render
from django.views import generic
from django.http import HttpResponse, JsonResponse
from wugsy.utils import REQUESTED, PROVIDED, _validator
from wugsy.decide import DecideGame
from rest_framework.decorators import api_view
# Create your views here.
class GamePage(generic.TemplateView):
template_name = "game.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
print(self.request.user)
return context
def _generate_game_data(given, user):
"""
From posted data, construct a new language game
"""
decider = DecideGame(given, user)
return decider.to_dict()
@api_view(['GET', 'POST'])
def generate_data(request):
"""
Get data for a new Game
"""
assert request.method == 'POST', 'Can only POST here'
given_data = request.data
user = request.user
out_data = _generate_game_data(given_data, user)
assert _validator(out_data, PROVIDED)
return JsonResponse(out_data)
from django.contrib import admin
# Register your models here.
from django.apps import AppConfig
class LangConfig(AppConfig):
name = 'lang'
from django.db import models
# Create your models here.
from django.test import TestCase
# Create your tests here.
from django.shortcuts import render
# Create your views here.
// pad numbers smaller than 10
function pad(n) {
return (n < 10) ? ("0" + n) : n;
}
// an abstract game class you can inherit from
function BaseGame() {
this.height = 100;
this.width = 100;
this.cards = {};
}
// game that follows the 00 rules
function Game00(gameData) {
BaseGame.call(this);
this.gameData = gameData;
console.log('Add game logic...')
$('#game-space').html('<h3>Game "' + gameData['game_title'] + '" here?</h3>');
}
Game00.prototype = Object.create(BaseGame.prototype);
// map game numbers to functions
var games = {'00': Game00}
// main method: lookup correct js
function buildGame(gameData) {
var gameType = gameData['game_type'];
var Game = games[pad(gameType)];
Game(gameData);
};
<li {% if active_link == "home" %}class="active"{% endif %}><a href="{% url 'home' %}">Home</a></li>
<li {% if active_link == "about" %}class="active"{% endif %}><a href="{% url 'about' %}">About</a></li>
<li {% if active_link == "about" %}class="active"{% endif %}><a href="{% url 'game' %}">Game</a></li>
<!DOCTYPE html>
<html lang="en">
{% load staticfiles %}
{% load thumbnail %}
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="{% block description %}{% endblock description %}">
<meta name="author" content="Arun Ravindran">
<link rel="shortcut icon" href="{% static 'site/ico/favicon.ico' %}">
<title>{% block title %}{% include "_brandname.html" %} :: {% endblock %}</title>
<!-- Bootstrap core CSS -->
<link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
<!-- Custom styles for this site -->
{% block styles %}
<script src="{% static 'site/js/jquery-3.2.1.min.js' %}"></script>
<link href="{% static 'site/css/main.css' %}" rel="stylesheet">
{% endblock styles %}
<!-- Custom tags for the head tag -->
{% block extrahead %}{% endblock extrahead %}
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
<body>
{% block navbar %}
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{% url 'home' %}">
{% block navbar-brand %}
<img src="{% static 'site/img/logo.png' %}" alt="logo">
{% include "_brandname.html" %}
{% endblock %}
</a>
</div>
{% block navbar-menu %}
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
{% block navbar-left %}{% endblock %}
</ul>
<ul class="nav navbar-nav navbar-right">
{% block navbar-right %}
{% if user.is_authenticated %}
{% if user.is_staff %}
<li><a href="{% url 'admin:index' %}">Admin</a></li>
{% endif %}
<li class="dropdown">
<a href="#" class="dropdown-toggle profile-menu" data-toggle="dropdown">
<img src="{% thumbnail user.profile.picture|default:'default_profile.png' 30x30 crop %}" alt="" />
{{ user.get_full_name|truncatechars:20 }}
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li><a href="{% url 'profiles:show_self' %}">Profile</a></li>
<li><a href="{% url 'accounts:logout' %}">Logout</a></li>
</ul>
</li>
{% endif %}
{% endblock %}
</ul>
</ul>
</div><!--/.nav-collapse -->
{% endblock %}
</div>
{% endblock navbar %}
{% block messages %}
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}"> <!-- singular -->
<a class="close" data-dismiss="alert">×</a>
{{ message|safe }}
</div>
{% endfor %}
{% endif %}
{% endblock %}
{% block splash %}
{% endblock splash %}
{% block container %}
<div class="container">
<div class="starter-template">
<h1>Game view</h1>
{% if not user.is_authenticated %}
<h2>Game for random user</h2>
{% else %}
<h2>Game for logged in user: {{user.get_full_name}}</h2>
{% endif %}
<form id="get-game" action = "/generate_data" method = "post">{% csrf_token %}
<input type="submit" name="Generate game" value="submit" />
</form>
<div id="json-space">JSON for a game will appear here</div>
<div id="game-space"></div>
</div>
</div><!-- /.container -->
{% endblock container %}
<!-- Site footer -->
{% block footer %}
<!-- Some social button for contact will do -->
<a name="contact"></a>
<div class="container">
<div class="footer">
<div class="row">
<div class="col-lg-6">
<p>&copy; Company {% now 'Y' %}</p>
</div>
<div class="col-lg-6 text-right">
Connect with us on
<a href="#"><i class="fa fa-facebook"></i> Facebook</a> or
<a href="#"><i class="fa fa-twitter"></i> Twitter</a>
</div>
</div>
</div>
</div>
{% endblock %}
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
<script src="{% static 'site/js/game.js' %}"></script>
{% block scripts %}
<script>
$('#get-game').submit(function(e){
e.preventDefault();
$.ajax({
url:"/generate_data",
type:'post',
data:$('#get-game').serialize(),
success:function(e){
console.log('Below is validated game JSON, which should be interpretable')
console.log(e);
// now, you can call the code that builds and inserts a game
buildGame(e)
// here, have the json on screen :)
$("#json-space").text(JSON.stringify(e));
}
});
});
</script>
{% endblock scripts %}
</body>
</html>
import random
class DecideGame(object):
"""
Class that generates a game from a request
Right now it just gives dummy data, but can be filled in with methods
that look things up in DB and decide
"""
def __init__(self, request, user):
self.request = request
self.user = user
self._nonce = random.randint(0, 10000)
self._type = self._get_type()
self._title = self._get_title()
self._opponent = self._get_opponent()
self._cards = self._get_cards()
self._concept_space = self._get_concept_space()
self._user_text_entry_field = self._get_user_text_entry_field()
self._user_info = self._get_user_info()
self._extra = self._get_extra()
def _get_type(self):
return 0
def _get_title(self):
return 'Prototype game {} for {}'.format(self._nonce, self.user.name)
def _get_opponent(self):
return dict(id=78,
username='fake-opponent',
score=1234,
picture='img.jpg')
def _get_cards(self):
out = list()
cards_for_games = {0: 25}
for i in range(0, cards_for_games.get(self._type, 16)):
out.append(dict(id=i,
colour='#ffffff',
card_text='dummy {}'.format(i),
reverse=None,
selected=False,
in_theme=True
))
return out
def _get_concept_space(self):
return dict(concept_text='Underlying concept',
colour='#0000ff',
hover_text='hovering')
def _get_user_text_entry_field(self):
return dict(placeholder='placeholder text here')
def _get_user_info(self):
return dict(id=321,
username='developer',
score=1246,
picture='img.jpg')
def _get_extra(self):
return None
def to_dict(self):
return dict(game_type=self._type,
game_title=self._title,
opponent=self._opponent,
cards=self._cards,
concept_space=self._concept_space,
user_text_entry_field=self._user_text_entry_field,
user_info=self._user_info,
extra=self._extra
)
......@@ -15,6 +15,7 @@ BASE_DIR = dirname(dirname(dirname(__file__)))
STATICFILES_DIRS = [join(BASE_DIR, 'static')]
MEDIA_ROOT = join(BASE_DIR, 'media')
MEDIA_URL = "/media/"
APPEND_SLASH=False
# Use Django templates using the new Django 1.8 TEMPLATES settings
TEMPLATES = [
......
......@@ -5,10 +5,13 @@ from django.conf.urls.static import static
import profiles.urls
import accounts.urls
from . import views
from game.views import GamePage, generate_data
urlpatterns = [
url(r'^$', views.HomePage.as_view(), name='home'),
url(r'^about/$', views.AboutPage.as_view(), name='about'),
url(r'^game/$', GamePage.as_view(), name='game'),
url(r'^generate_data$', generate_data, name='generate_data'),
url(r'^users/', include(profiles.urls, namespace='profiles')),
url(r'^admin/', include(admin.site.urls)),
url(r'^', include(accounts.urls, namespace='accounts')),
......
# validation scheme for frontend request for game data
REQUESTED = dict(
game_type=int,
time_remaining=float,
user_id=int,
opponent_id=int,
concept_space_text=str,
bad_game_selected=bool,
bad_game_feedback=dict(rating=int,
reason=str),
selected_cards=[int],
deleted_cards=[int],
card_order=[int]
)
# validation scheme for backend-generated game
PROVIDED = dict(
game_type=int,
game_title=str,
opponent=dict(id=int,
username=str,
score=int,
picture=str),
cards=[dict(id=int,
colour=str,
card_text=str,
reverse=None,
selected=bool,
in_theme=bool)],
concept_space=dict(concept_text=str,
colour=str,
hover_text=str),
user_text_entry_field=dict(placeholder=str),
user_info=dict(id=int,
username=str,
score=int,
picture=str),
extra=None
)
def _validator(data_to_check, schema):
"""
Check that data_to_check conforms to types in schema
"""
assert isinstance(data_to_check, dict), 'Data must be dict'
for field, expected_type in schema.items():
if expected_type is None:
continue
found = data_to_check.get(field)
msg = '{} {} is not type {}'.format(field, found, expected_type)
if isinstance(expected_type, type):
assert isinstance(found, expected_type), msg
else:
assert isinstance(found, type(expected_type)), msg
if isinstance(expected_type, dict):
#msg = '{} {} {} assertion fail'.format(expected_type, found, field)
assert _validator(found, expected_type), msg
elif isinstance(expected_type, list):
subschema = expected_type[0]
for item in found:
if isinstance(subschema, dict):
assert _validator(item, subschema)
elif isinstance(subschema, type):
assert isinstance(item, subschema)
else:
raise ValueError('List item must be dict or type')
return True
......@@ -4,6 +4,5 @@ from django.views import generic
class HomePage(generic.TemplateView):
template_name = "home.html"
class AboutPage(generic.TemplateView):
template_name = "about.html"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment