diff options
author | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2010-12-05 02:59:33 -0500 |
---|---|---|
committer | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2010-12-05 02:59:33 -0500 |
commit | a5871f943c857aae905be1791bc37ffd0618e923 (patch) | |
tree | 66d2ba2dff7542549e1b883e866edcc2b488dd68 | |
parent | 031818d0b9bce845c9b59b43d55b70b1df35f8a1 (diff) | |
download | askbot-a5871f943c857aae905be1791bc37ffd0618e923.tar.gz askbot-a5871f943c857aae905be1791bc37ffd0618e923.tar.bz2 askbot-a5871f943c857aae905be1791bc37ffd0618e923.zip |
more badges
-rw-r--r-- | askbot/conf/badges.py | 18 | ||||
-rw-r--r-- | askbot/models/__init__.py | 15 | ||||
-rw-r--r-- | askbot/models/badges.py | 88 | ||||
-rw-r--r-- | askbot/models/question.py | 14 | ||||
-rw-r--r-- | askbot/tests/badge_tests.py | 62 | ||||
-rw-r--r-- | askbot/views/users.py | 16 |
6 files changed, 190 insertions, 23 deletions
diff --git a/askbot/conf/badges.py b/askbot/conf/badges.py index 3654da4d..85602e3a 100644 --- a/askbot/conf/badges.py +++ b/askbot/conf/badges.py @@ -183,3 +183,21 @@ settings.register( description=_('Associate Editor: minimum number of edits') ) ) + +settings.register( + IntegerValue( + BADGES, + 'FAVORITE_QUESTION_BADGE_MIN_STARS', + default=3, + description=_('Favorite Question: minimum stars') + ) +) + +settings.register( + IntegerValue( + BADGES, + 'STELLAR_QUESTION_BADGE_MIN_STARS', + default=5, + description=_('Stellar Question: minimum stars') + ) +) diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index ea20300e..93a8790d 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -734,6 +734,12 @@ def user_retag_question( tagnames = tags, silent = silent ) + award_badges_signal.send(None, + event = 'retag_question', + actor = self, + context_object = question, + timestamp = timestamp + ) @auto_now_timestamp def user_accept_best_answer(self, answer = None, timestamp = None): @@ -1330,6 +1336,7 @@ def toggle_favorite_question(self, question, timestamp=None, cancel=False): fave = FavoriteQuestion.objects.get(question=question, user=self) fave.delete() result = False + question.update_favorite_count() except FavoriteQuestion.DoesNotExist: if timestamp is None: timestamp = datetime.datetime.now() @@ -1340,7 +1347,13 @@ def toggle_favorite_question(self, question, timestamp=None, cancel=False): ) fave.save() result = True - Question.objects.update_favorite_count(question) + question.update_favorite_count() + award_badges_signal.send(None, + event = 'select_favorite_question', + actor = self, + context_object = question, + timestamp = timestamp + ) return result VOTES_TO_EVENTS = { diff --git a/askbot/models/badges.py b/askbot/models/badges.py index 363d290a..791dbd10 100644 --- a/askbot/models/badges.py +++ b/askbot/models/badges.py @@ -24,6 +24,7 @@ from django.utils.translation import gettext as _ from django.dispatch import Signal from askbot.models.repute import BadgeData, Award from askbot.models.user import Activity +from askbot.models.question import FavoriteQuestion as Fave#name collision from askbot import const from askbot.conf import settings as askbot_settings from askbot.utils.decorators import auto_now_timestamp @@ -625,16 +626,80 @@ class AssociateEditor(EditorTypeBadge): self.description = _('Edited %(num)s entries') % {'num': self.min_edits} return self +class Organizer(Badge): + def __init__(self): + super(Organizer, self).__init__( + key = 'organizer', + name = _('Organizer'), + level = const.BRONZE_BADGE, + multiple = False, + description = _('First retag') + ) -ORIGINAL_DATA = """ - (_('Organizer'), 3, _('organizer'), _('First retag'), False, 0), +class Autobiographer(Badge): + def __init__(self): + super(Autobiographer, self).__init__( + key = 'autobiographer', + name = _('Autobiographer'), + level = const.BRONZE_BADGE, + multiple = False, + description = _('Completed all user profile fields') + ) + + def consider_award(self, actor = None, + context_object = None, timestamp = None): + user = context_object + if user.email and user.real_name and user.website \ + and user.location and user.about: + return self.award(user, user, timestamp) + return False + +class FavoriteTypeBadge(Badge): + """subclass must use __new__ and in addition + must provide min_stars property for the badge + """ + def __init__(self): + descr = _('Question favorited by %(num)s users') + super(FavoriteTypeBadge, self).__init__( + key = self.key, + name = self.name, + level = self.level, + multiple = True, + description = descr % {'num': self.min_stars} + ) - (_('Autobiographer'), 3, _('autobiographer'), _('Completed all user profile fields'), False, 0), + def consider_award(self, actor = None, + context_object = None, timestamp = None): + question = context_object + #model FavoriteQuestion imported under alias of Fave + count = Fave.objects.filter( + question = question + ).exclude( + user = question.author + ).count() + if count == self.min_stars: + return self.award(question.author, question, timestamp) + return False - (_('Stellar Question'), 1, _('stellar-question'), _('Question favorited by 100 users'), True, 0), - (_('Favorite Question'), 2, _('favorite-question'), _('Question favorited by 25 users'), True, 0), +class StellarQuestion(FavoriteTypeBadge): + def __new__(cls): + self = super(StellarQuestion, cls).__new__(cls) + self.key = 'stellar-question' + self.name = _('Stellar Question') + self.level = const.GOLD_BADGE + self.min_stars = askbot_settings.STELLAR_QUESTION_BADGE_MIN_STARS + return self +class FavoriteQuestion(FavoriteTypeBadge): + def __new__(cls): + self = super(FavoriteQuestion, cls).__new__(cls) + self.key = 'favorite-question' + self.name = _('Favorite Question') + self.level = const.SILVER_BADGE + self.min_stars = askbot_settings.FAVORITE_QUESTION_BADGE_MIN_STARS + return self +ORIGINAL_DATA = """ (_('Generalist'), 2, _('generalist'), _('Active in many different tags'), False, 0), (_('Expert'), 2, _('expert'), _('Very active in one tag'), False, 0), (_('Taxonomist'), 2, _('taxonomist'), _('Created a tag used by 50 questions'), True, 0) @@ -646,6 +711,7 @@ ORIGINAL_DATA = """ BADGES = { 'strunk-and-white': AssociateEditor,#legacy slug name + 'autobiographer': Autobiographer, 'critic': Critic, 'citizen-patrol': CitizenPatrol, 'civic-duty': CivicDuty, @@ -654,6 +720,7 @@ BADGES = { 'editor': Editor, 'enlightened': Enlightened, 'famous-question': FamousQuestion, + 'favorite-question': FavoriteQuestion, 'good-answer': GoodAnswer, 'good-question': GoodQuestion, 'great-answer': GreatAnswer, @@ -663,6 +730,7 @@ BADGES = { 'nice-answer': NiceAnswer, 'nice-question': NiceQuestion, 'notable-question': NotableQuestion, + 'organizer': Organizer, 'peer-pressure': PeerPressure, 'popular-question': PopularQuestion, 'pundit': Pundit, @@ -670,6 +738,7 @@ BADGES = { 'student': Student, 'supporter': Supporter, 'self-learner': SelfLearner, + 'stellar-question': StellarQuestion, 'teacher': Teacher, } @@ -678,9 +747,15 @@ BADGES = { #most likely - from manipulator functions that are added to the User objects EVENTS_TO_BADGES = { 'accept_best_answer': (Scholar, Guru, Enlightened), + 'delete_post': (Disciplined, PeerPressure,), + 'downvote': (Critic, CivicDuty),#no regard for question or answer for now 'edit_answer': (Editor, AssociateEditor), 'edit_question': (Editor, AssociateEditor), 'flag_post': (CitizenPatrol,), + 'post_answer': (Necromancer,), + 'retag_question': (Organizer,), + 'select_favorite_question': (FavoriteQuestion, StellarQuestion,), + 'update_user_profile': (Autobiographer,), 'upvote_answer': ( Teacher, NiceAnswer, GoodAnswer, GreatAnswer, Supporter, SelfLearner, CivicDuty, @@ -690,9 +765,6 @@ EVENTS_TO_BADGES = { NiceQuestion, GoodQuestion, GreatQuestion, Student, Supporter, CivicDuty ), - 'downvote': (Critic, CivicDuty),#no regard for question or answer for now - 'delete_post': (Disciplined, PeerPressure,), - 'post_answer': (Necromancer,), 'view_question': (PopularQuestion, NotableQuestion, FamousQuestion,), } diff --git a/askbot/models/question.py b/askbot/models/question.py index e4a0e799..e3bf5882 100644 --- a/askbot/models/question.py +++ b/askbot/models/question.py @@ -281,11 +281,6 @@ class QuestionManager(models.Manager): """ self.filter(id=question.id).update(view_count = question.view_count + 1) - def update_favorite_count(self, question): - """ - update favourite_count for given question - """ - self.filter(id=question.id).update(favourite_count = FavoriteQuestion.objects.filter(question=question).count()) class Question(content.Content, DeletableContent): post_type = 'question' @@ -328,6 +323,15 @@ class Question(content.Content, DeletableContent): self.answer_count = self.get_answers().count() if save: self.save() + + def update_favorite_count(self): + """ + update favourite_count for given question + """ + self.favourite_count = FavoriteQuestion.objects.filter( + question=self + ).count() + self.save() def get_similar_questions(self): diff --git a/askbot/tests/badge_tests.py b/askbot/tests/badge_tests.py index 516270f8..e8fe8bcc 100644 --- a/askbot/tests/badge_tests.py +++ b/askbot/tests/badge_tests.py @@ -3,6 +3,7 @@ from django.test.client import Client from askbot.tests.utils import AskbotTestCase from askbot.conf import settings from askbot import models +from askbot.models.badges import award_badges_signal class BadgeTests(AskbotTestCase): @@ -13,6 +14,9 @@ class BadgeTests(AskbotTestCase): self.client = Client() def assert_have_badge(self, badge_key, recipient = None, expected_count = 1): + """note - expected_count matches total number of + badges within test, not the one that was awarded between the calls + to this assertion""" filters = {'badge__slug': badge_key, 'user': recipient} count = models.Award.objects.filter(**filters).count() self.assertEquals(count, expected_count) @@ -407,3 +411,61 @@ class BadgeTests(AskbotTestCase): revision_comment = 'sdgdfgsgfs' ) self.assert_have_badge('strunk-and-white', self.u2, 1) + + def test_organizer_badge(self): + question = self.post_question(user = self.u1) + self.u1.retag_question(question = question, tags = 'blah boom') + self.assert_have_badge('organizer', self.u1, 1) + self.u1.retag_question(question = question, tags = 'blah pooh') + self.assert_have_badge('organizer', self.u1, 1) + + def test_autobiographer_badge(self): + self.u1.real_name = 'blah' + self.u1.website = 'cnn.com' + self.u1.location = 'irvine' + self.u1.about = 'blah' + self.u1.save() + award_badges_signal.send(None, + event = 'update_user_profile', + actor = self.u1, + context_object = self.u1 + ) + self.assert_have_badge('autobiographer', self.u1, 1) + award_badges_signal.send(None, + event = 'update_user_profile', + actor = self.u1, + context_object = self.u1 + ) + self.assert_have_badge('autobiographer', self.u1, 1) + + def test_stellar_badge1(self): + question = self.post_question(user = self.u1) + settings.update('STELLAR_QUESTION_BADGE_MIN_STARS', 2) + self.u2.toggle_favorite_question(question) + self.assert_have_badge('stellar-question', self.u1, 0) + self.u3.toggle_favorite_question(question) + self.assert_have_badge('stellar-question', self.u1, 1) + + def test_stellar_badge2(self): + question = self.post_question(user = self.u1) + settings.update('STELLAR_QUESTION_BADGE_MIN_STARS', 2) + self.u2.toggle_favorite_question(question) + self.assert_have_badge('stellar-question', self.u1, 0) + self.u1.toggle_favorite_question(question) + """no gaming""" + self.assert_have_badge('stellar-question', self.u1, 0) + + def test_stellar_badge3(self): + question = self.post_question(user = self.u1) + settings.update('STELLAR_QUESTION_BADGE_MIN_STARS', 2) + self.u2.toggle_favorite_question(question) + self.assert_have_badge('stellar-question', self.u1, 0) + self.u3.toggle_favorite_question(question) + #award now + self.assert_have_badge('stellar-question', self.u1, 1) + self.u3.toggle_favorite_question(question) + #dont take back + self.assert_have_badge('stellar-question', self.u1, 1) + self.u3.toggle_favorite_question(question) + #dont reaward + self.assert_have_badge('stellar-question', self.u1, 1) diff --git a/askbot/views/users.py b/askbot/views/users.py index 51103f91..fd1836f4 100644 --- a/askbot/views/users.py +++ b/askbot/views/users.py @@ -32,7 +32,7 @@ from askbot import const from askbot.conf import settings as askbot_settings from askbot import models from askbot import exceptions -from askbot.models import signals +from askbot.models.badges import award_badges_signal from askbot.skins.loaders import ENV from askbot.templatetags import extra_tags @@ -262,14 +262,12 @@ def edit_user(request, id): user.about = sanitize_html(form.cleaned_data['about']) user.save() - # send user updated singal if full fields have been updated - if user.email and user.real_name and user.website \ - and user.location and user.date_of_birth and user.about: - signals.user_updated.send( - sender=user.__class__, - instance=user, - updated_by=user - ) + # send user updated signal if full fields have been updated + award_badges_signal.send(None, + event = 'update_user_profile', + actor = user, + context_object = user + ) return HttpResponseRedirect(user.get_profile_url()) else: form = forms.EditUserForm(user) |