|
@@ -5,6 +5,7 @@ from django.template import RequestContext
|
|
from django.utils import timezone
|
|
from django.utils import timezone
|
|
from django.utils.translation import ugettext as _
|
|
from django.utils.translation import ugettext as _
|
|
from haystack.query import RelatedSearchQuerySet
|
|
from haystack.query import RelatedSearchQuerySet
|
|
|
|
+from misago.acl.exceptions import ACLError403, ACLError404
|
|
from misago.decorators import block_crawlers
|
|
from misago.decorators import block_crawlers
|
|
from misago.forms import FormFields
|
|
from misago.forms import FormFields
|
|
from misago.models import Forum, Thread, Post, User
|
|
from misago.models import Forum, Thread, Post, User
|
|
@@ -14,112 +15,122 @@ from misago.apps.errors import error403, error404
|
|
from misago.apps.profiles.views import list as users_list
|
|
from misago.apps.profiles.views import list as users_list
|
|
from misago.apps.search.forms import QuickSearchForm
|
|
from misago.apps.search.forms import QuickSearchForm
|
|
|
|
|
|
-@block_crawlers
|
|
|
|
-def search(request):
|
|
|
|
- queryset = Post.objects.filter(forum__in=Forum.objects.readable_forums(request.acl))
|
|
|
|
- return do_search(request, queryset)
|
|
|
|
|
|
|
|
|
|
+class ViewBase(object):
|
|
|
|
+ search_route = 'search'
|
|
|
|
+ results_route = 'search_results'
|
|
|
|
+ advanced_route = None
|
|
|
|
|
|
-def do_search(request, queryset, search_route=None):
|
|
|
|
- if not request.acl.search.can_search():
|
|
|
|
- return error403(request, _("You don't have permission to search community."))
|
|
|
|
|
|
+ def check_acl(self):
|
|
|
|
+ pass
|
|
|
|
|
|
- search_route = search_route or 'search'
|
|
|
|
|
|
+ def queryset(self):
|
|
|
|
+ pass
|
|
|
|
|
|
- if request.method != "POST":
|
|
|
|
- form = QuickSearchForm(request=request)
|
|
|
|
- return request.theme.render_to_response('search/home.html',
|
|
|
|
- {
|
|
|
|
- 'form': FormFields(form),
|
|
|
|
- 'search_route': search_route,
|
|
|
|
- 'search_result': request.session.get('%s_result' % search_route),
|
|
|
|
- 'disable_search': True,
|
|
|
|
- },
|
|
|
|
- context_instance=RequestContext(request))
|
|
|
|
|
|
+ def search_form_type(self):
|
|
|
|
+ return QuickSearchForm
|
|
|
|
+
|
|
|
|
+ def render_to_response(self, template, form, context):
|
|
|
|
+ context.update({
|
|
|
|
+ 'form': FormFields(form),
|
|
|
|
+ 'search_route': self.search_route,
|
|
|
|
+ 'results_route': self.results_route,
|
|
|
|
+ 'search_advanced': self.advanced_route,
|
|
|
|
+ 'disable_search': True,
|
|
|
|
+ })
|
|
|
|
+ return self.request.theme.render_to_response('search/%s.html' % template,
|
|
|
|
+ context,
|
|
|
|
+ context_instance=RequestContext(self.request))
|
|
|
|
+
|
|
|
|
+ def __new__(cls, request, **kwargs):
|
|
|
|
+ obj = super(ViewBase, cls).__new__(cls)
|
|
|
|
+ return obj(request, **kwargs)
|
|
|
|
+
|
|
|
|
+ def __call__(self, request, **kwargs):
|
|
|
|
+ try:
|
|
|
|
+ if request.user.is_crawler():
|
|
|
|
+ raise ACLError404()
|
|
|
|
+ self.check_acl()
|
|
|
|
+ if not request.acl.search.can_search():
|
|
|
|
+ raise ACLError403(_("You don't have permission to search community."))
|
|
|
|
+ self.request = request
|
|
|
|
+ return self.call(**kwargs)
|
|
|
|
+ except ACLError403 as e:
|
|
|
|
+ return error403(request, unicode(e))
|
|
|
|
+ except ACLError404 as e:
|
|
|
|
+ return error404(request, unicode(e))
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class SearchBaseView(ViewBase):
|
|
|
|
+ def call(self, **kwargs):
|
|
|
|
+ form_type = self.search_form_type()
|
|
|
|
+ if self.request.method != "POST":
|
|
|
|
+ form = self.search_form_type()(request=self.request)
|
|
|
|
+ return self.render_to_response('home', form,
|
|
|
|
+ {
|
|
|
|
+ 'search_result': self.request.session.get(self.results_route),
|
|
|
|
+ })
|
|
|
|
|
|
- try:
|
|
|
|
- form = QuickSearchForm(request.POST, request=request)
|
|
|
|
- if form.is_valid():
|
|
|
|
- if form.mode == 'forum':
|
|
|
|
- jump_to = Forum.objects.forum_by_name(form.target, request.acl)
|
|
|
|
- if jump_to:
|
|
|
|
- if jump_to.level == 1:
|
|
|
|
- return redirect(reverse('index') + ('#%s' % jump_to.slug))
|
|
|
|
- return redirect(jump_to.url)
|
|
|
|
- else:
|
|
|
|
- raise SearchException(_('Forum "%(forum)s" could not be found.') % {'forum': form.target})
|
|
|
|
- if form.mode == 'user':
|
|
|
|
- request.POST = request.POST.copy()
|
|
|
|
- request.POST['username'] = form.target
|
|
|
|
- return users_list(request)
|
|
|
|
- sqs = RelatedSearchQuerySet().auto_query(form.cleaned_data['search_query']).order_by('-id').load_all()
|
|
|
|
- sqs = sqs.load_all_queryset(Post, queryset.filter(deleted=False).filter(moderated=False).select_related('thread', 'forum', 'user'))[:60]
|
|
|
|
-
|
|
|
|
- if request.user.is_authenticated():
|
|
|
|
- request.user.last_search = timezone.now()
|
|
|
|
- request.user.save(force_update=True)
|
|
|
|
- if request.user.is_anonymous():
|
|
|
|
- request.session['last_search'] = timezone.now()
|
|
|
|
-
|
|
|
|
- if not sqs:
|
|
|
|
- raise SearchException(_("Search returned no results. Change search query and try again."))
|
|
|
|
- request.session['%s_result' % search_route] = {
|
|
|
|
- 'search_query': form.cleaned_data['search_query'],
|
|
|
|
- 'search_results': [p.object for p in sqs],
|
|
|
|
- }
|
|
|
|
- return redirect(reverse('%s_results' % search_route))
|
|
|
|
- else:
|
|
|
|
- raise SearchException(form.errors['search_query'][0])
|
|
|
|
- except SearchException as e:
|
|
|
|
- return request.theme.render_to_response('search/error.html',
|
|
|
|
- {
|
|
|
|
- 'form': FormFields(form),
|
|
|
|
- 'search_route': search_route,
|
|
|
|
- 'message': unicode(e),
|
|
|
|
- 'disable_search': True,
|
|
|
|
- },
|
|
|
|
- context_instance=RequestContext(request))
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-@block_crawlers
|
|
|
|
-def show_results(request, page=0):
|
|
|
|
- return results(request, page)
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-def results(request, page=0, search_route=None):
|
|
|
|
- if not request.acl.search.can_search():
|
|
|
|
- return error403(request, _("You don't have permission to search community."))
|
|
|
|
-
|
|
|
|
- search_route = search_route or 'search'
|
|
|
|
- result = request.session.get('%s_result' % search_route)
|
|
|
|
- if not result:
|
|
|
|
- form = QuickSearchForm(request=request)
|
|
|
|
- return request.theme.render_to_response('search/error.html',
|
|
|
|
- {
|
|
|
|
- 'form': FormFields(form),
|
|
|
|
- 'search_route': search_route,
|
|
|
|
- 'message': _("No search results were found."),
|
|
|
|
- 'disable_search': True,
|
|
|
|
- },
|
|
|
|
- context_instance=RequestContext(request))
|
|
|
|
-
|
|
|
|
- items = result['search_results']
|
|
|
|
- items_total = len(items);
|
|
|
|
- try:
|
|
|
|
- pagination = make_pagination(page, items_total, 12)
|
|
|
|
- except Http404:
|
|
|
|
- return redirect(reverse('%s_results' % search_route))
|
|
|
|
-
|
|
|
|
- form = QuickSearchForm(request=request, initial={'search_query': result['search_query']})
|
|
|
|
- return request.theme.render_to_response('search/results.html',
|
|
|
|
- {
|
|
|
|
- 'form': FormFields(form),
|
|
|
|
- 'search_route': search_route,
|
|
|
|
- 'search_query': result['search_query'],
|
|
|
|
- 'results': items[pagination['start']:pagination['stop']],
|
|
|
|
- 'disable_search': True,
|
|
|
|
- 'items_total': items_total,
|
|
|
|
- 'pagination': pagination,
|
|
|
|
- },
|
|
|
|
- context_instance=RequestContext(request))
|
|
|
|
|
|
+ try:
|
|
|
|
+ form = self.search_form_type()(self.request.POST, request=self.request)
|
|
|
|
+ if form.is_valid():
|
|
|
|
+ if form.mode == 'forum':
|
|
|
|
+ jump_to = Forum.objects.forum_by_name(form.target, self.request.acl)
|
|
|
|
+ if jump_to:
|
|
|
|
+ if jump_to.level == 1:
|
|
|
|
+ return redirect(reverse('index') + ('#%s' % jump_to.slug))
|
|
|
|
+ return redirect(jump_to.url)
|
|
|
|
+ else:
|
|
|
|
+ raise SearchException(_('Forum "%(forum)s" could not be found.') % {'forum': form.target})
|
|
|
|
+ if form.mode == 'user':
|
|
|
|
+ self.request.POST = self.request.POST.copy()
|
|
|
|
+ self.request.POST['username'] = form.target
|
|
|
|
+ return users_list(self.request)
|
|
|
|
+ sqs = RelatedSearchQuerySet().auto_query(form.cleaned_data['search_query']).order_by('-id').load_all()
|
|
|
|
+ sqs = sqs.load_all_queryset(Post, self.queryset().filter(deleted=False).filter(moderated=False).select_related('thread', 'forum', 'user'))[:60]
|
|
|
|
+
|
|
|
|
+ if self.request.user.is_authenticated():
|
|
|
|
+ self.request.user.last_search = timezone.now()
|
|
|
|
+ self.request.user.save(force_update=True)
|
|
|
|
+ if self.request.user.is_anonymous():
|
|
|
|
+ self.request.session['last_search'] = timezone.now()
|
|
|
|
+
|
|
|
|
+ if not sqs:
|
|
|
|
+ raise SearchException(_("Search returned no results. Change search query and try again."))
|
|
|
|
+ self.request.session[self.results_route] = {
|
|
|
|
+ 'search_query': form.cleaned_data['search_query'],
|
|
|
|
+ 'search_results': [p.object for p in sqs],
|
|
|
|
+ }
|
|
|
|
+ return redirect(reverse(self.results_route))
|
|
|
|
+ else:
|
|
|
|
+ if 'search_query' in form.errors:
|
|
|
|
+ raise SearchException(form.errors['search_query'][0])
|
|
|
|
+ raise SearchException(form.errors['__all__'][0])
|
|
|
|
+ except SearchException as e:
|
|
|
|
+ return self.render_to_response('error', form,
|
|
|
|
+ {'message': unicode(e)})
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class ResultsBaseView(ViewBase):
|
|
|
|
+ def call(self, **kwargs):
|
|
|
|
+ result = self.request.session.get(self.results_route)
|
|
|
|
+ if not result:
|
|
|
|
+ form = self.search_form_type()(request=self.request)
|
|
|
|
+ return self.render_to_response('error', form,
|
|
|
|
+ {'message': _("No search results were found.")})
|
|
|
|
+
|
|
|
|
+ items = result['search_results']
|
|
|
|
+ items_total = len(items);
|
|
|
|
+ try:
|
|
|
|
+ pagination = make_pagination(kwargs.get('page', 0), items_total, 12)
|
|
|
|
+ except Http404:
|
|
|
|
+ return redirect(reverse(self.search_route))
|
|
|
|
|
|
|
|
+ form = self.search_form_type()(request=self.request, initial={'search_query': result['search_query']})
|
|
|
|
+ return self.render_to_response('results', form,
|
|
|
|
+ {
|
|
|
|
+ 'search_query': result['search_query'],
|
|
|
|
+ 'results': items[pagination['start']:pagination['stop']],
|
|
|
|
+ 'items_total': items_total,
|
|
|
|
+ 'pagination': pagination,
|
|
|
|
+ })
|