]> git.openstreetmap.org Git - osqa.git/blob - forum/actions/meta.py
merging cacheimp -> trunk
[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.marked = True\r
137         self.node.nstate.accepted = self\r
138         self.node.save()\r
139         self.node.question.reset_accepted_count_cache()\r
140 \r
141     def cancel_action(self):\r
142         self.node.marked = False\r
143         self.node.nstate.accepted = None\r
144         self.node.save()\r
145         self.node.question.reset_accepted_count_cache()\r
146 \r
147     def describe(self, viewer=None):\r
148         answer = self.node\r
149         question = answer.parent\r
150 \r
151         if self.user == question.author:\r
152             asker = (self.user == viewer) and _("your") or _("his")\r
153         else:\r
154             asker = self.hyperlink(question.author.get_profile_url(), question.author.username)\r
155 \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
159             'asker': asker,\r
160             'question': self.hyperlink(question.get_absolute_url(), question.title)\r
161         }\r
162 \r
163 \r
164 class FavoriteAction(ActionProxy):\r
165     def process_action(self):\r
166         self.node.reset_favorite_count_cache()\r
167 \r
168     def cancel_action(self):\r
169         self.process_action()\r
170 \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
175         }\r
176 \r
177 \r
178 class DeleteAction(ActionProxy):\r
179     def process_action(self):\r
180         self.node.mark_deleted(self)\r
181         \r
182         if self.node.node_type == "answer":\r
183             self.node.question.reset_answer_count_cache()\r
184 \r
185     def cancel_action(self):\r
186         self.node.mark_deleted(None)\r
187 \r
188         if self.node.node_type == "answer":\r
189             self.node.question.reset_answer_count_cache()\r
190 \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
195         }\r
196 \r
197     def reason(self):\r
198         if self.extra != "BYFLAGGED":\r
199             return self.extra\r
200         else:\r
201             return _("flagged by multiple users: ") + "; ".join([f.extra for f in FlagAction.objects.filter(node=self.node)])\r
202 \r
203 class UnknownAction(ActionProxy):\r
204     pass\r
205 \r
206 \r
207 class QuestionViewAction(DummyActionProxy):\r
208     def __init__(self, node, user, ip=None):\r
209         self.viewuser = user\r
210         self.node = node\r
211         super(QuestionViewAction, self).__init__(ip)\r
212 \r
213     def process_action(self):\r
214         self.node.extra_count = F('extra_count') + 1\r
215         self.node.save()\r