summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2011-12-11 14:52:37 -0300
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2011-12-11 14:52:37 -0300
commitfd895ea3d663ce3d4a722007edbe4ae952219e49 (patch)
tree0a862be9209f9759e8d180bf3b3a13d9b0f6404e
parent2ab5eaf579f39e490a3a36175d47818469eb4807 (diff)
parenta6ee98b28c67c551dcbe252a35b8ea4331c9699d (diff)
downloadaskbot-fd895ea3d663ce3d4a722007edbe4ae952219e49.tar.gz
askbot-fd895ea3d663ce3d4a722007edbe4ae952219e49.tar.bz2
askbot-fd895ea3d663ce3d4a722007edbe4ae952219e49.zip
Merge branch 'master' into tomasz
-rw-r--r--askbot/__init__.py2
-rw-r--r--askbot/deps/django_authopenid/views.py2
-rw-r--r--askbot/doc/source/changelog.rst6
-rw-r--r--askbot/locale/en/LC_MESSAGES/django.po2
-rw-r--r--askbot/middleware/forum_mode.py69
-rw-r--r--askbot/shims/__init__.py0
-rw-r--r--askbot/shims/django_shims.py22
-rw-r--r--askbot/templatetags/extra_filters_jinja.py6
-rw-r--r--askbot/tests/misc_tests.py14
-rw-r--r--askbot/tests/post_model_tests.py77
-rw-r--r--askbot/tests/utils.py16
-rw-r--r--askbot_requirements_dev.txt20
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