1 from django.utils.translation import ugettext as _
\r
2 from django.db.models import F
\r
3 from forum.models.action import ActionProxy, DummyActionProxy
\r
4 from forum.models import Vote, Flag
\r
5 from forum import settings
\r
7 class VoteAction(ActionProxy):
\r
8 def update_node_score(self, inc):
\r
9 self.node.score = F('score') + inc
\r
12 def process_vote_action(self, value):
\r
13 self.update_node_score(value)
\r
14 vote = Vote(node=self.node, user=self.user, action=self, value=value)
\r
17 def cancel_action(self):
\r
19 self.update_node_score(-vote.value)
\r
23 def get_for(cls, user, node):
\r
25 vote = Vote.objects.get(user=user, node=node)
\r
30 def describe_vote(self, vote_desc, viewer=None):
\r
31 return _("%(user)s %(vote_desc)s %(post_desc)s") % {
\r
32 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
\r
33 'vote_desc': vote_desc, 'post_desc': self.describe_node(viewer, self.node)
\r
37 class VoteUpAction(VoteAction):
\r
38 def repute_users(self):
\r
39 self.repute(self.node.author, int(settings.REP_GAIN_BY_UPVOTED))
\r
41 def process_action(self):
\r
42 self.process_vote_action(1)
\r
43 self.user.reset_vote_up_count_cache()
\r
45 def cancel_action(self):
\r
46 super(VoteUpAction, self).cancel_action()
\r
47 self.user.reset_vote_up_count_cache()
\r
49 def describe(self, viewer=None):
\r
50 return self.describe_vote(_("voted up"), viewer)
\r
52 class VoteDownAction(VoteAction):
\r
53 def repute_users(self):
\r
54 self.repute(self.node.author, -int(settings.REP_LOST_BY_DOWNVOTED))
\r
55 self.repute(self.user, -int(settings.REP_LOST_BY_DOWNVOTING))
\r
57 def process_action(self):
\r
58 self.process_vote_action(-1)
\r
59 self.user.reset_vote_down_count_cache()
\r
61 def cancel_action(self):
\r
62 super(VoteDownAction, self).cancel_action()
\r
63 self.user.reset_vote_down_count_cache()
\r
65 def describe(self, viewer=None):
\r
66 return self.describe_vote(_("voted down"), viewer)
\r
69 class VoteUpCommentAction(VoteUpAction):
\r
70 def repute_users(self):
\r
73 def process_action(self):
\r
74 self.process_vote_action(1)
\r
76 def cancel_action(self):
\r
77 super(VoteUpAction, self).cancel_action()
\r
79 def describe(self, viewer=None):
\r
80 return self.describe_vote(_("liked"), viewer)
\r
83 class FlagAction(ActionProxy):
\r
84 def repute_users(self):
\r
85 self.repute(self.node.author, -int(settings.REP_LOST_BY_FLAGGED))
\r
87 def process_action(self):
\r
88 flag = Flag(user=self.user, node=self.node, action=self, reason=self.extra)
\r
90 self.node.reset_flag_count_cache()
\r
92 if self.node.flag_count == int(settings.FLAG_COUNT_TO_HIDE_POST):
\r
93 self.repute(self.node.author, -int(settings.REP_LOST_BY_FLAGGED_3_TIMES))
\r
95 if self.node.flag_count == int(settings.FLAG_COUNT_TO_DELETE_POST):
\r
96 self.repute(self.node.author, -int(settings.REP_LOST_BY_FLAGGED_5_TIMES))
\r
97 if not self.node.deleted:
\r
98 DeleteAction(node=self.node, user=self.user, extra="BYFLAGGED").save()
\r
100 def cancel_action(self):
\r
102 self.node.reset_flag_count_cache()
\r
105 def get_for(cls, user, node):
\r
107 flag = Flag.objects.get(user=user, node=node)
\r
108 return flag.reason or _("No reason given")
\r
112 def describe(self, viewer=None):
\r
113 return _("%(user)s flagged %(post_desc)s: %(reason)s") % {
\r
114 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
\r
115 'post_desc': self.describe_node(viewer, self.node), 'reason': self.extra
\r
119 class AcceptAnswerAction(ActionProxy):
\r
120 def repute_users(self):
\r
121 if (self.user == self.node.parent.author) and (not self.user == self.node.author):
\r
122 self.repute(self.user, int(settings.REP_GAIN_BY_ACCEPTING))
\r
124 if self.user != self.node.author:
\r
125 self.repute(self.node.author, int(settings.REP_GAIN_BY_ACCEPTED))
\r
127 def process_action(self):
\r
128 self.node.parent.extra_ref = self.node
\r
129 self.node.parent.save()
\r
130 self.node.marked = True
\r
131 self.node.extra_action = self
\r
134 def cancel_action(self):
\r
135 self.node.parent.extra_ref = None
\r
136 self.node.parent.save()
\r
137 self.node.marked = False
\r
138 self.node.extra_action = None
\r
141 def describe(self, viewer=None):
\r
143 question = answer.parent
\r
145 if self.user == question.author:
\r
146 asker = (self.user == viewer) and _("your") or _("his")
\r
148 asker = self.hyperlink(question.author.get_profile_url(), question.author.username)
\r
150 return _("%(user)s accepted %(answerer)s answer on %(asker)s question %(question)s") % {
\r
151 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
\r
152 'answerer': self.hyperlink(answer.author.get_profile_url(), self.friendly_username(viewer, answer.author)),
\r
154 'question': self.hyperlink(question.get_absolute_url(), question.title)
\r
158 class FavoriteAction(ActionProxy):
\r
159 def process_action(self):
\r
160 self.node.reset_favorite_count_cache()
\r
162 def cancel_action(self):
\r
163 self.process_action()
\r
165 def describe(self, viewer=None):
\r
166 return _("%(user)s marked %(post_desc)s as favorite") % {
\r
167 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
\r
168 'post_desc': self.describe_node(viewer, self.node),
\r
172 class DeleteAction(ActionProxy):
\r
173 def process_action(self):
\r
174 self.node.deleted = self
\r
177 if self.node.node_type == "answer":
\r
178 self.node.question.reset_answer_count_cache()
\r
180 def cancel_action(self):
\r
181 self.node.deleted = None
\r
184 if self.node.node_type == "answer":
\r
185 self.node.question.reset_answer_count_cache()
\r
187 def describe(self, viewer=None):
\r
188 return _("%(user)s deleted %(post_desc)s: %(reason)s") % {
\r
189 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
\r
190 'post_desc': self.describe_node(viewer, self.node), 'reason': self.reason(),
\r
194 if self.extra != "BYFLAGGED":
\r
197 return _("flagged by multiple users: ") + "; ".join([f.extra for f in FlagAction.objects.filter(node=self.node)])
\r
200 class QuestionViewAction(DummyActionProxy):
\r
201 def __init__(self, node, user, ip=None):
\r
202 self.viewuser = user
\r
204 super(QuestionViewAction, self).__init__(ip)
\r
206 def process_action(self):
\r
207 self.node.extra_count = F('extra_count') + 1
\r