diff options
author | Byron <byroncorrales@gmail.com> | 2011-12-11 14:48:36 -0600 |
---|---|---|
committer | Byron <byroncorrales@gmail.com> | 2011-12-11 14:48:36 -0600 |
commit | 42547a5b71e505be1f39f924e882c50f527d6e29 (patch) | |
tree | 57f827428971d5ab0bf036b5f1cc36103e8171ef | |
parent | 23728d65ac220631a0f361d09f3af92ed1c3afe2 (diff) | |
parent | a6ee98b28c67c551dcbe252a35b8ea4331c9699d (diff) | |
download | askbot-42547a5b71e505be1f39f924e882c50f527d6e29.tar.gz askbot-42547a5b71e505be1f39f924e882c50f527d6e29.tar.bz2 askbot-42547a5b71e505be1f39f924e882c50f527d6e29.zip |
Merge branch 'askbot/master'
-rw-r--r-- | askbot/__init__.py | 2 | ||||
-rw-r--r-- | askbot/deps/django_authopenid/views.py | 2 | ||||
-rw-r--r-- | askbot/doc/source/changelog.rst | 6 | ||||
-rw-r--r-- | askbot/locale/en/LC_MESSAGES/django.po | 2 | ||||
-rw-r--r-- | askbot/middleware/forum_mode.py | 69 | ||||
-rw-r--r-- | askbot/shims/__init__.py | 0 | ||||
-rw-r--r-- | askbot/shims/django_shims.py | 22 | ||||
-rw-r--r-- | askbot/templatetags/extra_filters_jinja.py | 6 | ||||
-rw-r--r-- | askbot/tests/misc_tests.py | 14 | ||||
-rw-r--r-- | askbot/tests/post_model_tests.py | 77 | ||||
-rw-r--r-- | askbot/tests/utils.py | 16 | ||||
-rw-r--r-- | askbot_requirements_dev.txt | 20 |
12 files changed, 186 insertions, 50 deletions
diff --git a/askbot/__init__.py b/askbot/__init__.py index 99c3f596..1c919add 100644 --- a/askbot/__init__.py +++ b/askbot/__init__.py @@ -9,7 +9,7 @@ import smtplib import sys import logging -VERSION = (0, 7, 33) +VERSION = (0, 7, 34) #keys are module names used by python imports, #values - the package qualifier to use for pip diff --git a/askbot/deps/django_authopenid/views.py b/askbot/deps/django_authopenid/views.py index ac406f1d..e9059c61 100644 --- a/askbot/deps/django_authopenid/views.py +++ b/askbot/deps/django_authopenid/views.py @@ -554,8 +554,6 @@ def show_signin_view( #annotate objects with extra data providers = util.get_enabled_login_providers() for login_method in existing_login_methods: - if login_method.provider_name == 'facebook': - continue#it is disabled try: provider_data = providers[login_method.provider_name] if provider_data['type'] == 'password': diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst index 2617b096..8b302e4a 100644 --- a/askbot/doc/source/changelog.rst +++ b/askbot/doc/source/changelog.rst @@ -1,8 +1,12 @@ Changes in Askbot ================= -0.7.33 (Current Version) +0.7.34 (Current Version) ------------------------ +* Returned support of Django 1.2 + +0.7.33 +------ * Made on log in redirect to the forum index page by default and to the question page, if user was reading the question it is still possible to override the ``next`` url parameter diff --git a/askbot/locale/en/LC_MESSAGES/django.po b/askbot/locale/en/LC_MESSAGES/django.po index ca813006..9e8c30a2 100644 --- a/askbot/locale/en/LC_MESSAGES/django.po +++ b/askbot/locale/en/LC_MESSAGES/django.po @@ -4026,7 +4026,7 @@ msgid "last used" msgstr "" msgid "cannot be deleted" -msgstr "sorry, but older votes cannot be revoked" +msgstr "" msgid "with openid it is easier" msgstr "With the OpenID you don't need to create new username and password." diff --git a/askbot/middleware/forum_mode.py b/askbot/middleware/forum_mode.py index 8f14199b..7f1e29b1 100644 --- a/askbot/middleware/forum_mode.py +++ b/askbot/middleware/forum_mode.py @@ -1,36 +1,57 @@ +""" +contains :class:`ForumModeMiddleware`, which is +enabling support of closed forum mode +""" from django.http import HttpResponseRedirect from django.utils.translation import ugettext as _ from django.conf import settings from django.core.urlresolvers import resolve - +from askbot.shims.django_shims import ResolverMatch from askbot.conf import settings as askbot_settings -PROTECTED_URLS = [ - 'about', - 'feeds', - 'privacy', - 'tags', - 'badges', - 'questions', - 'question', - 'question_revisions', - 'users', - 'edit_user', - 'faq', - 'user_profile', - 'answer_revisions', - 'user_subscriptions', - 'widget_questions'] +PROTECTED_VIEW_MODULES = ( + 'askbot.views', + 'django.contrib.syndication.views', +) +ALLOWED_VIEWS = ( + 'askbot.views.meta.media', +) + +def is_view_protected(view_func): + """True if view belongs to one of the + protected view modules + """ + for protected_module in PROTECTED_VIEW_MODULES: + if view_func.__module__.startswith(protected_module): + return True + return False +def is_view_allowed(func): + """True, if view is allowed to access + by the special rule + """ + view_path = func.__module__ + '.' + func.__name__ + return view_path in ALLOWED_VIEWS class ForumModeMiddleware(object): + """protects forum views is the closed forum mode""" def process_request(self, request): + """when askbot is in the closed mode + it will let through only authenticated users. + All others will be redirected to the login url. + """ if (askbot_settings.ASKBOT_CLOSED_FORUM_MODE - and request.user.is_anonymous() - and resolve(request.path).url_name in PROTECTED_URLS): - request.user.message_set.create(_('Please log in to use %s') % \ - askbot_settings.APP_SHORT_NAME) - return HttpResponseRedirect(settings.LOGIN_URL) - else: - return None + and request.user.is_anonymous()): + resolver_match = ResolverMatch(resolve(request.path)) + + if is_view_allowed(resolver_match.func): + return + + if is_view_protected(resolver_match.func): + request.user.message_set.create( + _('Please log in to use %s') % \ + askbot_settings.APP_SHORT_NAME + ) + return HttpResponseRedirect(settings.LOGIN_URL) + return None diff --git a/askbot/shims/__init__.py b/askbot/shims/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/askbot/shims/__init__.py diff --git a/askbot/shims/django_shims.py b/askbot/shims/django_shims.py new file mode 100644 index 00000000..0fe6a964 --- /dev/null +++ b/askbot/shims/django_shims.py @@ -0,0 +1,22 @@ +"""shims for django objects of different versions +only functionality that is necessary is implemented""" +import django + +class ResolverMatch(object): + """a shim for the ResolverMatch, implemented + since django 1.3 + before the match result was a three-tuple + """ + def __init__(self, resolver_match): + self.resolver_match = resolver_match + + def _get_func(self): + """the getter function for the + ``func`` property + """ + if django.VERSION[1] < 3: + return self.resolver_match[0] + else: + return self.resolver_match.func + + func = property(_get_func) diff --git a/askbot/templatetags/extra_filters_jinja.py b/askbot/templatetags/extra_filters_jinja.py index 8486d934..f4e0a5ee 100644 --- a/askbot/templatetags/extra_filters_jinja.py +++ b/askbot/templatetags/extra_filters_jinja.py @@ -14,6 +14,7 @@ from askbot.conf import settings as askbot_settings from askbot.skins import utils as skin_utils from askbot.utils import functions from askbot.utils.slug import slugify +from askbot.shims.django_shims import ResolverMatch from django_countries import countries from django_countries import settings as countries_settings @@ -36,8 +37,9 @@ absolutize_urls = register.filter(absolutize_urls_func) def clean_login_url(url): """pass through, unless user was originally on the logout page""" try: - resolver_match = resolve(url) - if resolver_match.url_name == 'question': + resolver_match = ResolverMatch(resolve(url)) + from askbot.views.readers import question + if resolver_match.func == question: return url except Http404: pass diff --git a/askbot/tests/misc_tests.py b/askbot/tests/misc_tests.py index c452d518..306d62ce 100644 --- a/askbot/tests/misc_tests.py +++ b/askbot/tests/misc_tests.py @@ -43,18 +43,20 @@ class MiscTests(AskbotTestCase): def test_get_related_object_type_name_for_anything_else_1(self): ct = ContentType.objects.get_for_model(self.u2) - self.assertIsNone(get_related_object_type_name(ct.id, self.u2.id)) + self.assertTrue( + get_related_object_type_name(ct.id, self.u2.id) is None + ) def test_get_related_object_type_name_for_anything_else_2(self): question = self.post_question(user=self.u1) comment = self.post_comment(user=self.u1, parent_post=question) ct = ContentType.objects.get_for_model(comment) - self.assertIsNone(get_related_object_type_name(ct.id, comment.id)) + self.assertTrue( + get_related_object_type_name(ct.id, comment.id) is None + ) def test_proper_PostRevision_manager_is_used(self): "Makes sure that both normal and related managers for PostRevision don't implement .create() method" question = self.post_question(user=self.u1) - with self.assertRaises(NotImplementedError): - question.revisions.create() - with self.assertRaises(NotImplementedError): - PostRevision.objects.create() + self.assertRaises(NotImplementedError, question.revisions.create) + self.assertRaises(NotImplementedError, PostRevision.objects.create) diff --git a/askbot/tests/post_model_tests.py b/askbot/tests/post_model_tests.py index 7ea8621a..48e0d667 100644 --- a/askbot/tests/post_model_tests.py +++ b/askbot/tests/post_model_tests.py @@ -13,31 +13,84 @@ class PostModelTests(AskbotTestCase): self.u3 = self.create_user(username='user3') def test_model_validation(self): - with self.assertRaises(NotImplementedError): - PostRevision.objects.create(text='blah', author=self.u1, revised_at=datetime.datetime.now(), revision_type=PostRevision.QUESTION_REVISION) + self.assertRaises( + NotImplementedError, + PostRevision.objects.create, + [], + { + 'text': 'blah', + 'author': self.u1, + 'revised_at': datetime.datetime.now(), + 'revision_type': PostRevision.QUESTION_REVISION + } + ) - with self.assertRaisesRegexp(AttributeError, r"'NoneType' object has no attribute 'revisions'"): + self.assertRaisesRegexp( + AttributeError, + r"'NoneType' object has no attribute 'revisions'", # cannot set `revision` without a parent - PostRevision.objects.create_answer_revision(text='blah', author=self.u1, revised_at=datetime.datetime.now()) + PostRevision.objects.create_answer_revision, + *[], + **{ + 'text': 'blah', + 'author': self.u1, + 'revised_at': datetime.datetime.now() + } + ) + + post_revision = PostRevision( + text='blah', + author=self.u1, + revised_at=datetime.datetime.now(), + revision=1, + revision_type=4 + ) + + self.assertRaisesRegexp( + ValidationError, + r"{'__all__': \[u'One \(and only one\) of question/answer fields has to be set.'\], 'revision_type': \[u'Value 4 is not a valid choice.'\]}", + post_revision.save + ) - with self.assertRaisesRegexp(ValidationError, r"{'__all__': \[u'One \(and only one\) of question/answer fields has to be set.'\], 'revision_type': \[u'Value 4 is not a valid choice.'\]}"): # revision_type not in (1,2) - PostRevision(text='blah', author=self.u1, revised_at=datetime.datetime.now(), revision=1, revision_type=4).save() question = self.post_question(user=self.u1) rev2 = PostRevision(question=question, text='blah', author=self.u1, revised_at=datetime.datetime.now(), revision=2, revision_type=PostRevision.QUESTION_REVISION) rev2.save() - self.assertIsNotNone(rev2.id) + self.assertFalse(rev2.id is None) + + post_revision = PostRevision( + question=question, + text='blah', + author=self.u1, + revised_at=datetime.datetime.now(), + revision=2, + revision_type=PostRevision.ANSWER_REVISION + ) + self.assertRaisesRegexp( + ValidationError, + r"{'__all__': \[u'Revision_type doesn`t match values in question/answer fields.', u'Post revision with this Question and Revision already exists.'\]}", + post_revision.save + ) - with self.assertRaisesRegexp(ValidationError, r"{'__all__': \[u'Revision_type doesn`t match values in question/answer fields.', u'Post revision with this Question and Revision already exists.'\]}"): - PostRevision(question=question, text='blah', author=self.u1, revised_at=datetime.datetime.now(), revision=2, revision_type=PostRevision.ANSWER_REVISION).save() - with self.assertRaisesRegexp(ValidationError, r"{'__all__': \[u'Revision_type doesn`t match values in question/answer fields.'\]}"): - PostRevision(question=question, text='blah', author=self.u1, revised_at=datetime.datetime.now(), revision=3, revision_type=PostRevision.ANSWER_REVISION).save() + post_revision = PostRevision( + question=question, + text='blah', + author=self.u1, + revised_at=datetime.datetime.now(), + revision=3, + revision_type=PostRevision.ANSWER_REVISION + ) + self.assertRaisesRegexp( + ValidationError, + r"{'__all__': \[u'Revision_type doesn`t match values in question/answer fields.'\]}", + post_revision.save + ) rev3 = PostRevision.objects.create_question_revision(question=question, text='blah', author=self.u1, revised_at=datetime.datetime.now(), revision_type=123) # revision_type - self.assertIsNotNone(rev3.id) + self.assertFalse(rev3.id is None) self.assertEqual(3, rev3.revision) # By the way: let's test the auto-increase of revision number self.assertEqual(PostRevision.QUESTION_REVISION, rev3.revision_type) diff --git a/askbot/tests/utils.py b/askbot/tests/utils.py index 54a2a0ec..fdeea371 100644 --- a/askbot/tests/utils.py +++ b/askbot/tests/utils.py @@ -1,7 +1,7 @@ """utility functions used by Askbot test cases """ from django.test import TestCase -from django.utils.unittest.compatibility import wraps +from functools import wraps from askbot import models def create_user( @@ -95,6 +95,20 @@ class AskbotTestCase(TestCase): return user_object + def assertRaisesRegexp(self, *args, **kwargs): + """a shim for python < 2.7""" + try: + #run assertRaisesRegex, if available + super(AskbotTestCase, self).assertRaisesRegexp(*args, **kwargs) + except AttributeError: + #in this case lose testing for the error text + #second argument is the regex that is supposed + #to match the error text + args_list = list(args)#conv tuple to list + args_list.pop(1)#so we can remove an item + self.assertRaises(*args_list, **kwargs) + + def post_question( self, user = None, diff --git a/askbot_requirements_dev.txt b/askbot_requirements_dev.txt new file mode 100644 index 00000000..af83b691 --- /dev/null +++ b/askbot_requirements_dev.txt @@ -0,0 +1,20 @@ +akismet +django>=1.1.2 +Jinja2 +Coffin>=0.3 +-e git+https://github.com/matthiask/south.git#egg=south +oauth2 +markdown2 +html5lib +django-keyedcache +django-threaded-multihost +django-robots +unidecode +django-countries==1.0.5 +django-celery==2.2.7 +django-kombu==0.9.2 +django-followit +django-recaptcha-works +python-openid +pystache==0.3.1 +pylint |