]> git.openstreetmap.org Git - osqa.git/blobdiff - forum/models/repute.py
ALteration of the schema to a single content model. As a bonus there is a complete...
[osqa.git] / forum / models / repute.py
old mode 100755 (executable)
new mode 100644 (file)
index a47ce47..4094351
-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'