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
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
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()
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 = {}
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)
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:
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
self.save()
self.cancel_reputes()
self.cancel_action()
- #self.trigger_hooks(False)
+ #self.trigger_hooks(False)
@classmethod
def get_current(cls, **kwargs):
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:
__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)
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
cls.hooks.append(fn)
-
class ActionRepute(models.Model):
action = models.ForeignKey(Action, related_name='reputes')
date = models.DateTimeField(default=datetime.datetime.now)
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 = models.F('reputation') + self.value
+ self.user.reputation = self._add_to_rep(self.value)
self.user.save()
def delete(self):
- self.user.reputation = models.F('reputation') - self.value
+ self.user.reputation = self._add_to_rep(-self.value)
self.user.save()
super(ActionRepute, self).delete()