bgneal@763: """Custom views for searching.""" bgneal@961: import logging bgneal@763: bgneal@961: from django.shortcuts import render_to_response 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@961: return render_to_response(self.template, context, bgneal@961: context_instance=self.context_class(self.request)) bgneal@961: bgneal@961: def extra_context(self): bgneal@961: return { bgneal@961: 'query_parser_error': self.query_parser_error, bgneal@961: }