X-Git-Url: https://git.openstreetmap.org./osqa.git/blobdiff_plain/58f020d4fab8251103edb89bfc4cf5d5d389d1ad..3ef231f42d6b4d94e7cad81053e29d2dc7e7a331:/forum/models/action.py diff --git a/forum/models/action.py b/forum/models/action.py index 1d2e773..7e88745 100644 --- a/forum/models/action.py +++ b/forum/models/action.py @@ -1,4 +1,6 @@ from django.utils.translation import ugettext as _ +from django.utils.encoding import smart_unicode + from utils import PickledObjectField from threading import Thread from forum.utils import html @@ -15,8 +17,13 @@ class ActionQuerySet(CachedQuerySet): else: return super(ActionQuerySet, self).obj_from_datadict(datadict) - def get(self, *args, **kwargs): - return super(ActionQuerySet, self).get(*args, **kwargs).leaf() + def get(self, *args, **kwargs): + action = super(ActionQuerySet, self).get(*args, **kwargs).leaf + + if not isinstance(action, self.model): + raise self.model.DoesNotExist() + + return action class ActionManager(CachedManager): use_for_related_fields = True @@ -36,9 +43,10 @@ class ActionManager(CachedManager): class Action(BaseModel): user = models.ForeignKey('User', related_name="actions") - ip = models.CharField(max_length=16) + real_user = models.ForeignKey('User', related_name="proxied_actions", null=True) + ip = models.CharField(max_length=39) node = models.ForeignKey('Node', null=True, related_name="actions") - action_type = models.CharField(max_length=16) + action_type = models.CharField(max_length=32) action_date = models.DateTimeField(default=datetime.datetime.now) extra = PickledObjectField() @@ -46,7 +54,7 @@ class Action(BaseModel): canceled = models.BooleanField(default=False) canceled_by = models.ForeignKey('User', null=True, related_name="canceled_actions") canceled_at = models.DateTimeField(null=True) - canceled_ip = models.CharField(max_length=16) + canceled_ip = models.CharField(max_length=39) hooks = {} @@ -95,6 +103,7 @@ class Action(BaseModel): cancel = ActionRepute(action=self, user=repute.user, value=(-repute.value), by_canceled=True) cancel.save() + @property def leaf(self): leaf_cls = ActionProxyMetaClass.types.get(self.action_type, None) @@ -111,7 +120,7 @@ class Action(BaseModel): def get_type(cls): return re.sub(r'action$', '', cls.__name__.lower()) - def save(self, data=None, *args, **kwargs): + def save(self, data=None, threaded=True, *args, **kwargs): isnew = False if not self.id: @@ -127,7 +136,7 @@ class Action(BaseModel): if (self.node is None) or (not self.node.nis.wiki): self.repute_users() self.process_action() - self.trigger_hooks(True) + self.trigger_hooks(threaded, True) return self @@ -145,7 +154,7 @@ class Action(BaseModel): self.save() self.cancel_reputes() self.cancel_action() - #self.trigger_hooks(False) + #self.trigger_hooks(False) @classmethod def get_current(cls, **kwargs): @@ -167,15 +176,18 @@ class Action(BaseModel): Action.hooks[cls].append(fn) - def trigger_hooks(self, new=True): - thread = Thread(target=trigger_hooks_threaded, args=[self, Action.hooks, new]) - thread.setDaemon(True) - thread.start() + def trigger_hooks(self, threaded, new=True): + if threaded: + thread = Thread(target=trigger_hooks, args=[self, Action.hooks, new]) + thread.setDaemon(True) + thread.start() + else: + trigger_hooks(self, Action.hooks, new) class Meta: app_label = 'forum' -def trigger_hooks_threaded(action, hooks, new): +def trigger_hooks(action, hooks, new): for cls, hooklist in hooks.items(): if isinstance(action, cls): for hook in hooklist: @@ -203,13 +215,13 @@ class ActionProxy(Action): __metaclass__ = ActionProxyMetaClass def friendly_username(self, viewer, user): - return (viewer == user) and _('You') or user.username + return (viewer == user) and _('You') or smart_unicode(user.username) def friendly_ownername(self, owner, user): - return (owner == user) and _('your') or user.username + return (owner == user) and _('your') or smart_unicode(user.username) def viewer_or_user_verb(self, viewer, user, viewer_verb, user_verb): - return (viewer == user) and viewer_verb or user_verb + return (viewer == user) and viewer_verb or user_verb def hyperlink(self, url, title, **attrs): return html.hyperlink(url, title, **attrs) @@ -223,11 +235,14 @@ class ActionProxy(Action): node_desc = node_link return _("%(user)s %(node_name)s %(node_desc)s") % { - 'user': self.hyperlink(node.author.get_profile_url(), self.friendly_ownername(viewer, node.author)), - 'node_name': node.friendly_name, - 'node_desc': node_desc, + 'user': self.hyperlink(node.author.get_profile_url(), self.friendly_ownername(viewer, node.author)), + 'node_name': node.friendly_name, + 'node_desc': node_desc, } - + + def affected_links(self, viewer): + return ", ".join([self.hyperlink(u.get_profile_url(), self.friendly_username(viewer, u)) for u in set([r.user for r in self.reputes.all()])]) + class Meta: proxy = True @@ -269,7 +284,6 @@ class DummyActionProxy(object): cls.hooks.append(fn) - class ActionRepute(models.Model): action = models.ForeignKey(Action, related_name='reputes') date = models.DateTimeField(default=datetime.datetime.now) @@ -287,13 +301,19 @@ class ActionRepute(models.Model): if self.value < 0: return self.value return 0 + def _add_to_rep(self, value): + if int(self.user.reputation + value) < 1 and not settings.ALLOW_NEGATIVE_REPUTATION: + return 0 + else: + return models.F('reputation') + value + def save(self, *args, **kwargs): super(ActionRepute, self).save(*args, **kwargs) - self.user.reputation += self.value + self.user.reputation = self._add_to_rep(self.value) self.user.save() def delete(self): - self.user.reputation -= self.value + self.user.reputation = self._add_to_rep(-self.value) self.user.save() super(ActionRepute, self).delete()