#!/usr/bin/env python3 """ The main quest models. """ from django.db import models from django.conf import settings from django.core.validators import MaxValueValidator, MinValueValidator from taggit.managers import TaggableManager class Quest(models.Model): """ The meta quest object. Contains general information about the quest. """ title = models.CharField(max_length=100) owner = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE) anon_name = models.CharField(max_length=20, default="Anonymous") live = models.BooleanField(default=False) live_time = models.DateTimeField(blank=True, null=True) tags = TaggableManager() anonymize = models.BooleanField(default=True) description = models.CharField(max_length=256, blank=True, null=True) latest_post_date = models.DateTimeField(null=True, blank=True) def update_post_date(self): try: latest_post = self.post_set.order_by('-timestamp')[0] self.latest_post_date = latest_post.timestamp self.save() except: pass # no posts yet class Message(models.Model): """ Represents a chat message. """ quest = models.ForeignKey(Quest, on_delete=models.CASCADE) user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True) timestamp = models.DateTimeField(auto_now=True) message = models.TextField(max_length=512) class Page(models.Model): """ Represents the title of a quest page. """ quest = models.ForeignKey(Quest, on_delete=models.CASCADE) page_num = models.CharField(max_length=4) title = models.CharField(max_length=200) appendix = models.BooleanField() def __str__(self): return self.title class Post(models.Model): """ An object for arbituary posts. Contains all post data, type, etc. """ quest = models.ForeignKey(Quest, on_delete=models.CASCADE) page = models.ForeignKey(Page, on_delete=models.CASCADE) POST_TYPES = ( ('text', 'Text'), ('dice', 'Dice'), ('poll', 'Poll') ) post_type = models.CharField(max_length=4, choices=POST_TYPES) post_text = models.TextField() timestamp = models.DateTimeField(auto_now=True) def save(self, **kwargs): super(Post, self).save(**kwargs) self.quest.update_post_date() def delete(self): super(Post, self).delete() self.quest.update_post_date() class DiceCall(models.Model): """ An object representing dice calls made by the QM. """ post = models.OneToOneField( Post, on_delete=models.CASCADE, primary_key=True, ) dice_roll = models.CharField(max_length=16) strict = models.BooleanField() dice_challenge = models.IntegerField( null=True, blank=True, validators=[ MinValueValidator(1), MaxValueValidator(65536), ] ) rolls_taken = models.IntegerField( null=True, blank=True, validators=[ MinValueValidator(1), MaxValueValidator(256), ] ) open = models.BooleanField() class DiceRoll(models.Model): """ Represents a dice roll made on a valid dicecall. """ dicecall = models.ForeignKey(DiceCall, on_delete=models.CASCADE) message = models.OneToOneField( Message, on_delete=models.CASCADE, primary_key=True, ) roll = models.CharField(max_length=16) results = models.TextField() total = models.IntegerField() class Poll(models.Model): """ An object representing polls made by the QM. """ post = models.OneToOneField( Post, on_delete=models.CASCADE, primary_key=True, ) multi_choice = models.BooleanField() allow_writein = models.BooleanField() open = models.BooleanField() class PollOption(models.Model): """ Represents options (choices) attached to a given poll. These can be added by the QM upon creation, or by users through write-ins. """ poll = models.ForeignKey(Poll, on_delete=models.CASCADE) text = models.CharField(max_length=200) class PollVote(models.Model): """ Represents a user voting for an option. """ option = models.ForeignKey(PollOption, on_delete=models.CASCADE) user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True) ip_address = models.GenericIPAddressField() class Meta: unique_together = ('option', 'ip_address')