Web: add an app for storycraft, mainly for viewing completed games at the moment
This commit is contained in:
parent
91b276ece5
commit
632a3f5e99
|
@ -99,12 +99,13 @@ INSTALLED_APPS = (
|
|||
#'django.contrib.contenttypes',
|
||||
#'django.contrib.sessions',
|
||||
#'django.contrib.sites',
|
||||
#'django.contrib.messages',
|
||||
'django.contrib.messages',
|
||||
# Uncomment the next line to enable the admin:
|
||||
#'django.contrib.admin',
|
||||
# Uncomment the next line to enable admin documentation:
|
||||
# 'django.contrib.admindocs',
|
||||
'karma',
|
||||
'storycraft',
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
* {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #333333;
|
||||
background: #efefef;
|
||||
font-family: 'Bitstream Vera Sans', sans-serif;
|
||||
font-size: 10pt;
|
||||
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#container {
|
||||
background: white;
|
||||
min-height: 100%;
|
||||
border-left: 1px solid #666666;
|
||||
border-right: 1px solid #666666;
|
||||
width: 85%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
#messages {
|
||||
background: white;
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
#messages .messagelist .error {
|
||||
list-style-type: none;
|
||||
color: red;
|
||||
}
|
||||
|
||||
#mainpage {
|
||||
padding: 5px;
|
||||
|
||||
overflow: auto;
|
||||
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
#mainpage #title {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
#mainpage #title h1 {
|
||||
font-family: 'Cardo', 'Times New Roman', serif;
|
||||
font-size: 32pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.gameitem {
|
||||
margin: 10px;
|
||||
border: 1px solid #999999;
|
||||
}
|
||||
|
||||
.gameitem .gameinfo {
|
||||
padding: 0px;
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.gameitem .gameplayers {
|
||||
padding: 5px;
|
||||
border: 1px solid #e0e0e0;
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.gameitem .gameinfo li {
|
||||
padding: 5px;
|
||||
display: table-cell;
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.gameitem .gameplayers li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.gameitem .gameplayers li:before {
|
||||
content: ", ";
|
||||
}
|
||||
.gameitem .gameplayers li:first-child:before {
|
||||
content: "Players: ";
|
||||
}
|
||||
|
||||
.gameitem .gameinfo li.gameid {
|
||||
width: 30%;
|
||||
background: #e0e0e0;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.gameitem .gameinfo li.gamestatus {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.gameitem .gameinfo li.gamecode {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.gameitem a {
|
||||
color: #333333;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.storyblock {
|
||||
border: 1px solid #e0e0e0;
|
||||
margin: 0px 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.storyblock p:first-letter {
|
||||
font-size: 3.5em;
|
||||
line-height: 0.8em;
|
||||
float: left;
|
||||
margin: 0 3px 3px 0;
|
||||
}
|
||||
|
||||
.gamestory {
|
||||
font-family: 'Cardo', 'Times New Roman', serif;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
#footer {
|
||||
position: relative;
|
||||
margin-top: -50px;
|
||||
height: 50px;
|
||||
clear: both;
|
||||
|
||||
text-align: center;
|
||||
|
||||
background: #333333;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
#footer p {
|
||||
padding-top: 10px;
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
/*
|
||||
vi:tabstop=4:expandtab:autoindent
|
||||
*/
|
|
@ -0,0 +1,64 @@
|
|||
from django.db import models
|
||||
|
||||
class StorycraftGame(models.Model):
|
||||
id = models.IntegerField(primary_key=True)
|
||||
round_mode = models.IntegerField()
|
||||
game_length = models.IntegerField()
|
||||
line_length = models.IntegerField()
|
||||
random_method = models.IntegerField()
|
||||
lines_per_turn = models.IntegerField()
|
||||
status = models.CharField()
|
||||
owner_nick = models.CharField()
|
||||
owner_userhost = models.CharField()
|
||||
start_time = models.DateTimeField()
|
||||
end_time = models.DateTimeField()
|
||||
|
||||
class Meta:
|
||||
db_table = 'storycraft_game'
|
||||
ordering = ['id']
|
||||
managed = False
|
||||
|
||||
def __unicode__(self):
|
||||
"""Return a terse summary of the vital game info."""
|
||||
|
||||
return '#{0:d} - created on {1:s} by {2:s}, {3:s}'.format(self.id, self.start_time, self.owner_nick, self.status)
|
||||
|
||||
def is_completed(self):
|
||||
"""Return if this game is completed."""
|
||||
|
||||
return self.status == 'COMPLETED' and self.end_time
|
||||
|
||||
class StorycraftPlayer(models.Model):
|
||||
id = models.IntegerField(primary_key=True)
|
||||
game = models.ForeignKey(StorycraftGame)
|
||||
nick = models.CharField()
|
||||
userhost = models.CharField()
|
||||
|
||||
class Meta:
|
||||
db_table = 'storycraft_player'
|
||||
ordering = ['id']
|
||||
managed = False
|
||||
|
||||
def __unicode__(self):
|
||||
"""Return the nick!user@host."""
|
||||
|
||||
return '{0:s}!{1:s}'.format(self.nick, self.userhost)
|
||||
|
||||
class StorycraftLine(models.Model):
|
||||
id = models.IntegerField(primary_key=True)
|
||||
game = models.ForeignKey(StorycraftGame)
|
||||
player = models.ForeignKey(StorycraftPlayer)
|
||||
line = models.TextField()
|
||||
time = models.DateTimeField()
|
||||
|
||||
class Meta:
|
||||
db_table = 'storycraft_line'
|
||||
ordering = ['id']
|
||||
managed = False
|
||||
|
||||
def __unicode__(self):
|
||||
"""Just return the line."""
|
||||
|
||||
return '{0:s}'.format(self.line)
|
||||
|
||||
# vi:tabstop=4:expandtab:autoindent
|
|
@ -0,0 +1,8 @@
|
|||
from django.conf.urls.defaults import *
|
||||
|
||||
urlpatterns = patterns('storycraft.views',
|
||||
(r'^$', 'index'),
|
||||
(r'^games/(?P<game_id>\d+)/$', 'game_index', dict(), 'game_index'),
|
||||
)
|
||||
|
||||
# vi:tabstop=4:expandtab:autoindent
|
|
@ -0,0 +1,30 @@
|
|||
from django.contrib import messages
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.template import RequestContext
|
||||
|
||||
from storycraft.models import StorycraftGame, StorycraftLine, StorycraftPlayer
|
||||
|
||||
def index(request):
|
||||
"""Display a short list of each game (and its summary) in the system.
|
||||
|
||||
TODO: add paginator.
|
||||
"""
|
||||
|
||||
games = StorycraftGame.objects.all()
|
||||
return render_to_response('storycraft/index.html', {'games': games}, context_instance=RequestContext(request))
|
||||
|
||||
def game_index(request, game_id):
|
||||
"""Display one individual game's details, including the story, if it's done."""
|
||||
|
||||
game = get_object_or_404(StorycraftGame, pk=game_id)
|
||||
players = StorycraftPlayer.objects.filter(game=game.id)
|
||||
lines = []
|
||||
|
||||
if game.is_completed():
|
||||
lines = StorycraftLine.objects.filter(game=game.id)
|
||||
|
||||
return render_to_response('storycraft/game_index.html', {'game': game, 'players': players, 'lines': lines}, context_instance=RequestContext(request))
|
||||
|
||||
# vi:tabstop=4:expandtab:autoindent
|
|
@ -5,6 +5,9 @@
|
|||
<title>dr.botzo</title>
|
||||
</head>
|
||||
<body>
|
||||
<ul><li><a href="karma/">Karma</a></li></ul>
|
||||
<ul>
|
||||
<li><a href="karma/">Karma</a></li>
|
||||
<li><a href="storycraft/">Storycraft</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<link href='http://fonts.googleapis.com/css?family=Cardo&subset=latin' rel='stylesheet' type='text/css' />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>dr.botzo — Storycraft</title>
|
||||
<link rel="stylesheet" href="/static/storycraft/page.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
{% if messages %}
|
||||
<div id="messages">
|
||||
<ul class="messagelist">
|
||||
{% for message in messages %}
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div id="container">
|
||||
<div id="mainpage">
|
||||
<div id="title">
|
||||
<h1>Storycraft #{{ game.id }}</h1>
|
||||
</div>
|
||||
<div id="gamesummary">
|
||||
{% include 'storycraft/tmpl_game_summary.html' %}
|
||||
</div>
|
||||
{% include 'storycraft/tmpl_game_story.html' %}
|
||||
</div>
|
||||
</div>
|
||||
{% include 'storycraft/tmpl_footer.html' %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!--
|
||||
vi:tabstop=2:expandtab:autoindent
|
||||
-->
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<link href='http://fonts.googleapis.com/css?family=Cardo&subset=latin' rel='stylesheet' type='text/css' />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>dr.botzo — Storycraft</title>
|
||||
<link rel="stylesheet" href="/static/storycraft/page.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
{% if messages %}
|
||||
<div id="messages">
|
||||
<ul class="messagelist">
|
||||
{% for message in messages %}
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div id="container">
|
||||
<div id="mainpage">
|
||||
<div id="title">
|
||||
<h1>Storycraft</h1>
|
||||
</div>
|
||||
<div id="gamelist">
|
||||
{% if games %}
|
||||
{% for game in games %}
|
||||
{% include 'storycraft/tmpl_game_summary.html' %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p>No storycraft games. :(</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% include 'storycraft/tmpl_footer.html' %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!--
|
||||
vi:tabstop=2:expandtab:autoindent
|
||||
-->
|
|
@ -0,0 +1,7 @@
|
|||
<div id="footer">
|
||||
<p>Storycraft is a game of collaborative storytelling, intentionally leading to much insanity and nonsense. All stories were made to be funny but may not even be coherent. Void where prohibited.</p>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
vi:tabstop=2:expandtab:autoindent
|
||||
-->
|
|
@ -0,0 +1,19 @@
|
|||
<div class="storyblock">
|
||||
{% if game.is_completed %}
|
||||
<div class="gamestory">
|
||||
<p>
|
||||
{% for line in lines %}
|
||||
<span title="{{ line.player.nick }} @ {{ line.time }}">{{ line }}</span>
|
||||
{% endfor %}
|
||||
</p>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="gamenostory">
|
||||
<p>This game has not been completed yet. Come back later (or get to work).</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!--
|
||||
vi:tabstop=2:expandtab:autoindent
|
||||
-->
|
|
@ -0,0 +1,18 @@
|
|||
<div class="gameitem">
|
||||
<ul class="gameinfo">
|
||||
<li class="gameid"><span><a href="{% url game_index game.id %}">{{ game.id }} — started by {{ game.owner_nick }}</a></span></li>
|
||||
<li class="gamestatus"><span>{{ game.status }}</span></li>
|
||||
<li class="gamecode"><span>o:{{ game.round_mode }}[{{ game.game_length }}],{{ game.line_length }},{{ game.random_method }},{{ game.lines_per_turn }}</span></li>
|
||||
</ul>
|
||||
{% if players %}
|
||||
<ul class="gameplayers">
|
||||
{% for player in players %}
|
||||
<li>{{ player.nick }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!--
|
||||
vi:tabstop=2:expandtab:autoindent
|
||||
-->
|
|
@ -8,6 +8,7 @@ urlpatterns = patterns(
|
|||
'',
|
||||
(r'^$', 'index.views.index'),
|
||||
(r'^karma/', include('karma.urls')),
|
||||
(r'^storycraft/', include('storycraft.urls')),
|
||||
# Example:
|
||||
# (r'^web/', include('web.foo.urls')),
|
||||
|
||||
|
|
Loading…
Reference in New Issue