diff options
-rw-r--r-- | askbot/doc/source/changelog.rst | 1 | ||||
-rw-r--r-- | askbot/doc/source/optional-modules.rst | 5 | ||||
-rw-r--r-- | askbot/media/style/style.less | 1 | ||||
-rw-r--r-- | askbot/models/__init__.py | 3 | ||||
-rw-r--r-- | askbot/models/question.py | 13 | ||||
-rw-r--r-- | askbot/startup_procedures.py | 19 | ||||
-rw-r--r-- | askbot/tests/__init__.py | 1 | ||||
-rw-r--r-- | askbot/tests/haystack_search_tests.py | 2 | ||||
-rw-r--r-- | askbot/tests/page_load_tests.py | 4 | ||||
-rw-r--r-- | askbot/tests/user_views_tests.py | 39 | ||||
-rw-r--r-- | askbot/views/users.py | 4 |
11 files changed, 72 insertions, 20 deletions
diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst index d77e11ab..a971d9d6 100644 --- a/askbot/doc/source/changelog.rst +++ b/askbot/doc/source/changelog.rst @@ -3,6 +3,7 @@ Changes in Askbot Development version ------------------- +* Added support of Haystack for search (Adolfo) * Added minimum reputation setting to accept any answer as correct (Evgeny) * Added "VIP" option to groups - if checked, all posts belong to the group and users of that group in the future will be able to moderate those posts. Moderation features for VIP group are in progress (Evgeny) * Added setting `NOTIFICATION_DELAY_TIME` to use with enabled celery daemon (Adolfo) diff --git a/askbot/doc/source/optional-modules.rst b/askbot/doc/source/optional-modules.rst index aab80bf4..995ed224 100644 --- a/askbot/doc/source/optional-modules.rst +++ b/askbot/doc/source/optional-modules.rst @@ -60,6 +60,11 @@ Haystack search Askbot supports `Haystack <http://haystacksearch.org/>`_, a modular search framework that supports popular search engine backends as Solr, Elasticsearch, Whoosh and Xapian. +.. note:: + Haystack support in Askbot is a new feature, + please give us your feedback at ``support@askbot.com`` + regarding the possible improvements. + To enable: * add 'haystack' to INSTALLED_APPS diff --git a/askbot/media/style/style.less b/askbot/media/style/style.less index 607261ce..a7d035ed 100644 --- a/askbot/media/style/style.less +++ b/askbot/media/style/style.less @@ -2695,7 +2695,6 @@ a:hover.medal { } .user-profile-page{ - font-size:13px; color:@info-text-dark; p{ diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index fce1a09a..5b9f8336 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -98,7 +98,7 @@ def get_users_by_text_query(search_query, users_query_set = None): """Runs text search in user names and profile. For postgres, search also runs against user group names. """ - if django_settings.ENABLE_HAYSTACK_SEARCH: + if getattr(django_settings, 'ENABLE_HAYSTACK_SEARCH', False): from askbot.search.haystack import AskbotSearchQuerySet qs = AskbotSearchQuerySet().filter(content=search_query).models(User).get_django_queryset(User) return qs @@ -2931,7 +2931,6 @@ def format_instant_notification_email( only update_types in const.RESPONSE_ACTIVITY_TYPE_MAP_FOR_TEMPLATES are supported """ - site_url = askbot_settings.APP_URL origin_post = post.get_origin_post() #todo: create a better method to access "sub-urls" in user views diff --git a/askbot/models/question.py b/askbot/models/question.py index 7897250b..36a1725e 100644 --- a/askbot/models/question.py +++ b/askbot/models/question.py @@ -2,7 +2,7 @@ import datetime import operator import re -from django.conf import settings +from django.conf import settings as django_settings from django.db import models from django.contrib.auth.models import User from django.core import cache # import cache, not from cache import cache, to be able to monkey-patch cache.cache in test cases @@ -176,7 +176,7 @@ class ThreadManager(BaseQuerySetManager): """returns a query set of questions, matching the full text query """ - if settings.ENABLE_HAYSTACK_SEARCH: + if django_settings.ENABLE_HAYSTACK_SEARCH: from askbot.search.haystack import AskbotSearchQuerySet hs_qs = AskbotSearchQuerySet().filter(content=search_query) return hs_qs.get_django_queryset() @@ -303,7 +303,7 @@ class ThreadManager(BaseQuerySetManager): elif search_state.scope == 'favorite': favorite_filter = models.Q(favorited_by=request_user) - if 'followit' in settings.INSTALLED_APPS: + if 'followit' in django_settings.INSTALLED_APPS: followed_users = request_user.get_followed_users() favorite_filter |= models.Q(posts__post_type__in=('question', 'answer'), posts__author__in=followed_users) qs = qs.filter(favorite_filter) @@ -383,7 +383,10 @@ class ThreadManager(BaseQuerySetManager): orderby = QUESTION_ORDER_BY_MAP[search_state.sort] - if not (settings.ENABLE_HAYSTACK_SEARCH and orderby=='-relevance'): + if not ( + getattr(django_settings, 'ENABLE_HAYSTACK_SEARCH', False) \ + and orderby=='-relevance' + ): #FIXME: this does not produces the very same results as postgres. qs = qs.extra(order_by=[orderby]) @@ -882,7 +885,7 @@ class Thread(models.Model): { 'latest':'-added_at', 'oldest':'added_at', - 'votes':'-score' + 'votes':'-points' }[sort_method] ).values_list('id', flat=True) diff --git a/askbot/startup_procedures.py b/askbot/startup_procedures.py index 0a9e4e07..706e19ad 100644 --- a/askbot/startup_procedures.py +++ b/askbot/startup_procedures.py @@ -534,12 +534,16 @@ def test_avatar(): def test_haystack(): if 'haystack' in django_settings.INSTALLED_APPS: try_import('haystack', 'django-haystack', short_message = True) - if not hasattr(django_settings, 'HAYSTACK_SEARCH_ENGINE'): - message = 'Please add HAYSTACK_SEARCH_ENGINE = simple, for more info please checkout: http://django-haystack.readthedocs.org/en/v1.2.7/settings.html#haystack-search-engine' - raise AskbotConfigError(message) - if not hasattr(django_settings, 'HAYSTACK_SITECONF'): - message = 'Please add HAYSTACK_SITECONF = "askbot.search.haystack"' - raise AskbotConfigError(message) + if getattr(django_settings, 'ENABLE_HAYSTACK_SEARCH', False): + errors = list() + if not hasattr(django_settings, 'HAYSTACK_SEARCH_ENGINE'): + message = "Please HAYSTACK_SEARCH_ENGINE to an appropriate value, value 'simple' can be used for basic testing" + errors.append(message) + if not hasattr(django_settings, 'HAYSTACK_SITECONF'): + message = 'Please add HAYSTACK_SITECONF = "askbot.search.haystack"' + errors.append(message) + footer = 'Please refer to haystack documentation at http://django-haystack.readthedocs.org/en/v1.2.7/settings.html#haystack-search-engine' + print_errors(errors, footer=footer) def test_custom_user_profile_tab(): setting_name = 'ASKBOT_CUSTOM_USER_PROFILE_TAB' @@ -732,9 +736,6 @@ def run_startup_tests(): 'value': True, 'message': 'Please add: RECAPTCHA_USE_SSL = True' }, - 'ENABLE_HAYSTACK_SEARCH': { - 'message': 'Please add: ENABLE_HAYSTACK_SEARCH = False or True according to your setup' - }, 'HAYSTACK_SITECONF': { 'value': 'askbot.search.haystack', 'message': 'Please add: HAYSTACK_SITECONF = "askbot.search.haystack"' diff --git a/askbot/tests/__init__.py b/askbot/tests/__init__.py index 96ba2045..59db8f67 100644 --- a/askbot/tests/__init__.py +++ b/askbot/tests/__init__.py @@ -19,5 +19,6 @@ from askbot.tests.email_parsing_tests import * from askbot.tests.widget_tests import * from askbot.tests.category_tree_tests import CategoryTreeTests from askbot.tests.user_model_tests import UserModelTests +from askbot.tests.user_views_tests import * from askbot.tests.utils_tests import * from askbot.tests.view_context_tests import * diff --git a/askbot/tests/haystack_search_tests.py b/askbot/tests/haystack_search_tests.py index d1592f42..7a8bfcfd 100644 --- a/askbot/tests/haystack_search_tests.py +++ b/askbot/tests/haystack_search_tests.py @@ -11,7 +11,7 @@ class HaystackSearchTests(AskbotTestCase): that were added for askbot """ def setUp(self): - self._old_value = settings.ENABLE_HAYSTACK_SEARCH + self._old_value = getattr(settings, 'ENABLE_HAYSTACK_SEARCH', False) setattr(settings, "ENABLE_HAYSTACK_SEARCH", True) self.user = self.create_user(username='gepeto') diff --git a/askbot/tests/page_load_tests.py b/askbot/tests/page_load_tests.py index 9520af1a..6c820fef 100644 --- a/askbot/tests/page_load_tests.py +++ b/askbot/tests/page_load_tests.py @@ -166,13 +166,15 @@ class PageLoadTestCase(AskbotTestCase): group.save() user = self.create_user('user') user.join_group(group) - self.post_question(user=user, title='alibaba', group_id=group.id) + question = self.post_question(user=user, title='alibaba', group_id=group.id) + #ask for data anonymously - should get nothing query_data = {'query': 'alibaba'} response = self.client.get(reverse('api_get_questions'), query_data) response_data = simplejson.loads(response.content) self.assertEqual(len(response_data), 0) + #log in - should get the question self.client.login(method='force', user_id=user.id) response = self.client.get(reverse('api_get_questions'), query_data) response_data = simplejson.loads(response.content) diff --git a/askbot/tests/user_views_tests.py b/askbot/tests/user_views_tests.py new file mode 100644 index 00000000..489cf76a --- /dev/null +++ b/askbot/tests/user_views_tests.py @@ -0,0 +1,39 @@ +from askbot.tests.utils import AskbotTestCase +from askbot.views.users import owner_or_moderator_required +from django.contrib.auth.models import AnonymousUser +from django.core.urlresolvers import reverse +from django.http import HttpResponseRedirect +from mock import Mock +import urllib +import urlparse + +class UserViewsTests(AskbotTestCase): + + def test_owner_or_mod_required_passes_url_parameters(self): + @owner_or_moderator_required + def mock_view(request, user, context): + return None + + request = Mock(spec=('path', 'REQUEST', 'user')) + request.user = AnonymousUser() + request.REQUEST = {'abra': 'cadabra', 'foo': 'bar'} + request.path = '/some/path/' + user = self.create_user('user') + response = mock_view(request, user, {}) + self.assertEqual(isinstance(response, HttpResponseRedirect), True) + + url = response['location'] + parsed_url = urlparse.urlparse(url) + + self.assertEqual(parsed_url.path, reverse('user_signin')) + + next = dict(urlparse.parse_qsl(parsed_url.query))['next'] + next_url = urllib.unquote(next) + parsed_url = urlparse.urlparse(next_url) + + self.assertEqual(parsed_url.path, request.path) + + query = dict(urlparse.parse_qsl(parsed_url.query)) + self.assertEqual(set(query.keys()), set(['foo', 'abra'])) + self.assertEqual(set(query.values()), set(['bar', 'cadabra'])) + self.assertEqual(query['abra'], 'cadabra') diff --git a/askbot/views/users.py b/askbot/views/users.py index c2f11328..707f4e14 100644 --- a/askbot/views/users.py +++ b/askbot/views/users.py @@ -12,6 +12,7 @@ import functools import datetime import logging import operator +import urllib from django.db.models import Count from django.conf import settings as django_settings @@ -54,7 +55,8 @@ def owner_or_moderator_required(f): elif request.user.is_authenticated() and request.user.can_moderate_user(profile_owner): pass else: - params = '?next=%s' % request.path + next_url = request.path + '?' + urllib.urlencode(request.REQUEST) + params = '?next=%s' % urllib.quote(next_url) return HttpResponseRedirect(url_utils.get_login_url() + params) return f(request, profile_owner, context) return wrapped_func |