]> git.openstreetmap.org Git - osqa.git/blob - forum/models/repute.py
OSQA - 19
[osqa.git] / forum / models / repute.py
1 from base import *
2 from django.contrib.contenttypes.models import ContentType
3 from forum.models import User
4
5 from django.utils.translation import ugettext as _
6
7 class Badge(BaseModel):
8     """Awarded for notable actions performed on the site by Users."""
9     GOLD = 1
10     SILVER = 2
11     BRONZE = 3
12     TYPE_CHOICES = (
13         (GOLD,   _('gold')),
14         (SILVER, _('silver')),
15         (BRONZE, _('bronze')),
16     )
17
18     name        = models.CharField(max_length=50)
19     type        = models.SmallIntegerField(choices=TYPE_CHOICES)
20     slug        = models.SlugField(max_length=50, blank=True)
21     description = models.CharField(max_length=300)
22     multiple    = models.BooleanField(default=False)
23     # Denormalised data
24     awarded_count = models.PositiveIntegerField(default=0)
25     awarded_to    = models.ManyToManyField(User, through='Award', related_name='badges')
26
27     class Meta:
28         app_label = 'forum'
29         db_table = u'badge'
30         ordering = ('name',)
31         unique_together = ('name', 'type')
32
33     def __unicode__(self):
34         return u'%s: %s' % (self.get_type_display(), self.name)
35
36     def save(self, *args, **kwargs):
37         if not self.slug:
38             self.slug = self.name#slugify(self.name)
39         super(Badge, self).save(*args, **kwargs)
40
41     def get_absolute_url(self):
42         return '%s%s/' % (reverse('badge', args=[self.id]), self.slug)
43
44
45 class AwardManager(models.Manager):
46     def get_recent_awards(self):
47         awards = super(AwardManager, self).extra(
48             select={'badge_id': 'badge.id', 'badge_name':'badge.name',
49                           'badge_description': 'badge.description', 'badge_type': 'badge.type',
50                           'user_id': 'auth_user.id', 'user_name': 'auth_user.username'
51                           },
52             tables=['award', 'badge', 'auth_user'],
53             order_by=['-awarded_at'],
54             where=['auth_user.id=award.user_id AND badge_id=badge.id'],
55         ).values('badge_id', 'badge_name', 'badge_description', 'badge_type', 'user_id', 'user_name')
56         return awards
57
58 class Award(GenericContent, UserContent):
59     """The awarding of a Badge to a User."""
60     badge      = models.ForeignKey('Badge', related_name='award_badge')
61     awarded_at = models.DateTimeField(default=datetime.datetime.now)
62     notified   = models.BooleanField(default=False)
63
64     objects = AwardManager()
65
66     def __unicode__(self):
67         return u'[%s] is awarded a badge [%s] at %s' % (self.user.username, self.badge.name, self.awarded_at)
68
69     def save(self, *args, **kwargs):
70         super(Award, self).save(*args, **kwargs)
71
72         if self._is_new:
73             self.badge.awarded_count += 1
74             self.badge.save()
75
76             if self.badge.type == Badge.GOLD:
77                 self.user.gold += 1
78             if self.badge.type == Badge.SILVER:
79                 self.user.silver += 1
80             if self.badge.type == Badge.BRONZE:
81                 self.user.bronze += 1
82             self.user.save()
83
84     class Meta:
85         #unique_together = ('content_type', 'object_id', 'user', 'badge')
86         app_label = 'forum'
87         db_table = u'award'
88
89
90 class Repute(MetaContent, CancelableContent, UserContent):
91     value    = models.SmallIntegerField(default=0)
92     question = models.ForeignKey('Question')
93     reputed_at = models.DateTimeField(default=datetime.datetime.now)
94     reputation_type = models.SmallIntegerField(choices=TYPE_REPUTATION)
95     user_previous_rep = models.IntegerField(default=0)
96
97     def __unicode__(self):
98         return u'[%s]\' reputation changed at %s' % (self.user.username, self.reputed_at)
99
100     @property
101     def positive(self):
102         if self.value > 0: return self.value
103         return 0
104
105     @property
106     def negative(self):
107         if self.value < 0: return self.value
108         return 0
109
110     @property
111     def reputation(self):
112         return self.user_previous_rep + self.value
113
114     def cancel(self):
115         if super(Repute, self).cancel():
116             self.user.reputation = self.user.reputation - self.value
117             self.user.save()
118
119     def save(self, *args, **kwargs):
120         self.user_previous_rep = self.user.reputation
121         self.user.reputation = self.user.reputation + self.value
122         self.user.save()
123         super(Repute, self).save(*args, **kwargs)
124
125     class Meta:
126         app_label = 'forum'
127         db_table = u'repute'