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