3 # Copyright (C) 2013 FinalsClub Foundation
6 from allauth.account.signals import email_confirmed
7 from django.contrib.auth.models import User
8 from django.db.models import Sum
9 from django.db.models.signals import post_save
10 from django.dispatch import receiver
11 from django.db import models, DatabaseError
12 from django.middleware.transaction import transaction
13 from karmaworld.apps.courses.models import School
15 logger = logging.getLogger(__name__)
18 class UserProfile(models.Model):
19 user = models.OneToOneField(User)
21 school = models.ForeignKey(School, blank=True, null=True)
25 for cls in ALL_KARMA_EVENT_CLASSES:
26 points = cls.objects.filter(user=self.user).aggregate(Sum('points'))['points__sum']
51 APPRENTICE: 'Apprentice',
64 points = self.get_points()
65 highest_badge = self.NO_BADGE
66 for badge in self.BADGES:
67 if points >= self.BADGE_THRESHOLDS[badge]:
70 if highest_badge is not self.NO_BADGE:
71 return self.BADGE_NAMES[highest_badge]
75 def __unicode__(self):
76 return self.user.__unicode__()
79 @receiver(email_confirmed, weak=True)
80 def give_email_confirm_karma(sender, **kwargs):
81 GenericKarmaEvent.create_event(kwargs['email_address'].user, kwargs['email_address'].email, GenericKarmaEvent.EMAIL_CONFIRMED)
84 class BaseKarmaEvent(models.Model):
85 points = models.IntegerField()
86 user = models.ForeignKey(User)
87 timestamp = models.DateTimeField(default=datetime.datetime.utcnow)
92 def get_message(self):
93 raise NotImplemented()
96 class GenericKarmaEvent(BaseKarmaEvent):
98 NOTE_DELETED = 'upload'
99 EMAIL_CONFIRMED = 'thanks'
101 EVENT_TYPE_CHOICES = (
102 (NONE, 'This should not happen'),
103 (NOTE_DELETED, 'Your note "{m}" was deleted'),
104 (EMAIL_CONFIRMED, 'You confirmed your email address {m}'),
112 event_type = models.CharField(max_length=15, choices=EVENT_TYPE_CHOICES, default=NONE)
113 message = models.CharField(max_length=255)
116 def create_event(user, message, type):
117 event = GenericKarmaEvent.objects.create(user=user,
118 points=GenericKarmaEvent.POINTS[type],
123 def get_message(self):
124 if self.event_type == self.NONE:
127 return self.get_event_type_display().format(m=self.message)
129 def __unicode__(self):
130 return unicode(self.user) + ' -- ' + self.get_message()
133 class NoteKarmaEvent(BaseKarmaEvent):
136 NOTE_DELETED = 'deleted'
137 GIVE_FLAG = 'give_flag'
138 GET_FLAGGED = 'get_flagged'
139 EVENT_TYPE_CHOICES = (
140 (UPLOAD, "You uploaded a note"),
141 (THANKS, "You received a thanks for your note"),
142 (NOTE_DELETED, "Your note was deleted"),
143 (GIVE_FLAG, "You flagged a note"),
144 (GET_FLAGGED, "Your note was flagged as spam"),
146 note = models.ForeignKey('notes.Note')
147 event_type = models.CharField(max_length=15, choices=EVENT_TYPE_CHOICES)
157 def get_message(self):
158 return self.get_event_type_display()
160 def __unicode__(self):
161 return unicode(self.user) + ' -- ' + self.get_event_type_display() + ' -- ' + unicode(self.note)
164 def create_event(user, note, type):
165 event = NoteKarmaEvent.objects.create(user=user,
167 points=NoteKarmaEvent.POINTS[type],
172 class CourseKarmaEvent(BaseKarmaEvent):
173 GIVE_FLAG = 'give_flag'
174 EVENT_TYPE_CHOICES = (
175 (GIVE_FLAG, "You flagged a course"),
177 course = models.ForeignKey('courses.Course')
178 event_type = models.CharField(max_length=15, choices=EVENT_TYPE_CHOICES)
184 def get_message(self):
185 return self.get_event_type_display()
187 def __unicode__(self):
188 return unicode(self.user) + ' -- ' + self.get_event_type_display() + ' -- ' + unicode(self.course)
191 def create_event(user, course, type):
192 event = CourseKarmaEvent.objects.create(user=user,
194 points=CourseKarmaEvent.POINTS[type],
199 ALL_KARMA_EVENT_CLASSES = (GenericKarmaEvent, NoteKarmaEvent, CourseKarmaEvent)
202 def user_display_name(user):
203 """Return the best way to display a user's
204 name to them on the site."""
205 if hasattr(user, 'first_name') and user.first_name and \
206 hasattr(user, 'last_name') and user.last_name:
207 return user.first_name + ' ' + user.last_name
208 elif hasattr(user, 'email') and user.email:
214 @receiver(post_save, sender=User, weak=True)
215 def create_user_profile(sender, instance, created, **kwargs):
217 with transaction.commit_on_success():
219 UserProfile.objects.create(user=instance)
220 except DatabaseError:
221 logger.warn("Could not create UserProfile for user {u}. This is okay if running syncdb.".format(u=instance))