]> git.openstreetmap.org Git - osqa.git/blob - forum/models/repute.py
initial import
[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(MetaContent, 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(UserContent):
91     """The reputation histories for user"""
92     value    = models.SmallIntegerField(default=0)
93     question = models.ForeignKey('Question')
94     reputed_at = models.DateTimeField(default=datetime.datetime.now)
95     reputation_type = models.SmallIntegerField(choices=TYPE_REPUTATION)
96     user_previous_rep = models.IntegerField(default=0)
97
98     def __unicode__(self):
99         return u'[%s]\' reputation changed at %s' % (self.user.username, self.reputed_at)
100
101     @property
102     def positive(self):
103         if self.value > 0: return self.value
104         return 0
105
106     @property
107     def negative(self):
108         if self.value < 0: return self.value
109         return 0
110
111     @property
112     def reputation(self):
113         return self.user_previous_rep + self.value
114
115     def save(self, *args, **kwargs):
116         self.user_previous_rep = self.user.reputation
117         self.user.reputation = self.user.reputation + self.value
118         self.user.save()
119         super(Repute, self).save(*args, **kwargs)
120
121     class Meta:
122         app_label = 'forum'
123         db_table = u'repute'