"""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)