]> git.openstreetmap.org Git - osqa.git/blobdiff - forum/models/user.py
now superusers and staff can unsubscribe users subscription.
[osqa.git] / forum / models / user.py
index f5eb9a615304bcd045617859fc01f8b0d6c6623e..7772bc9fc630e695f7209406f9f2b1b1e0b4c672 100644 (file)
@@ -1,4 +1,5 @@
 from base import *
 from base import *
+from utils import PickledObjectField
 from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.auth.models import User as DjangoUser, AnonymousUser as DjangoAnonymousUser
 from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.auth.models import User as DjangoUser, AnonymousUser as DjangoAnonymousUser
@@ -124,11 +125,36 @@ class User(BaseModel, DjangoUser):
     def __unicode__(self):
         return self.username
 
     def __unicode__(self):
         return self.username
 
+    @property
+    def prop(self):
+        prop = self.__dict__.get('_prop', None)
+
+        if prop is None:
+            prop = UserPropertyDict(self)
+            self._prop = prop
+
+        return prop
+
     @property
     def is_siteowner(self):
         #todo: temporary thing, for now lets just assume that the site owner will always be the first user of the application
         return self.id == 1
 
     @property
     def is_siteowner(self):
         #todo: temporary thing, for now lets just assume that the site owner will always be the first user of the application
         return self.id == 1
 
+    @property
+    def decorated_name(self):
+        if settings.SHOW_STATUS_DIAMONDS:
+            if self.is_superuser:
+                return u"%s \u2666\u2666" % self.username
+
+            if self.is_staff:
+                return u"%s \u2666" % self.username
+
+        return self.username
+
+    @property
+    def last_activity(self):
+        return self.actions.order_by('-action_date')[0].action_date
+
     @property
     def gravatar(self):
         return md5(self.email).hexdigest()
     @property
     def gravatar(self):
         return md5(self.email).hexdigest()
@@ -164,6 +190,18 @@ class User(BaseModel, DjangoUser):
     def get_absolute_url(self):
         return self.get_profile_url()
 
     def get_absolute_url(self):
         return self.get_profile_url()
 
+    @models.permalink
+    def get_asked_url(self):
+        return ('user_questions', (), {'mode': _('asked-by'), 'user': self.id, 'slug': slugify(self.username)})
+
+    @models.permalink
+    def get_answered_url(self):
+        return ('user_questions', (), {'mode': _('answered-by'), 'user': self.id, 'slug': slugify(self.username)})
+
+    @models.permalink
+    def get_subscribed_url(self):
+        return ('user_questions', (), {'mode': _('subscribed-by'), 'user': self.id, 'slug': slugify(self.username)})
+
     def get_profile_link(self):
         profile_link = u'<a href="%s">%s</a>' % (self.get_profile_url(), self.username)
         return mark_safe(profile_link)
     def get_profile_link(self):
         profile_link = u'<a href="%s">%s</a>' % (self.get_profile_url(), self.username)
         return mark_safe(profile_link)
@@ -238,7 +276,7 @@ class User(BaseModel, DjangoUser):
 
     @true_if_is_super_or_staff
     def can_accept_answer(self, answer):
 
     @true_if_is_super_or_staff
     def can_accept_answer(self, answer):
-        return self == answer.question.author
+        return self == answer.question.author and (settings.USERS_CAN_ACCEPT_OWN or answer.author != answer.question.author)
 
     @true_if_is_super_or_staff
     def can_create_tags(self):
 
     @true_if_is_super_or_staff
     def can_create_tags(self):
@@ -277,12 +315,16 @@ class User(BaseModel, DjangoUser):
             return self.can_delete_comment(post)
 
         return (self == post.author and (post.__class__.__name__ == "Answer" or
             return self.can_delete_comment(post)
 
         return (self == post.author and (post.__class__.__name__ == "Answer" or
-        not post.answers.exclude(author=self).count()))
+        not post.answers.exclude(author__id=self.id).count()))
 
     @true_if_is_super_or_staff
     def can_upload_files(self):
         return self.reputation >= int(settings.REP_TO_UPLOAD)
 
 
     @true_if_is_super_or_staff
     def can_upload_files(self):
         return self.reputation >= int(settings.REP_TO_UPLOAD)
 
+    @true_if_is_super_or_staff
+    def is_a_super_user_or_staff(self):
+        return False
+
     def email_valid_and_can_ask(self):
         return 'ask' not in settings.REQUIRE_EMAIL_VALIDATION_TO or self.email_isvalid
 
     def email_valid_and_can_ask(self):
         return 'ask' not in settings.REQUIRE_EMAIL_VALIDATION_TO or self.email_isvalid
 
@@ -297,13 +339,13 @@ class User(BaseModel, DjangoUser):
     def suspension(self):
         if self.__dict__.get('_suspension_dencache_', False) != None:
             try:
     def suspension(self):
         if self.__dict__.get('_suspension_dencache_', False) != None:
             try:
-                self.__dict__['_suspension_dencache_'] = self.actions.get(action_type="suspend", canceled=False)
+                self.__dict__['_suspension_dencache_'] = self.reputes.get(action__action_type="suspend", action__canceled=False).action
             except ObjectDoesNotExist:
                 self.__dict__['_suspension_dencache_'] = None
             except MultipleObjectsReturned:
                 logging.error("Multiple suspension actions found for user %s (%s)" % (self.username, self.id))
             except ObjectDoesNotExist:
                 self.__dict__['_suspension_dencache_'] = None
             except MultipleObjectsReturned:
                 logging.error("Multiple suspension actions found for user %s (%s)" % (self.username, self.id))
-                self.__dict__['_suspension_dencache_'] = self.actions.filter(action_type="suspend", canceled=False
-                                                                             ).order_by('-action_date')[0]
+                self.__dict__['_suspension_dencache_'] = self.reputes.filter(action__action_type="suspend", action__canceled=False
+                                                                             ).order_by('-action__action_date')[0]
 
         return self.__dict__['_suspension_dencache_']
 
 
         return self.__dict__['_suspension_dencache_']
 
@@ -326,14 +368,82 @@ class User(BaseModel, DjangoUser):
     class Meta:
         app_label = 'forum'
 
     class Meta:
         app_label = 'forum'
 
+class UserProperty(BaseModel):
+    user = models.ForeignKey(User, related_name='properties')
+    key = models.CharField(max_length=16)
+    value = PickledObjectField()
+
+    class Meta:
+        app_label = 'forum'
+        unique_together = ('user', 'key')
+
+    def cache_key(self):
+        return self._generate_cache_key("%s:%s" % (self.user.id, self.key))
+
+    @classmethod
+    def infer_cache_key(cls, querydict):
+        if 'user' in querydict and 'key' in querydict:
+            return cls._generate_cache_key("%s:%s" % (querydict['user'].id, querydict['key']))
+
+        return None
+
+class UserPropertyDict(object):
+    def __init__(self, user):
+        self.__dict__['_user'] = user
+
+    def __get_property(self, name):
+        if self.__dict__.get('__%s__' % name, None):
+            return self.__dict__['__%s__' % name]
+        try:
+            user = self.__dict__['_user']
+            prop = UserProperty.objects.get(user=user, key=name)
+            self.__dict__['__%s__' % name] = prop
+            self.__dict__[name] = prop.value
+            return prop
+        except:
+            return None
+
+
+    def __getattr__(self, name):
+        if self.__dict__.get(name, None):
+            return self.__dict__[name]
+
+        prop = self.__get_property(name)
+
+        if prop:
+            return prop.value
+        else:
+            return None
+
+    def __setattr__(self, name, value):
+        current = self.__get_property(name)
+
+        if value is not None:
+            if current:
+                current.value = value
+                self.__dict__[name] = value
+                current.save(full_save=True)
+            else:
+                user = self.__dict__['_user']
+                prop = UserProperty(user=user, value=value, key=name)
+                prop.save()
+                self.__dict__[name] = value
+                self.__dict__['__%s__' % name] = prop
+        else:
+            if current:
+                current.delete()
+                del self.__dict__[name]
+                del self.__dict__['__%s__' % name]
+
+
 class SubscriptionSettings(models.Model):
 class SubscriptionSettings(models.Model):
-    user = models.OneToOneField(User, related_name='subscription_settings')
+    user = models.OneToOneField(User, related_name='subscription_settings', editable=False)
 
     enable_notifications = models.BooleanField(default=True)
 
     #notify if
     member_joins = models.CharField(max_length=1, default='n')
 
     enable_notifications = models.BooleanField(default=True)
 
     #notify if
     member_joins = models.CharField(max_length=1, default='n')
-    new_question = models.CharField(max_length=1, default='d')
+    new_question = models.CharField(max_length=1, default='n')
     new_question_watched_tags = models.CharField(max_length=1, default='i')
     subscribed_questions = models.CharField(max_length=1, default='i')
 
     new_question_watched_tags = models.CharField(max_length=1, default='i')
     subscribed_questions = models.CharField(max_length=1, default='i')
 
@@ -352,6 +462,8 @@ class SubscriptionSettings(models.Model):
     notify_comments = models.BooleanField(default=False)
     notify_accepted = models.BooleanField(default=False)
 
     notify_comments = models.BooleanField(default=False)
     notify_accepted = models.BooleanField(default=False)
 
+    send_digest = models.BooleanField(default=True)
+
     class Meta:
         app_label = 'forum'
 
     class Meta:
         app_label = 'forum'