bgneal@763: """Custom views for searching."""
bgneal@961: import logging
bgneal@763: 
bgneal@1032: from django.shortcuts import render
bgneal@763: from haystack.views import SearchView
bgneal@961: from xapian import QueryParserError
bgneal@763: 
bgneal@961: logger = logging.getLogger(__name__)
bgneal@763: 
bgneal@763: class UserSearchView(SearchView):
bgneal@763:     """This class passes the user making the search as an __init__ argument to
bgneal@763:     the search form as the keyword argument 'user'.
bgneal@763: 
bgneal@763:     """
bgneal@961:     query_parser_error = False
bgneal@961: 
bgneal@763:     def build_form(self, form_kwargs=None):
bgneal@763:         """Pass the request.user object to the form's constructor."""
bgneal@763:         if not form_kwargs:
bgneal@763:             form_kwargs = {}
bgneal@763:         if 'user' not in form_kwargs:
bgneal@763:             form_kwargs['user'] = self.request.user
bgneal@763:         return super(UserSearchView, self).build_form(form_kwargs)
bgneal@961: 
bgneal@961:     # This nonsense is because Xapian can raise QueryParserError when evaluating
bgneal@961:     # the query. This was triggered by some sh*t-bag looking for SQL injection
bgneal@961:     # vulnerabilities.
bgneal@961:     # If QueryParserError is raised, just drive on and set a flag in the context
bgneal@961:     # (via extra_context()) so that an error is rendered on the template instead
bgneal@961:     # of a 500 error.
bgneal@961: 
bgneal@961:     def create_response(self):
bgneal@961:         try:
bgneal@961:             return super(UserSearchView, self).create_response()
bgneal@961:         except QueryParserError:
bgneal@961:             self.query_parser_error = True
bgneal@961: 
bgneal@961:         logger.warning("QueryParserError triggered from user search input")
bgneal@961: 
bgneal@961:         context = {
bgneal@961:             'query': self.query,
bgneal@961:             'form': self.form,
bgneal@961:             'page': None,
bgneal@961:             'paginator': None,
bgneal@961:             'suggestion': None,
bgneal@961:         }
bgneal@961: 
bgneal@961:         context.update(self.extra_context())
bgneal@1032:         return render(self.request, self.template, context)
bgneal@961: 
bgneal@961:     def extra_context(self):
bgneal@961:         return {
bgneal@961:             'query_parser_error': self.query_parser_error,
bgneal@1127:             'V3_DESIGN': True,
bgneal@961:         }