Web: add an app for storycraft, mainly for viewing completed games at the moment

This commit is contained in:
Brian S. Stephan 2011-02-20 11:32:17 -06:00
parent 91b276ece5
commit 632a3f5e99
13 changed files with 382 additions and 2 deletions

View File

@ -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__":

View File

@ -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
*/

View File

64
web/storycraft/models.py Normal file
View File

@ -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

8
web/storycraft/urls.py Normal file
View File

@ -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

30
web/storycraft/views.py Normal file
View File

@ -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

View File

@ -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>

View File

@ -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&amp;subset=latin' rel='stylesheet' type='text/css' />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>dr.botzo &mdash; 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
-->

View File

@ -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&amp;subset=latin' rel='stylesheet' type='text/css' />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>dr.botzo &mdash; 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
-->

View File

@ -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
-->

View File

@ -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
-->

View File

@ -0,0 +1,18 @@
<div class="gameitem">
<ul class="gameinfo">
<li class="gameid"><span><a href="{% url game_index game.id %}">{{ game.id }} &mdash; 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
-->

View File

@ -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')),