dr.botzo/storycraft/models.py

115 lines
4.0 KiB
Python

"""Track storycraft games."""
import logging
from django.db import models
from django.utils import timezone
log = logging.getLogger('storycraft.models')
class StorycraftGame(models.Model):
"""Contain entire games of storycraft."""
STATUS_OPEN = 'OPEN'
STATUS_IN_PROGRESS = 'IN PROGRESS'
STATUS_COMPLETED = 'COMPLETED'
STATUS_CHOICES = (
(STATUS_OPEN, "OPEN"),
(STATUS_IN_PROGRESS, "IN PROGRESS"),
(STATUS_COMPLETED, "COMPLETED"),
)
game_length = models.PositiveSmallIntegerField()
line_length = models.PositiveSmallIntegerField()
lines_per_turn = models.PositiveSmallIntegerField()
status = models.CharField(max_length=16, choices=STATUS_CHOICES, default=STATUS_OPEN)
owner_nick = models.CharField(max_length=64)
owner_nickmask = models.CharField(max_length=200)
create_time = models.DateTimeField(auto_now_add=True)
start_time = models.DateTimeField(null=True)
end_time = models.DateTimeField(null=True)
def __str__(self):
"""String representation."""
return "Storycraft game {0:d}: {1:s}; {2:s}".format(self.pk, self.summary(), self.get_progress_string())
def get_progress_string(self):
"""Get a terse summary of the game's progress."""
lines = self.get_lines()
num_lines = len(lines)
if self.status == StorycraftGame.STATUS_IN_PROGRESS:
num_lines -= 1
if num_lines == self.game_length - 1:
last_line = ' LAST LINE'
else:
last_line = ''
progress = "lines: {0:d}/{1:d}{2:s}".format(num_lines, self.game_length, last_line)
return progress
def get_lines(self):
"""Get the lines for the game."""
return self.lines.order_by('-time')
def summary(self):
"""Display game info for a general summary."""
status_str = "#{0:d} - created on {1:s} by {2:s}, {3:s}".format(self.id,
timezone.localtime(self.create_time).strftime('%Y-%m-%d %H:%M:%S %Z'),
self.owner_nick, self.status)
if self.status == StorycraftGame.STATUS_COMPLETED and self.end_time:
status_str = status_str + ' ({0:s})'.format(self.end_time.strftime('%Y/%m/%d %H:%M:%S'))
elif self.status == StorycraftGame.STATUS_IN_PROGRESS:
lines = self.get_lines()
player = self._get_player_by_id(lines[0].player_id)
status_str = status_str + ' ({0:d} lines, next is {1:s})'.format(len(lines)-1, player.nick)
# get players in game
player_names = []
for player in self.players.all():
player_names.append(player.nick)
status_str = status_str + ', players: {0:s}'.format(', '.join(player_names))
status_str = status_str + "; [o:{0:d}[{1:d}],{2:d}]".format(self.game_length, self.line_length,
self.lines_per_turn)
return status_str
class StorycraftPlayer(models.Model):
"""Contain entire games of storycraft."""
game = models.ForeignKey('StorycraftGame', related_name='players', on_delete=models.CASCADE)
nick = models.CharField(max_length=64)
nickmask = models.CharField(max_length=200)
def __str__(self):
"""String representation."""
return "{0:s} in storycraft game {1:d}".format(self.nick, self.game.pk)
class StorycraftLine(models.Model):
"""Handle requests to dispatchers and do something with them."""
game = models.ForeignKey('StorycraftGame', related_name='lines', on_delete=models.CASCADE)
player = models.ForeignKey('StorycraftPlayer', related_name='lines', on_delete=models.CASCADE)
line = models.TextField(default="")
time = models.DateTimeField(auto_now_add=True)
def __str__(self):
"""String representation."""
return "line by {0:s} in storycraft game {1:d}".format(self.player.nick, self.game.pk)