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]:
70 def __unicode__(self):
71 return self.user.__unicode__()
74 class BaseKarmaEvent(models.Model):
75 points = models.IntegerField()
76 user = models.ForeignKey(User)
77 timestamp = models.DateTimeField(default=datetime.datetime.utcnow)
82 def get_message(self):
83 raise NotImplemented()
86 class GenericKarmaEvent(BaseKarmaEvent):
87 message = models.CharField(max_length=255)
90 def create_event(user, message, points):
91 event = GenericKarmaEvent.objects.create(user=user,
96 def get_message(self):
100 class NoteKarmaEvent(BaseKarmaEvent):
103 NOTE_DELETED = 'deleted'
104 GIVE_FLAG = 'give_flag'
105 GET_FLAGGED = 'get_flagged'
106 EVENT_TYPE_CHOICES = (
107 (UPLOAD, "You uploaded a note"),
108 (THANKS, "You received a thanks for your note"),
109 (NOTE_DELETED, "Your note was deleted"),
110 (GIVE_FLAG, "You flagged a note"),
111 (GET_FLAGGED, "Your note was flagged as spam"),
113 note = models.ForeignKey('notes.Note')
114 event_type = models.CharField(max_length=15, choices=EVENT_TYPE_CHOICES)
124 def get_message(self):
125 return self.get_event_type_display()
127 def __unicode__(self):
128 return unicode(self.user) + ' -- ' + self.get_event_type_display() + ' -- ' + unicode(self.note)
131 def create_event(user, note, type):
132 event = NoteKarmaEvent.objects.create(user=user,
134 points=NoteKarmaEvent.POINTS[type],
139 class CourseKarmaEvent(BaseKarmaEvent):
140 GIVE_FLAG = 'give_flag'
141 GET_FLAGGED = 'get_flagged'
142 EVENT_TYPE_CHOICES = (
143 (GIVE_FLAG, "You flagged a course"),
144 (GET_FLAGGED, "Your course was flagged as spam"),
146 course = models.ForeignKey('courses.Course')
147 event_type = models.CharField(max_length=15, choices=EVENT_TYPE_CHOICES)
154 def get_message(self):
155 return self.get_event_type_display()
157 def __unicode__(self):
158 return unicode(self.user) + ' -- ' + self.get_event_type_display() + ' -- ' + unicode(self.course)
161 def create_event(user, course, type):
162 event = CourseKarmaEvent.objects.create(user=user,
164 points=CourseKarmaEvent.POINTS[type],
169 ALL_KARMA_EVENT_CLASSES = (GenericKarmaEvent, NoteKarmaEvent, CourseKarmaEvent)
172 def user_display_name(user):
173 """Return the best way to display a user's
174 name to them on the site."""
175 if hasattr(user, 'first_name') and user.first_name and \
176 hasattr(user, 'last_name') and user.last_name:
177 return user.first_name + ' ' + user.last_name
178 elif hasattr(user, 'email') and user.email:
184 @receiver(post_save, sender=User, weak=True)
185 def create_user_profile(sender, instance, created, **kwargs):
187 with transaction.commit_on_success():
189 UserProfile.objects.create(user=instance)
190 except DatabaseError:
191 logger.warn("Could not create UserProfile for user {u}. This is okay if running syncdb.".format(u=instance))