-from base import *\r
-\r
-from django.utils.translation import ugettext as _\r
-\r
-class Badge(models.Model):\r
- """Awarded for notable actions performed on the site by Users."""\r
- GOLD = 1\r
- SILVER = 2\r
- BRONZE = 3\r
- TYPE_CHOICES = (\r
- (GOLD, _('gold')),\r
- (SILVER, _('silver')),\r
- (BRONZE, _('bronze')),\r
- )\r
-\r
- name = models.CharField(max_length=50)\r
- type = models.SmallIntegerField(choices=TYPE_CHOICES)\r
- slug = models.SlugField(max_length=50, blank=True)\r
- description = models.CharField(max_length=300)\r
- multiple = models.BooleanField(default=False)\r
- # Denormalised data\r
- awarded_count = models.PositiveIntegerField(default=0)\r
-\r
- awarded_to = models.ManyToManyField(User, through='Award', related_name='badges')\r
-\r
- class Meta:\r
- app_label = 'forum'\r
- db_table = u'badge'\r
- ordering = ('name',)\r
- unique_together = ('name', 'type')\r
-\r
- def __unicode__(self):\r
- return u'%s: %s' % (self.get_type_display(), self.name)\r
-\r
- def save(self, **kwargs):\r
- if not self.slug:\r
- self.slug = self.name#slugify(self.name)\r
- super(Badge, self).save(**kwargs)\r
-\r
- def get_absolute_url(self):\r
- return '%s%s/' % (reverse('badge', args=[self.id]), self.slug)\r
-\r
-class AwardManager(models.Manager):\r
- def get_recent_awards(self):\r
- awards = super(AwardManager, self).extra(\r
- select={'badge_id': 'badge.id', 'badge_name':'badge.name',\r
- 'badge_description': 'badge.description', 'badge_type': 'badge.type',\r
- 'user_id': 'auth_user.id', 'user_name': 'auth_user.username'\r
- },\r
- tables=['award', 'badge', 'auth_user'],\r
- order_by=['-awarded_at'],\r
- where=['auth_user.id=award.user_id AND badge_id=badge.id'],\r
- ).values('badge_id', 'badge_name', 'badge_description', 'badge_type', 'user_id', 'user_name')\r
- return awards\r
-\r
-class Award(models.Model):\r
- """The awarding of a Badge to a User."""\r
- user = models.ForeignKey(User, related_name='award_user')\r
- badge = models.ForeignKey('Badge', related_name='award_badge')\r
- content_type = models.ForeignKey(ContentType)\r
- object_id = models.PositiveIntegerField()\r
- content_object = generic.GenericForeignKey('content_type', 'object_id')\r
- awarded_at = models.DateTimeField(default=datetime.datetime.now)\r
- notified = models.BooleanField(default=False)\r
-\r
- objects = AwardManager()\r
-\r
- def __unicode__(self):\r
- return u'[%s] is awarded a badge [%s] at %s' % (self.user.username, self.badge.name, self.awarded_at)\r
-\r
- class Meta:\r
- app_label = 'forum'\r
- db_table = u'award'\r
-\r
-class ReputeManager(models.Manager):\r
- def get_reputation_by_upvoted_today(self, user):\r
- """\r
- For one user in one day, he can only earn rep till certain score (ep. +200)\r
- by upvoted(also substracted from upvoted canceled). This is because we need\r
- to prohibit gaming system by upvoting/cancel again and again.\r
- """\r
- if user is not None:\r
- today = datetime.date.today()\r
- sums = self.filter(models.Q(reputation_type=1) | models.Q(reputation_type=-8),\r
- user=user, reputed_at__range=(today, today + datetime.timedelta(1))). \\r
- agregate(models.Sum('positive'), models.Sum('negative')) \r
-\r
- return sums['positive__sum'] + sums['negative__sum']\r
- else:\r
- return 0\r
-\r
-class Repute(models.Model):\r
- """The reputation histories for user"""\r
- user = models.ForeignKey(User)\r
- positive = models.SmallIntegerField(default=0)\r
- negative = models.SmallIntegerField(default=0)\r
- question = models.ForeignKey('Question')\r
- reputed_at = models.DateTimeField(default=datetime.datetime.now)\r
- reputation_type = models.SmallIntegerField(choices=TYPE_REPUTATION)\r
- reputation = models.IntegerField(default=1)\r
- \r
- objects = ReputeManager()\r
-\r
- def __unicode__(self):\r
- return u'[%s]\' reputation changed at %s' % (self.user.username, self.reputed_at)\r
-\r
- class Meta:\r
- app_label = 'forum'\r
- db_table = u'repute'\r
+from base import *
+from django.contrib.contenttypes.models import ContentType
+from forum.models import User
+
+from django.utils.translation import ugettext as _
+
+class Badge(BaseModel):
+ """Awarded for notable actions performed on the site by Users."""
+ GOLD = 1
+ SILVER = 2
+ BRONZE = 3
+ TYPE_CHOICES = (
+ (GOLD, _('gold')),
+ (SILVER, _('silver')),
+ (BRONZE, _('bronze')),
+ )
+
+ name = models.CharField(max_length=50)
+ type = models.SmallIntegerField(choices=TYPE_CHOICES)
+ slug = models.SlugField(max_length=50, blank=True)
+ description = models.CharField(max_length=300)
+ multiple = models.BooleanField(default=False)
+ # Denormalised data
+ awarded_count = models.PositiveIntegerField(default=0)
+ awarded_to = models.ManyToManyField(User, through='Award', related_name='badges')
+
+ class Meta:
+ app_label = 'forum'
+ db_table = u'badge'
+ ordering = ('name',)
+ unique_together = ('name', 'type')
+
+ def __unicode__(self):
+ return u'%s: %s' % (self.get_type_display(), self.name)
+
+ def save(self, *args, **kwargs):
+ if not self.slug:
+ self.slug = self.name#slugify(self.name)
+ super(Badge, self).save(*args, **kwargs)
+
+ def get_absolute_url(self):
+ return '%s%s/' % (reverse('badge', args=[self.id]), self.slug)
+
+
+class AwardManager(models.Manager):
+ def get_recent_awards(self):
+ awards = super(AwardManager, self).extra(
+ select={'badge_id': 'badge.id', 'badge_name':'badge.name',
+ 'badge_description': 'badge.description', 'badge_type': 'badge.type',
+ 'user_id': 'auth_user.id', 'user_name': 'auth_user.username'
+ },
+ tables=['award', 'badge', 'auth_user'],
+ order_by=['-awarded_at'],
+ where=['auth_user.id=award.user_id AND badge_id=badge.id'],
+ ).values('badge_id', 'badge_name', 'badge_description', 'badge_type', 'user_id', 'user_name')
+ return awards
+
+class Award(GenericContent, UserContent):
+ """The awarding of a Badge to a User."""
+ badge = models.ForeignKey('Badge', related_name='award_badge')
+ awarded_at = models.DateTimeField(default=datetime.datetime.now)
+ notified = models.BooleanField(default=False)
+
+ objects = AwardManager()
+
+ def __unicode__(self):
+ return u'[%s] is awarded a badge [%s] at %s' % (self.user.username, self.badge.name, self.awarded_at)
+
+ def save(self, *args, **kwargs):
+ super(Award, self).save(*args, **kwargs)
+
+ if self._is_new:
+ self.badge.awarded_count += 1
+ self.badge.save()
+
+ if self.badge.type == Badge.GOLD:
+ self.user.gold += 1
+ if self.badge.type == Badge.SILVER:
+ self.user.silver += 1
+ if self.badge.type == Badge.BRONZE:
+ self.user.bronze += 1
+ self.user.save()
+
+ class Meta:
+ unique_together = ('content_type', 'object_id', 'user', 'badge')
+ app_label = 'forum'
+ db_table = u'award'
+
+
+class Repute(UserContent):
+ """The reputation histories for user"""
+ value = models.SmallIntegerField(default=0)
+ question = models.ForeignKey('Question')
+ reputed_at = models.DateTimeField(default=datetime.datetime.now)
+ reputation_type = models.SmallIntegerField(choices=TYPE_REPUTATION)
+ user_previous_rep = models.IntegerField(default=0)
+
+ def __unicode__(self):
+ return u'[%s]\' reputation changed at %s' % (self.user.username, self.reputed_at)
+
+ @property
+ def positive(self):
+ if self.value > 0: return self.value
+ return 0
+
+ @property
+ def negative(self):
+ if self.value < 0: return self.value
+ return 0
+
+ @property
+ def reputation(self):
+ return self.user_previous_rep + self.value
+
+ def save(self, *args, **kwargs):
+ self.user_previous_rep = self.user.reputation
+ self.user.reputation = self.user.reputation + self.value
+ self.user.save()
+ super(Repute, self).save(*args, **kwargs)
+
+ class Meta:
+ app_label = 'forum'
+ db_table = u'repute'