]> git.openstreetmap.org Git - osqa.git/blob - forum/actions/meta.py
OSQA-349
[osqa.git] / forum / actions / meta.py
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
6 \r
7 class VoteAction(ActionProxy):\r
8     def update_node_score(self, inc):\r
9         self.node.score = F('score') + inc\r
10         self.node.save()\r
11 \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
15         vote.save()\r
16 \r
17     def cancel_action(self):\r
18         vote = self.vote\r
19         self.update_node_score(-vote.value)\r
20         vote.delete()\r
21 \r
22     @classmethod\r
23     def get_for(cls, user, node):\r
24         try:\r
25             vote = Vote.objects.get(user=user, node=node)\r
26             return vote.value\r
27         except:\r
28             return None\r
29 \r
30     @classmethod\r
31     def get_action_for(cls, user, node):\r
32         try:\r
33             vote = Vote.objects.get(user=user, node=node)\r
34             return vote.action\r
35         except:\r
36             return None\r
37 \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
42         }\r
43 \r
44 \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
48 \r
49     def process_action(self):\r
50         self.process_vote_action(1)\r
51         self.user.reset_vote_up_count_cache()\r
52 \r
53     def cancel_action(self):\r
54         super(VoteUpAction, self).cancel_action()\r
55         self.user.reset_vote_up_count_cache()\r
56 \r
57     def describe(self, viewer=None):\r
58         return self.describe_vote(_("voted up"), viewer)\r
59 \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
64 \r
65     def process_action(self):\r
66         self.process_vote_action(-1)\r
67         self.user.reset_vote_down_count_cache()\r
68 \r
69     def cancel_action(self):\r
70         super(VoteDownAction, self).cancel_action()\r
71         self.user.reset_vote_down_count_cache()\r
72 \r
73     def describe(self, viewer=None):\r
74         return self.describe_vote(_("voted down"), viewer)\r
75 \r
76 \r
77 class VoteUpCommentAction(VoteUpAction):\r
78     def repute_users(self):\r
79         pass\r
80 \r
81     def process_action(self):\r
82         self.process_vote_action(1)\r
83 \r
84     def cancel_action(self):\r
85         super(VoteUpAction, self).cancel_action()\r
86 \r
87     def describe(self, viewer=None):\r
88         return self.describe_vote(_("liked"), viewer)\r
89 \r
90 \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
94 \r
95     def process_action(self):\r
96         flag = Flag(user=self.user, node=self.node, action=self, reason=self.extra)\r
97         flag.save()\r
98         self.node.reset_flag_count_cache()\r
99 \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
102 \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
107 \r
108     def cancel_action(self):\r
109         self.flag.delete()\r
110         self.node.reset_flag_count_cache()\r
111 \r
112     @classmethod\r
113     def get_for(cls, user, node):\r
114         try:\r
115             flag = Flag.objects.get(user=user, node=node)\r
116             return flag.reason or _("No reason given")\r
117         except:\r
118             return None\r
119 \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
124         }\r
125 \r
126 \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
131 \r
132         if self.user != self.node.author:\r
133             self.repute(self.node.author, int(settings.REP_GAIN_BY_ACCEPTED))\r
134 \r
135     def process_action(self):\r
136         self.node.parent.extra_ref = self.node\r
137         self.node.parent.save()\r
138         self.node.marked = True\r
139         self.node.nstate.accepted = self\r
140         self.node.save()\r
141 \r
142     def cancel_action(self):\r
143         self.node.parent.extra_ref = None\r
144         self.node.parent.save()\r
145         self.node.marked = False\r
146         self.node.nstate.accepted = None\r
147         self.node.save()\r
148 \r
149     def describe(self, viewer=None):\r
150         answer = self.node\r
151         question = answer.parent\r
152 \r
153         if self.user == question.author:\r
154             asker = (self.user == viewer) and _("your") or _("his")\r
155         else:\r
156             asker = self.hyperlink(question.author.get_profile_url(), question.author.username)\r
157 \r
158         return _("%(user)s accepted %(answerer)s answer on %(asker)s question %(question)s") % {\r
159             'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),\r
160             'answerer': self.hyperlink(answer.author.get_profile_url(), self.friendly_ownername(viewer, answer.author)),\r
161             'asker': asker,\r
162             'question': self.hyperlink(question.get_absolute_url(), question.title)\r
163         }\r
164 \r
165 \r
166 class FavoriteAction(ActionProxy):\r
167     def process_action(self):\r
168         self.node.reset_favorite_count_cache()\r
169 \r
170     def cancel_action(self):\r
171         self.process_action()\r
172 \r
173     def describe(self, viewer=None):\r
174         return _("%(user)s marked %(post_desc)s as favorite") % {\r
175             'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),\r
176             'post_desc': self.describe_node(viewer, self.node),\r
177         }\r
178 \r
179 \r
180 class DeleteAction(ActionProxy):\r
181     def process_action(self):\r
182         self.node.mark_deleted(self)\r
183         \r
184         if self.node.node_type == "answer":\r
185             self.node.question.reset_answer_count_cache()\r
186 \r
187     def cancel_action(self):\r
188         self.node.mark_deleted(None)\r
189 \r
190         if self.node.node_type == "answer":\r
191             self.node.question.reset_answer_count_cache()\r
192 \r
193     def describe(self, viewer=None):\r
194         return _("%(user)s deleted %(post_desc)s") % {\r
195             'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),\r
196             'post_desc': self.describe_node(viewer, self.node)\r
197         }\r
198 \r
199     def reason(self):\r
200         if self.extra != "BYFLAGGED":\r
201             return self.extra\r
202         else:\r
203             return _("flagged by multiple users: ") + "; ".join([f.extra for f in FlagAction.objects.filter(node=self.node)])\r
204 \r
205 class UnknownAction(ActionProxy):\r
206     pass\r
207 \r
208 \r
209 class QuestionViewAction(DummyActionProxy):\r
210     def __init__(self, node, user, ip=None):\r
211         self.viewuser = user\r
212         self.node = node\r
213         super(QuestionViewAction, self).__init__(ip)\r
214 \r
215     def process_action(self):\r
216         self.node.extra_count = F('extra_count') + 1\r
217         self.node.save()\r