Source code for apps.widgets.quests.models
"""Defines the Quest Model."""
import datetime
from django.conf import settings
from django.db import models
from django.contrib.auth.models import User
from apps.managers.cache_mgr import cache_mgr
from apps.managers.score_mgr import score_mgr
from apps.managers.predicate_mgr import predicate_mgr
[docs]class Quest(models.Model):
"""Represents a quest in the database."""
name = models.CharField(max_length=255, help_text="The name of the quest.")
quest_slug = models.SlugField(help_text="A unique identifier of the quest. Automatically "
"generated if left blank.")
description = models.TextField(
help_text="Discription of the quest. It should outline the steps to completing"
" this quest. %s" % settings.MARKDOWN_TEXT)
priority = models.IntegerField(
default=1,
help_text="Quest with lower values (higher priority) will be listed first."
)
unlock_conditions = models.TextField(
help_text="Conditions a user needs to meet in order to have this quest be"
" available (appeared in the Quest widget). " +
settings.PREDICATE_DOC_TEXT
)
completion_conditions = models.TextField(
help_text="Conditions a user needs to meet in order to complete the quest. " +
settings.PREDICATE_DOC_TEXT
)
users = models.ManyToManyField(User, through="QuestMember")
def __unicode__(self):
return self.name
[docs] def can_add_quest(self, user):
"""Returns True if the user can add the quest."""
return predicate_mgr.eval_predicates(self.unlock_conditions, user)
[docs] def completed_quest(self, user):
"""Returns True if the user completed the quest."""
return predicate_mgr.eval_predicates(self.completion_conditions, user)
[docs] def accept(self, user):
"""Lets the user accept the quest. Returns True if successful."""
# Check if user can add the quest.
if not self.can_add_quest(user):
return False
# Check if this quest is in their list of quests.
if self in user.quest_set.all():
return False
member = QuestMember(quest=self, user=user)
member.save()
return True
[docs] def opt_out(self, user):
"""Lets the user opt out of seeing the quest. Returns True if successful."""
# Check if user can add the quest.
if not self.can_add_quest(user):
return False
# Note in this case, we don't care if the user already has the quest.
member, _ = QuestMember.objects.get_or_create(quest=self, user=user)
member.opt_out = True
member.save()
return True
[docs]class QuestMember(models.Model):
"""Represents a user's participation in a quest.
Shouldn't be in the admin interface, since there shouldn't be a reason to edit instances."""
user = models.ForeignKey(User)
quest = models.ForeignKey(Quest)
completed = models.BooleanField(default=False,
help_text="True if the user completed the quest.")
opt_out = models.BooleanField(default=False,
help_text="True if the user opts out of the quest.")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
"""meta"""
unique_together = ["user", "quest"]
[docs] def save(self, *args, **kwargs):
"""Custom save method to create a points transaction after the object is saved."""
super(QuestMember, self).save(*args, **kwargs)
if self.completed:
message = "Quest: %s" % self.quest.name
self.user.profile.add_points(score_mgr.quest_points(),
datetime.datetime.today(), message, self)
cache_mgr.delete('get_quests-%s' % self.user.username)
[docs] def delete(self, *args, **kwargs):
"""Custom delete method."""
cache_mgr.delete('get_quests-%s' % self.user.username)
super(QuestMember, self).delete(*args, **kwargs)