X-Git-Url: https://git.openstreetmap.org./osqa.git/blobdiff_plain/f5f883ab101be733caa56ee5ff3e4ffb7225ac3d..700b6dec7e4d655fee91e26f9757442162047281:/forum/models/user.py?ds=sidebyside diff --git a/forum/models/user.py b/forum/models/user.py index a1481b3..cabaabb 100644 --- a/forum/models/user.py +++ b/forum/models/user.py @@ -1,4 +1,5 @@ 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 @@ -124,6 +125,16 @@ class User(BaseModel, DjangoUser): 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 @@ -140,6 +151,10 @@ class User(BaseModel, DjangoUser): 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() @@ -175,6 +190,18 @@ class User(BaseModel, DjangoUser): 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'%s' % (self.get_profile_url(), self.username) return mark_safe(profile_link) @@ -249,7 +276,7 @@ class User(BaseModel, DjangoUser): @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): @@ -288,7 +315,7 @@ class User(BaseModel, DjangoUser): 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): @@ -308,13 +335,13 @@ class User(BaseModel, DjangoUser): 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)) - 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_'] @@ -337,14 +364,82 @@ class User(BaseModel, DjangoUser): 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): - 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') - 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') @@ -363,6 +458,8 @@ class SubscriptionSettings(models.Model): notify_comments = models.BooleanField(default=False) notify_accepted = models.BooleanField(default=False) + send_digest = models.BooleanField(default=True) + class Meta: app_label = 'forum'