]> git.openstreetmap.org Git - osqa.git/blob - forum_modules/default_badges/badges.py
Minor change to describe question and answer badges separately, so questions say...
[osqa.git] / forum_modules / default_badges / badges.py
1 from datetime import datetime, timedelta
2 from django.utils.translation import ugettext as _
3 from forum.badges.base import AbstractBadge
4 from forum.models import Badge
5 from forum.actions import *
6 from forum.models import Vote, Flag
7
8 import settings
9
10 class QuestionViewBadge(AbstractBadge):
11     abstract = True
12     listen_to = (QuestionViewAction,)
13
14     @property
15     def description(self):
16         return _('Asked a question with %s views') % str(self.nviews)
17
18     def award_to(self, action):
19         if action.node.extra_count == int(self.nviews):
20             return action.node.author
21
22
23 class PopularQuestion(QuestionViewBadge):
24     name = _('Popular Question')
25     nviews = settings.POPULAR_QUESTION_VIEWS
26
27
28 class NotableQuestion(QuestionViewBadge):
29     type = Badge.SILVER
30     name = _('Notable Question')
31     nviews = settings.NOTABLE_QUESTION_VIEWS
32
33 class FamousQuestion(QuestionViewBadge):
34     type = Badge.GOLD
35     name = _('Famous Question')
36     nviews = settings.FAMOUS_QUESTION_VIEWS
37
38
39
40
41 class NodeScoreBadge(AbstractBadge):
42     abstract = True
43     listen_to = (VoteAction,)
44
45     def award_to(self, action):
46         if (action.node.node_type == self.node_type) and (action.node.score == int(self.expected_score)):
47             return action.node.author
48             
49
50 class QuestionScoreBadge(NodeScoreBadge):
51     abstract = True
52     node_type = "question"
53
54     @property
55     def description(self):
56         return _('Question voted up %s times') % str(self.expected_score)
57
58 class NiceQuestion(QuestionScoreBadge):
59     expected_score = settings.NICE_QUESTION_VOTES_UP
60     name = _("Nice Question")
61
62 class GoodQuestion(QuestionScoreBadge):
63     type = Badge.SILVER
64     expected_score = settings.GOOD_QUESTION_VOTES_UP
65     name = _("Good Question")
66
67 class GreatQuestion(QuestionScoreBadge):
68     type = Badge.GOLD
69     expected_score = settings.GREAT_QUESTION_VOTES_UP
70     name = _("Great Question")
71
72
73 class AnswerScoreBadge(NodeScoreBadge):
74     abstract = True
75     node_type = "answer"
76
77     @property
78     def description(self):
79         return _('Answer voted up %s times') % str(self.expected_score)
80     
81 class NiceAnswer(AnswerScoreBadge):
82     expected_score = settings.NICE_ANSWER_VOTES_UP
83     name = _("Nice Answer")
84
85 class GoodAnswer(AnswerScoreBadge):
86     type = Badge.SILVER
87     expected_score = settings.GOOD_ANSWER_VOTES_UP
88     name = _("Good Answer")
89
90 class GreatAnswer(AnswerScoreBadge):
91     type = Badge.GOLD
92     expected_score = settings.GREAT_ANSWER_VOTES_UP
93     name = _("Great Answer")
94
95
96
97 class FavoriteQuestionBadge(AbstractBadge):
98     abstract = True
99     listen_to = (FavoriteAction,)
100
101     @property
102     def description(self):
103         return _('Question favorited by %s users') % str(self.expected_count)
104
105     def award_to(self, action):
106         if (action.node.node_type == "question") and (action.node.favorite_count == int(self.expected_count)):
107             return action.node.author
108
109 class FavoriteQuestion(FavoriteQuestionBadge):
110     type = Badge.SILVER
111     name = _("Favorite Question")
112     expected_count = settings.FAVORITE_QUESTION_FAVS
113
114 class StellarQuestion(FavoriteQuestionBadge):
115     type = Badge.GOLD
116     name = _("Stellar Question")
117     expected_count = settings.STELLAR_QUESTION_FAVS
118
119
120
121 class Disciplined(AbstractBadge):
122     listen_to = (DeleteAction,)
123     name = _("Disciplined")
124     description = _('Deleted own post with score of %s or higher') % settings.DISCIPLINED_MIN_SCORE
125
126     def award_to(self, action):
127         if (action.node.author == action.user) and (action.node.score >= int(settings.DISCIPLINED_MIN_SCORE)):
128             return action.user
129
130 class PeerPressure(AbstractBadge):
131     listen_to = (DeleteAction,)
132     name = _("Peer Pressure")
133     description = _('Deleted own post with score of %s or lower') % settings.PEER_PRESSURE_MAX_SCORE
134
135     def award_to(self, action):
136         if (action.node.author == action.user) and (action.node.score <= int(settings.PEER_PRESSURE_MAX_SCORE)):
137             return action.user
138
139
140 class Critic(AbstractBadge):
141     award_once = True
142     listen_to = (VoteDownAction,)
143     name = _("Critic")
144     description = _('First down vote')
145
146     def award_to(self, action):
147         if (action.user.vote_down_count == 1):
148             return action.user
149
150
151 class Supporter(AbstractBadge):
152     award_once = True
153     listen_to = (VoteUpAction,)
154     name = _("Supporter")
155     description = _('First up vote')
156
157     def award_to(self, action):
158         if (action.user.vote_up_count == 1):
159             return action.user
160
161
162 class FirstActionBadge(AbstractBadge):
163     award_once = True
164     abstract = True
165     
166     def award_to(self, action):
167         if (self.listen_to[0].objects.filter(user=action.user).count() == 1):
168             return action.user
169
170 class CitizenPatrol(FirstActionBadge):
171     listen_to = (FlagAction,)
172     name = _("Citizen Patrol")
173     description = _('First flagged post')
174
175 class Organizer(FirstActionBadge):
176     listen_to = (RetagAction,)
177     name = _("Organizer")
178     description = _('First retag')
179
180 class Editor(FirstActionBadge):
181     listen_to = (ReviseAction,)
182     name = _("Editor")
183     description = _('First edit')
184
185 class Scholar(FirstActionBadge):
186     listen_to = (AcceptAnswerAction,)
187     name = _("Scholar")
188     description = _('First accepted answer on your own question')
189
190 class Cleanup(FirstActionBadge):
191     listen_to = (RollbackAction,)
192     name = _("Cleanup")
193     description = _('First rollback')
194
195
196 class Autobiographer(AbstractBadge):
197     award_once = True
198     listen_to = (EditProfileAction,)
199     name = _("Autobiographer")
200     description = _('Completed all user profile fields')
201
202     def award_to(self, action):
203         user = action.user
204         if user.email and user.real_name and user.website and user.location and \
205                 user.date_of_birth and user.about:
206             return user
207
208
209
210 class CivicDuty(AbstractBadge):
211     type = Badge.SILVER
212     award_once = True
213     listen_to = (VoteUpAction, VoteDownAction)
214     name = _("Civic Duty")
215     description = _('Voted %s times') % settings.CIVIC_DUTY_VOTES
216
217     def award_to(self, action):
218         if (action.user.vote_up_count + action.user.vote_down_count) == int(settings.CIVIC_DUTY_VOTES):
219             return action.user
220
221
222 class Pundit(AbstractBadge):
223     award_once = True
224     listen_to = (CommentAction,)
225     name = _("Pundit")
226     description = _('Left %s comments') % settings.PUNDIT_COMMENT_COUNT
227
228     def award_to(self, action):
229         if (action.user.nodes.filter(node_type="comment", deleted=None)) == int(settings.CIVIC_DUTY_VOTES):
230             return action.user
231
232
233 class SelfLearner(AbstractBadge):
234     listen_to = (VoteUpAction, )
235     name = _("Self Learner")
236     description = _('Answered your own question with at least %s up votes') % settings.SELF_LEARNER_UP_VOTES
237
238     def award_to(self, action):
239         if (action.node.node_type == "answer") and (action.node.author == action.node.parent.author) and (
240             action.node.score == int(settings.SELF_LEARNER_UP_VOTES)):
241             return action.node.author
242
243
244 class StrunkAndWhite(AbstractBadge):
245     type = Badge.SILVER
246     award_once = True
247     listen_to = (ReviseAction,)
248     name = _("Strunk & White")
249     description = _('Edited %s entries') % settings.STRUNK_AND_WHITE_EDITS
250
251     def award_to(self, action):
252         if (ReviseAction.objects.filter(user=action.user).count() == int(settings.STRUNK_AND_WHITE_EDITS)):
253             return action.user
254
255
256 class Student(AbstractBadge):
257     award_once = True
258     listen_to = (VoteUpAction,)
259     name = _("Student")
260     description = _('Asked first question with at least one up vote')
261
262     def award_to(self, action):
263         if (action.node.node_type == "question") and (action.node.author.nodes.filter_state(deleted=False).filter(node_type="question", score=1).count() == 1):
264             return action.node.author
265
266
267 class Teacher(AbstractBadge):
268     award_once = True
269     listen_to = (VoteUpAction,)
270     name = _("Teacher")
271     description = _('Answered first question with at least one up vote')
272
273     def award_to(self, action):
274         if (action.node.node_type == "answer") and (action.node.author.nodes.filter_state(deleted=False).filter(node_type="answer", score=1).count() == 1):
275             return action.node.author
276
277
278 class Enlightened(AbstractBadge):
279     type = Badge.SILVER
280     award_once = True
281     listen_to = (VoteUpAction, AcceptAnswerAction)
282     name = _("Enlightened")
283     description = _('First answer was accepted with at least %s up votes') % settings.ENLIGHTENED_UP_VOTES
284
285     def award_to(self, action):
286         if (action.node.node_type == "answer") and (action.node.accepted) and (
287             action.node.score >= int(settings.ENLIGHTENED_UP_VOTES)):
288             return action.node.author
289
290
291 class Guru(AbstractBadge):
292     type = Badge.SILVER
293     listen_to = (VoteUpAction, AcceptAnswerAction)
294     name = _("Guru")
295     description = _('Accepted answer and voted up %s times') % settings.GURU_UP_VOTES
296
297     def award_to(self, action):
298         if (action.node.node_type == "answer") and (action.node.accepted) and (
299             action.node.score >= int(settings.ENLIGHTENED_UP_VOTES)):
300             return action.node.author
301
302
303 class Necromancer(AbstractBadge):
304     type = Badge.SILVER
305     listen_to = (VoteUpAction,)
306     name = _("Necromancer")
307     description = _('Answered a question more than %(dif_days)s days later with at least %(up_votes)s votes') % \
308             {'dif_days': settings.NECROMANCER_DIF_DAYS, 'up_votes': settings.NECROMANCER_UP_VOTES}
309
310     def award_to(self, action):
311         if (action.node.node_type == "answer") and (
312             action.node.added_at >= (action.node.question.added_at + timedelta(days=int(settings.NECROMANCER_DIF_DAYS)))):
313             return action.node.author
314
315 class Taxonomist(AbstractBadge):
316     type = Badge.SILVER
317     listen_to = tuple()
318     name = _("Taxonomist")
319     description = _('Created a tag used by %s questions') % settings.TAXONOMIST_USE_COUNT
320
321     def award_to(self, action):
322         return None
323