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
31 def get_action_for(cls, user, node):
\r
33 vote = Vote.objects.get(user=user, node=node)
\r
38 def describe_vote(self, vote_desc, viewer=None):
\r
39 return _("%(user)s %(vote_desc)s %(post_desc)s") % {
\r
40 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
\r
41 'vote_desc': vote_desc, 'post_desc': self.describe_node(viewer, self.node)
\r
45 class VoteUpAction(VoteAction):
\r
46 def repute_users(self):
\r
47 self.repute(self.node.author, int(settings.REP_GAIN_BY_UPVOTED))
\r
49 def process_action(self):
\r
50 self.process_vote_action(1)
\r
51 self.user.reset_vote_up_count_cache()
\r
53 def cancel_action(self):
\r
54 super(VoteUpAction, self).cancel_action()
\r
55 self.user.reset_vote_up_count_cache()
\r
57 def describe(self, viewer=None):
\r
58 return self.describe_vote(_("voted up"), viewer)
\r
60 class VoteDownAction(VoteAction):
\r
61 def repute_users(self):
\r
62 self.repute(self.node.author, -int(settings.REP_LOST_BY_DOWNVOTED))
\r
63 self.repute(self.user, -int(settings.REP_LOST_BY_DOWNVOTING))
\r
65 def process_action(self):
\r
66 self.process_vote_action(-1)
\r
67 self.user.reset_vote_down_count_cache()
\r
69 def cancel_action(self):
\r
70 super(VoteDownAction, self).cancel_action()
\r
71 self.user.reset_vote_down_count_cache()
\r
73 def describe(self, viewer=None):
\r
74 return self.describe_vote(_("voted down"), viewer)
\r
77 class VoteUpCommentAction(VoteUpAction):
\r
78 def repute_users(self):
\r
81 def process_action(self):
\r
82 self.process_vote_action(1)
\r
84 def cancel_action(self):
\r
85 super(VoteUpAction, self).cancel_action()
\r
87 def describe(self, viewer=None):
\r
88 return self.describe_vote(_("liked"), viewer)
\r
91 class FlagAction(ActionProxy):
\r
92 def repute_users(self):
\r
93 self.repute(self.node.author, -int(settings.REP_LOST_BY_FLAGGED))
\r
95 def process_action(self):
\r
96 flag = Flag(user=self.user, node=self.node, action=self, reason=self.extra)
\r
98 self.node.reset_flag_count_cache()
\r
100 if self.node.flag_count >= int(settings.FLAG_COUNT_TO_HIDE_POST):
\r
101 self.repute(self.node.author, -int(settings.REP_LOST_BY_FLAGGED_3_TIMES))
\r
103 if self.node.flag_count >= int(settings.FLAG_COUNT_TO_DELETE_POST):
\r
104 self.repute(self.node.author, -int(settings.REP_LOST_BY_FLAGGED_5_TIMES))
\r
105 if not self.node.nis.deleted:
\r
106 DeleteAction(node=self.node, user=self.user, extra="BYFLAGGED").save()
\r
108 def cancel_action(self):
\r
110 self.node.reset_flag_count_cache()
\r
113 def get_for(cls, user, node):
\r
115 flag = Flag.objects.get(user=user, node=node)
\r
116 return flag.reason or _("No reason given")
\r
120 def describe(self, viewer=None):
\r
121 return _("%(user)s flagged %(post_desc)s: %(reason)s") % {
\r
122 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
\r
123 'post_desc': self.describe_node(viewer, self.node), 'reason': self.extra
\r
127 class AcceptAnswerAction(ActionProxy):
\r
128 def repute_users(self):
\r
129 if (self.user == self.node.parent.author) and (not self.user == self.node.author):
\r
130 self.repute(self.user, int(settings.REP_GAIN_BY_ACCEPTING))
\r
132 if self.user != self.node.author:
\r
133 self.repute(self.node.author, int(settings.REP_GAIN_BY_ACCEPTED))
\r
135 def process_action(self):
\r
136 self.node.marked = True
\r
137 self.node.nstate.accepted = self
\r
139 self.node.question.reset_accepted_count_cache()
\r
141 def cancel_action(self):
\r
142 self.node.marked = False
\r
143 self.node.nstate.accepted = None
\r
145 self.node.question.reset_accepted_count_cache()
\r
147 def describe(self, viewer=None):
\r
149 question = answer.parent
\r
151 if self.user == question.author:
\r
152 asker = (self.user == viewer) and _("your") or _("his")
\r
154 asker = self.hyperlink(question.author.get_profile_url(), question.author.username)
\r
156 return _("%(user)s accepted %(answerer)s answer on %(asker)s question %(question)s") % {
\r
157 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
\r
158 'answerer': self.hyperlink(answer.author.get_profile_url(), self.friendly_ownername(viewer, answer.author)),
\r
160 'question': self.hyperlink(question.get_absolute_url(), question.title)
\r
164 class FavoriteAction(ActionProxy):
\r
165 def process_action(self):
\r
166 self.node.reset_favorite_count_cache()
\r
168 def cancel_action(self):
\r
169 self.process_action()
\r
171 def describe(self, viewer=None):
\r
172 return _("%(user)s marked %(post_desc)s as favorite") % {
\r
173 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
\r
174 'post_desc': self.describe_node(viewer, self.node),
\r
178 class DeleteAction(ActionProxy):
\r
179 def process_action(self):
\r
180 self.node.mark_deleted(self)
\r
182 if self.node.node_type == "answer":
\r
183 self.node.question.reset_answer_count_cache()
\r
185 def cancel_action(self):
\r
186 self.node.mark_deleted(None)
\r
188 if self.node.node_type == "answer":
\r
189 self.node.question.reset_answer_count_cache()
\r
191 def describe(self, viewer=None):
\r
192 return _("%(user)s deleted %(post_desc)s") % {
\r
193 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
\r
194 'post_desc': self.describe_node(viewer, self.node)
\r
198 if self.extra != "BYFLAGGED":
\r
201 return _("flagged by multiple users: ") + "; ".join([f.extra for f in FlagAction.objects.filter(node=self.node)])
\r
203 class UnknownAction(ActionProxy):
\r
207 class QuestionViewAction(DummyActionProxy):
\r
208 def __init__(self, node, user, ip=None):
\r
209 self.viewuser = user
\r
211 super(QuestionViewAction, self).__init__(ip)
\r
213 def process_action(self):
\r
214 self.node.extra_count = F('extra_count') + 1
\r