3 # Copyright (C) 2013 FinalsClub Foundation
6 from django.contrib.auth.models import User
7 from django.db.models import Sum
8 from django.db.models.signals import post_save
9 from django.dispatch import receiver
10 from django.db import models, DatabaseError
11 from django.middleware.transaction import transaction
12 from karmaworld.apps.courses.models import School
14 logger = logging.getLogger(__name__)
17 class UserProfile(models.Model):
18 user = models.OneToOneField(User)
20 school = models.ForeignKey(School, blank=True, null=True)
24 for cls in ALL_KARMA_EVENT_CLASSES:
25 points = cls.objects.filter(user=self.user).aggregate(Sum('points'))['points__sum']
50 APPRENTICE: 'Apprentice',
63 points = self.get_points()
64 highest_badge = self.NO_BADGE
65 for badge in self.BADGES:
66 if points >= self.BADGE_THRESHOLDS[badge]:
69 if highest_badge is not self.NO_BADGE:
70 return self.BADGE_NAMES[highest_badge]
74 def __unicode__(self):
75 return self.user.__unicode__()
78 class BaseKarmaEvent(models.Model):
79 points = models.IntegerField()
80 user = models.ForeignKey(User)
81 timestamp = models.DateTimeField(default=datetime.datetime.utcnow)
86 def get_message(self):
87 raise NotImplemented()
90 class GenericKarmaEvent(BaseKarmaEvent):
91 message = models.CharField(max_length=255)
94 def create_event(user, message, points):
95 event = GenericKarmaEvent.objects.create(user=user,
100 def get_message(self):
104 class NoteKarmaEvent(BaseKarmaEvent):
107 NOTE_DELETED = 'deleted'
108 GIVE_FLAG = 'give_flag'
109 GET_FLAGGED = 'get_flagged'
110 EVENT_TYPE_CHOICES = (
111 (UPLOAD, "You uploaded a note"),
112 (THANKS, "You received a thanks for your note"),
113 (NOTE_DELETED, "Your note was deleted"),
114 (GIVE_FLAG, "You flagged a note"),
115 (GET_FLAGGED, "Your note was flagged as spam"),
117 note = models.ForeignKey('notes.Note')
118 event_type = models.CharField(max_length=15, choices=EVENT_TYPE_CHOICES)
128 def get_message(self):
129 return self.get_event_type_display()
131 def __unicode__(self):
132 return unicode(self.user) + ' -- ' + self.get_event_type_display() + ' -- ' + unicode(self.note)
135 def create_event(user, note, type):
136 event = NoteKarmaEvent.objects.create(user=user,
138 points=NoteKarmaEvent.POINTS[type],
143 class CourseKarmaEvent(BaseKarmaEvent):
144 GIVE_FLAG = 'give_flag'
145 EVENT_TYPE_CHOICES = (
146 (GIVE_FLAG, "You flagged a course"),
148 course = models.ForeignKey('courses.Course')
149 event_type = models.CharField(max_length=15, choices=EVENT_TYPE_CHOICES)
155 def get_message(self):
156 return self.get_event_type_display()
158 def __unicode__(self):
159 return unicode(self.user) + ' -- ' + self.get_event_type_display() + ' -- ' + unicode(self.course)
162 def create_event(user, course, type):
163 event = CourseKarmaEvent.objects.create(user=user,
165 points=CourseKarmaEvent.POINTS[type],
170 ALL_KARMA_EVENT_CLASSES = (GenericKarmaEvent, NoteKarmaEvent, CourseKarmaEvent)
173 def user_display_name(user):
174 """Return the best way to display a user's
175 name to them on the site."""
176 if hasattr(user, 'first_name') and user.first_name and \
177 hasattr(user, 'last_name') and user.last_name:
178 return user.first_name + ' ' + user.last_name
179 elif hasattr(user, 'email') and user.email:
185 @receiver(post_save, sender=User, weak=True)
186 def create_user_profile(sender, instance, created, **kwargs):
188 with transaction.commit_on_success():
190 UserProfile.objects.create(user=instance)
191 except DatabaseError:
192 logger.warn("Could not create UserProfile for user {u}. This is okay if running syncdb.".format(u=instance))