Permalink
Browse files

[bug 687933] Port search view to oedipus.

  • Loading branch information...
2 parents ddd2e86 + 63b4009 commit 26302fe91f842bfd7c742c369de74b13db3afbad @erikrose erikrose committed Nov 1, 2011
View
@@ -13,6 +13,8 @@
from sumo.models import ModelBase
from search.utils import crc32
+from search import S
+
def _last_post_from(posts, exclude_post=None):
"""Return the most recent post in the given set, excluding the given post.
@@ -103,12 +105,6 @@ class Thread(NotificationsMixin, ModelBase):
class Meta:
ordering = ['-is_sticky', '-last_post__created']
- class SphinxMeta(object):
- index = 'discussion_forums'
- filter_mapping = {
- 'title': crc32,
- 'content': crc32}
-
def __setattr__(self, attr, val):
"""Notice when the forum field changes.
@@ -190,6 +186,10 @@ class Post(ActionMixin, ModelBase):
class Meta:
ordering = ['created']
+ class SphinxMeta(object):
+ index = 'discussion_forums'
+ filter_mapping = {'author_ord': crc32}
+
def __unicode__(self):
return self.content[:50]
@@ -251,3 +251,12 @@ def get_absolute_url(self):
@property
def content_parsed(self):
return wiki_to_html(self.content)
+
+
+# The index is on Post, but with the Thread.title for the Thread
+# related to the Post. We base the S off of Post because we need
+# to excerpt content.
+discussion_search = (
+ S(Post).weight(title=2, content=1)
+ .group_by('thread_id', '-@group')
+ .order_by('created'))
View
@@ -68,7 +68,9 @@ class Meta:
class SphinxMeta(object):
index = 'questions'
filter_mapping = {
- 'tag': crc32}
+ 'tag': crc32,
+ 'question_creator': crc32,
+ 'answer_creator': crc32}
id_field = 'question_id'
def __unicode__(self):
@@ -495,12 +497,12 @@ def _has_beta(version, dev_releases):
def _content_parsed(obj):
- cache_key = obj.html_cache_key % obj.id
- html = cache.get(cache_key)
- if html is None:
- html = wiki_to_html(obj.content)
- cache.add(cache_key, html)
- return html
+ cache_key = obj.html_cache_key % obj.id
+ html = cache.get(cache_key)
+ if html is None:
+ html = wiki_to_html(obj.content)
+ cache.add(cache_key, html)
+ return html
question_search = (
View
@@ -5,9 +5,6 @@
import oedipus
from tower import ugettext_lazy as _lazy
-from search.sphinxapi import (SPH_SORT_ATTR_DESC, SPH_SORT_ATTR_ASC,
- SPH_SORT_EXTENDED, SPH_GROUPBY_ATTR)
-
WHERE_WIKI = 1
WHERE_SUPPORT = 2
@@ -25,10 +22,10 @@
)
GROUPSORT = (
- '@relevance DESC, age ASC', # default
- 'updated DESC',
- 'created DESC',
- 'replies DESC',
+ ('-@relevance', 'age'), # default
+ '-updated',
+ '-created',
+ '-replies',
)
# For discussion forums
@@ -66,11 +63,10 @@
)
SORT_QUESTIONS = (
- #: (mode, clause)
- (SPH_SORT_EXTENDED, '@relevance DESC, age ASC'), # default
- (SPH_SORT_ATTR_DESC, 'updated'),
- (SPH_SORT_ATTR_DESC, 'created'),
- (SPH_SORT_ATTR_DESC, 'replies'),
+ ('-@relevance', 'age'), # default
+ ('updated',),
+ ('created',),
+ ('replies',)
)
SORTBY_QUESTIONS = (
View
@@ -1,174 +0,0 @@
-import logging
-import os
-import re
-import socket
-
-from django.conf import settings
-from django.utils.encoding import smart_unicode
-
-import bleach
-
-from search import sphinxapi
-
-
-log = logging.getLogger('k.search')
-
-
-class SearchError(Exception):
- """An error occurred executing a search."""
-
-
-class SearchClient(object):
- """
- Base-class for search clients
- """
-
- match_mode = sphinxapi.SPH_MATCH_EXTENDED2
- rank_mode = sphinxapi.SPH_RANK_PROXIMITY_BM25
- sort_mode = (sphinxapi.SPH_SORT_RELEVANCE, '')
-
- def __init__(self):
- self.sphinx = sphinxapi.SphinxClient()
- if os.environ.get('DJANGO_ENVIRONMENT') == 'test':
- self.sphinx.SetServer(settings.SPHINX_HOST,
- settings.TEST_SPHINX_PORT)
- else:
- self.sphinx.SetServer(settings.SPHINX_HOST, settings.SPHINX_PORT)
-
- self.sphinx.SetMatchMode(self.match_mode)
- self.sphinx.SetRankingMode(self.rank_mode)
- self.sphinx.SetSortMode(*self.sort_mode)
-
- def _prepare_filters(self, filters=None):
- """Process filters and filter ranges."""
- sc = self.sphinx
- sc.ResetFilters()
- if filters is None:
- filters = []
-
- for f in filters:
- if f.get('exclude') and not f.get('value'):
- # Sphinx doesn't like excluding nothing: excludes everything.
- continue
- if f.get('range', False):
- sc.SetFilterRange(f['filter'], f['min'],
- f['max'], f.get('exclude', False))
- else:
- sc.SetFilter(f['filter'], f['value'],
- f.get('exclude', False))
-
- def _prepare(self):
- """Override to twiddle `self.sphinx` before the query gets sent."""
-
- def _sanitize_query(self, query):
- """Strip control characters that cause problems."""
- query = re.sub(r'(?<=\S)\-', '\-', query)
- return query.replace('^', '').replace('$', '')
-
- def _query_sphinx(self, query=''):
- """
- Pass the query to the SphinxClient() and return the results.
-
- Catches common exceptions raised by Sphinx.
- """
-
- query = self._sanitize_query(query)
-
- try:
- result = self.sphinx.Query(query, self.index)
- except socket.timeout:
- log.error('Query has timed out!')
- raise SearchError('Query has timed out!')
- except socket.error, msg:
- log.error('Query socket error: %s' % msg)
- raise SearchError('Could not execute your search!')
- except Exception, e:
- log.error('Sphinx threw an unknown exception: %s' % e)
- raise SearchError('Sphinx threw an unknown exception!')
-
- if result:
- return result['matches']
- else:
- return []
-
- def query(self, query, filters=None, offset=0,
- limit=settings.SEARCH_MAX_RESULTS):
- """Query the search index."""
- self._prepare_filters(filters)
-
- self.sphinx.SetFieldWeights(self.weights)
- self.sphinx.SetLimits(offset, limit)
-
- self._prepare()
- return self._query_sphinx(query)
-
- def excerpt(self, result, query):
- """
- Given document content and a search query (both strings), uses
- Sphinx to build an excerpt, highlighting the keywords from the
- query.
-
- Length of the final excerpt is roughly determined by
- SEARCH_SUMMARY_LENGTH in settings.py.
- """
- if not isinstance(result, basestring):
- return ''
- documents = [result]
-
- try:
- # build excerpts that are longer and truncate
- # see multiplier constant definition for details
- excerpt = self.sphinx.BuildExcerpts(
- documents, self.index, query,
- {'limit': settings.SEARCH_SUMMARY_LENGTH})[0]
- except socket.error:
- log.error('Socket error building excerpt!')
- excerpt = ''
- except socket.timeout:
- log.error('Building excerpt timed out!')
- excerpt = ''
-
- return bleach.clean(smart_unicode(excerpt))
-
- def set_sort_mode(self, mode, clause=''):
- self.sphinx.SetSortMode(mode, clause)
-
-
-class QuestionsClient(SearchClient):
- index = 'questions'
- weights = {'title': 4, 'question_content': 3, 'answer_content': 3}
- groupsort = '@group desc'
-
- def _prepare(self):
- """Prepare to group the answers together."""
- super(QuestionsClient, self)._prepare()
- self.sphinx.SetGroupBy('question_id', sphinxapi.SPH_GROUPBY_ATTR,
- self.groupsort)
-
-
-class WikiClient(SearchClient):
- """
- Search the knowledge base
- """
- index = 'wiki_pages'
- weights = {'title': 6, 'content': 1, 'keywords': 4, 'summary': 2}
-
-
-class DiscussionClient(SearchClient):
- """
- Search the discussion forums.
- """
- index = 'discussion_forums'
- weights = {'title': 2, 'content': 1}
- groupsort = '@group desc'
- sort_mode = (sphinxapi.SPH_SORT_ATTR_ASC, 'created')
-
- def _prepare(self):
- """Group posts together, and ensure thread['attrs']['updated'] is the
- last post's updated date.
-
- """
- super(DiscussionClient, self)._prepare()
- self.sphinx.SetGroupBy('thread_id', sphinxapi.SPH_GROUPBY_ATTR,
- self.groupsort)
- self.sphinx.SetSortMode(*self.sort_mode)
Oops, something went wrong.

0 comments on commit 26302fe

Please sign in to comment.