indexden is now optional
[oweals/karmaworld.git] / karmaworld / apps / users / models.py
index de80967532d2702f71008bcf988531e255782344..c34917582d5074a4cf0fee51884ac3e5fd18d377 100644 (file)
@@ -3,6 +3,7 @@
 # Copyright (C) 2013  FinalsClub Foundation
 import logging
 import datetime
+from allauth.account.signals import email_confirmed
 from django.contrib.auth.models import User
 from django.db.models import Sum
 from django.db.models.signals import post_save
@@ -14,10 +15,21 @@ from karmaworld.apps.courses.models import School
 logger = logging.getLogger(__name__)
 
 
+class UserProfileManager(models.Manager):
+    """ Handle restoring data. """
+    def get_by_natural_key(self, user):
+        return self.get(user=user)
+
+
 class UserProfile(models.Model):
-    user      = models.OneToOneField(User)
+    user = models.OneToOneField(User)
+    thanked_notes = models.ManyToManyField('notes.Note', related_name='users_thanked', blank=True, null=True)
+    flagged_notes = models.ManyToManyField('notes.Note', related_name='users_flagged', blank=True, null=True)
+    flagged_courses = models.ManyToManyField('courses.Course', related_name='users_flagged', blank=True, null=True)
+    school = models.ForeignKey(School, blank=True, null=True)
 
-    school    = models.ForeignKey(School, blank=True, null=True)
+    def natural_key(self):
+        return (self.user,)
 
     def get_points(self):
         sum = 0
@@ -28,6 +40,12 @@ class UserProfile(models.Model):
 
         return sum
 
+    def get_id(self):
+        return self.user.id
+
+    def has_staff_status(self):
+        return self.user.is_staff
+
     NO_BADGE = 0
     PROSPECT = 1
     BEGINNER = 2
@@ -65,12 +83,27 @@ class UserProfile(models.Model):
         for badge in self.BADGES:
             if points >= self.BADGE_THRESHOLDS[badge]:
                 highest_badge = badge
-        return highest_badge
+
+        if highest_badge is not self.NO_BADGE:
+            return self.BADGE_NAMES[highest_badge]
+        else:
+            return None
 
     def __unicode__(self):
         return self.user.__unicode__()
 
 
+@receiver(email_confirmed, weak=True)
+def give_email_confirm_karma(sender, **kwargs):
+    GenericKarmaEvent.create_event(kwargs['email_address'].user, kwargs['email_address'].email, GenericKarmaEvent.EMAIL_CONFIRMED)
+
+
+class BaseKarmaEventManager(models.Manager):
+    """ Handle restoring data. """
+    def get_by_natural_key(self, points, user, timestamp):
+        return self.get(user=user, timestamp=timestamp)
+
+
 class BaseKarmaEvent(models.Model):
     points    = models.IntegerField()
     user      = models.ForeignKey(User)
@@ -78,23 +111,50 @@ class BaseKarmaEvent(models.Model):
 
     class Meta:
         abstract = True
+        unique_together = ('points', 'user', 'timestamp')
+
+    def natural_key(self):
+        return (self.user, self.timestamp)
 
     def get_message(self):
         raise NotImplemented()
 
 
 class GenericKarmaEvent(BaseKarmaEvent):
+    NONE = 'none'
+    NOTE_DELETED       = 'upload'
+    EMAIL_CONFIRMED    = 'thanks'
+
+    EVENT_TYPE_CHOICES = (
+        (NONE,               'This should not happen'),
+        (NOTE_DELETED,       'Your note "{m}" was deleted'),
+        (EMAIL_CONFIRMED,    'You confirmed your email address {m}'),
+    )
+
+    POINTS = {
+        NOTE_DELETED: -5,
+        EMAIL_CONFIRMED: 5,
+    }
+
+    event_type = models.CharField(max_length=15, choices=EVENT_TYPE_CHOICES, default=NONE)
     message = models.CharField(max_length=255)
 
     @staticmethod
-    def create_event(user, message, points):
+    def create_event(user, message, type):
         event = GenericKarmaEvent.objects.create(user=user,
-                                                 points=points,
+                                                 points=GenericKarmaEvent.POINTS[type],
+                                                 event_type=type,
                                                  message=message)
         event.save()
 
     def get_message(self):
-        return self.message
+        if self.event_type == self.NONE:
+            return self.message
+        else:
+            return self.get_event_type_display().format(m=self.message)
+
+    def __unicode__(self):
+        return unicode(self.user) + ' -- ' + self.get_message()
 
 
 class NoteKarmaEvent(BaseKarmaEvent):
@@ -103,12 +163,19 @@ class NoteKarmaEvent(BaseKarmaEvent):
     NOTE_DELETED = 'deleted'
     GIVE_FLAG    = 'give_flag'
     GET_FLAGGED  = 'get_flagged'
+    DOWNLOADED_NOTE = 'downloaded'
+    HAD_NOTE_DOWNLOADED = 'was_downloaded'
+    CREATED_KEYWORD = 'created_keyword'
+
     EVENT_TYPE_CHOICES = (
         (UPLOAD,       "You uploaded a note"),
         (THANKS,       "You received a thanks for your note"),
         (NOTE_DELETED, "Your note was deleted"),
         (GIVE_FLAG,    "You flagged a note"),
         (GET_FLAGGED,  "Your note was flagged as spam"),
+        (DOWNLOADED_NOTE,  "You downloaded a note"),
+        (HAD_NOTE_DOWNLOADED,  "Your note was downloaded"),
+        (CREATED_KEYWORD,  "You created a keyword"),
     )
     note = models.ForeignKey('notes.Note')
     event_type = models.CharField(max_length=15, choices=EVENT_TYPE_CHOICES)
@@ -118,7 +185,10 @@ class NoteKarmaEvent(BaseKarmaEvent):
         THANKS: 1,
         NOTE_DELETED: -5,
         GIVE_FLAG: -1,
-        GET_FLAGGED: -100
+        GET_FLAGGED: -100,
+        DOWNLOADED_NOTE: -2,
+        HAD_NOTE_DOWNLOADED: 2,
+        CREATED_KEYWORD: 1,
     }
 
     def get_message(self):