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