diff --git a/apps/search/__init__.py b/apps/search/__init__.py
index 2d9286beab1..876f8ae0507 100644
--- a/apps/search/__init__.py
+++ b/apps/search/__init__.py
@@ -1,7 +1,6 @@
from .utils import crc32
# TODO: use lazy gettext, as in zamboni
-import gettext
from django.utils.translation import ugettext
WHERE_WIKI = 1
@@ -42,20 +41,27 @@
)
# reverse lookup
STATUS_ALIAS_REVERSE = {
+ STATUS_ALIAS_NO: (),
STATUS_ALIAS_NH: (STATUS_NORMAL, STATUS_ORIGINALREPLY),
STATUS_ALIAS_HA: (STATUS_PROPOSED, STATUS_REQUEST),
STATUS_ALIAS_SO: (STATUS_SOLVED,),
STATUS_ALIAS_AR: (STATUS_ARCHIVE,),
- STATUS_ALIAS_OT: (STATUS_LOCKED, STATUS_STICKY, STATUS_ANNOUNCE, STATUS_INVALID, STATUS_HOT),
+ STATUS_ALIAS_OT: (STATUS_LOCKED, STATUS_STICKY, STATUS_ANNOUNCE,
+ STATUS_INVALID, STATUS_HOT,),
}
+CREATED_NONE = 0
+CREATED_BEFORE = 1
+CREATED_AFTER = 2
CREATED_LIST = (
- (0, ugettext('Don\'t filter')),
- (1, ugettext('Before')),
- (2, ugettext('After')),
+ (CREATED_NONE, ugettext('Don\'t filter')),
+ (CREATED_BEFORE, ugettext('Before')),
+ (CREATED_AFTER, ugettext('After')),
)
+# multiplier
+LUP_MULTIPLIER = 86400 # one day
LUP_LIST = (
(0, "Don't filter"),
(1, "Last 24 hours"),
diff --git a/apps/search/templates/form.html b/apps/search/templates/form.html
index ed350139708..ea7709b51a5 100644
--- a/apps/search/templates/form.html
+++ b/apps/search/templates/form.html
@@ -69,7 +69,7 @@
{{ search_form.created.label_tag()|safe }}
{{ search_form.created|safe }}
-
+
diff --git a/apps/search/views.py b/apps/search/views.py
index 7319c539170..2c27b2d434a 100644
--- a/apps/search/views.py
+++ b/apps/search/views.py
@@ -10,6 +10,7 @@
from django.core.urlresolvers import reverse
import jingo
+import time
from sumo.utils import paginate
from sumo.models import ForumThread, WikiPage, Forum, Category
@@ -24,26 +25,30 @@
def search(request):
+ """Performs search or displays the search form"""
+
+ # set up form
search_form = SearchForm(request.GET.copy())
+ # set up query variables
q = request.GET.get('q', '')
- refine_query = {'q': q}
locale = request.GET.get('locale', request.LANGUAGE_CODE)
- sphinx_locale = (crc32(locale),)
- refine_query['locale'] = locale
+ language = request.GET.get('language', locale)
+ sphinx_locale = (crc32(language),)
where = int(request.GET.get('w', CONSTANTS.WHERE_ALL))
- refine_query['w'] = where
page = int(request.GET.get('page', 1))
page = max(page, 1)
offset = (page-1) * settings.SEARCH_RESULTS_PER_PAGE
- if (len(q) <= 0 or (request.GET.get('a', '0') == '1')):
+ # no query or advanced search?
+ # => return empty form
+ if (not q or (request.GET.get('a', '0') == '1')):
return jingo.render(request, 'form.html',
{'locale': request.LANGUAGE_CODE,
- 'advanced': request.GET.get('a', '0'),
+ 'advanced': request.GET.get('a'),
'request': request,
'w': where, 'search_form': search_form,
})
@@ -54,18 +59,14 @@ def search(request):
wc = WikiClient() # Wiki SearchClient instance
filters_w = [] # filters for the wiki search
- # Category filter
- categories = request.GET.get('category[]',
- settings.SEARCH_DEFAULT_CATEGORIES)
+ # Category filter
+ categories = request.GET.getlist('category') or \
+ settings.SEARCH_DEFAULT_CATEGORIES
filters_w.append({
'filter': 'category',
- 'value': map(int,
- categories.split(',')),
+ 'value': map(int, categories),
})
- refine_query['category[]'] = categories
- #for category in categories:
- # refine_query['category[]'].append(category)
# Locale filter
@@ -74,15 +75,15 @@ def search(request):
'value': sphinx_locale,
})
+
# Tag filter
- tag = request.GET.get('tag', '')
- if (tag is not None) and len(tag) > 0:
+ tag = request.GET.get('tag', None)
+ if tag:
filters_w.append({
'filter': 'tag',
'value': map(crc32, request.GET.get('tag').split(',')),
})
- refine_query['tag'] = tag
# execute the query and append to documents
documents += wc.query(q, filters_w)
@@ -95,34 +96,90 @@ def search(request):
filters_f.append({
'filter': 'forumId',
'value': map(int,
- request.GET.get('forums',
- settings.SEARCH_DEFAULT_FORUM).split(',')),
+ request.GET.getlist('fid') or \
+ settings.SEARCH_DEFAULT_FORUMS),
})
# Status filter
- if request.GET.get('status') is not None:
- """filters_f.append({
- 'filter': 'status',
- 'value': STATUS_LIST[request.GET.get('status')],
- })"""
+ status = int(request.GET.get('status'))
+ # no replies case is not stored in status
+ if status == CONSTANTS.STATUS_ALIAS_NR:
+ filters_f.append({
+ 'filter': 'replies',
+ 'value': (0,),
+ })
- refine_query['status'] = request.GET.get('status', '0')
+ # avoid filtering by status
+ status = None
+
+ if status:
+ filters_f.append({
+ 'filter': 'status',
+ 'value': CONSTANTS.STATUS_ALIAS_REVERSE[int(
+ request.GET.get('status'))],
+ })
# Author filter
- if request.GET.get('author') is not None:
+ if request.GET.get('author'):
filters_f.append({
- 'filter': 'author',
+ 'filter': 'author_ord',
'value': (crc32(request.GET.get('author')),
crc32(request.GET.get('author') + ' (anon)'),),
})
- refine_query['author'] = request.GET.get('author', '')
-
+ unix_now = int(time.time())
# Created filter
- if request.GET.get('created') is not None:
+ created = int(request.GET.get('created'))
+ created_date = request.GET.get('created_date')
+
+ if not created_date:
+ # no date => no filtering
+ created = None
+ else:
+ try:
+ created_date = int(time.mktime(
+ time.strptime(created_date, '%m/%d/%Y'),
+ ))
+ except ValueError:
+ created = None
+
+
+ if not created:
pass
- refine_query['created'] = request.GET.get('created', '')
+ elif created == CONSTANTS.CREATED_BEFORE:
+ filters_f.append({
+ 'range': True,
+ 'filter': 'created',
+ 'min': 0,
+ 'max': created_date,
+ })
+
+ elif created == CONSTANTS.CREATED_AFTER:
+ filters_f.append({
+ 'range': True,
+ 'filter': 'created',
+ 'min': created_date,
+ 'max': int(unix_now),
+ })
+
+
+ # Last modified filter
+ lastmodif = int(request.GET.get('lastmodif'))
+
+ if not lastmodif:
+ pass
+
+ else:
+ filters_f.append({
+ 'range': True,
+ 'filter': 'created',
+ 'min': unix_now - CONSTANTS.LUP_MULTIPLIER * lastmodif,
+ 'max': unix_now,
+ })
+
+ # Sort results by
+
documents += fc.query(q, filters_f)
diff --git a/apps/sumo/models.py b/apps/sumo/models.py
index 3b3fb9ea1ca..53e3b8f6bbe 100644
--- a/apps/sumo/models.py
+++ b/apps/sumo/models.py
@@ -52,7 +52,8 @@ class Forum(ModelBase):
moderator_group = models.CharField(max_length=200, null=True)
approval_type = models.CharField(max_length=20, null=True)
outbound_address = models.CharField(max_length=250, null=True)
- outbound_mails_for_inbound_mails = models.CharField(max_length=1, null=True)
+ outbound_mails_for_inbound_mails = models.CharField(max_length=1,
+ null=True)
outbound_mails_reply_link = models.CharField(max_length=1, null=True)
outbound_from = models.CharField(max_length=250, null=True)
inbound_pop_server = models.CharField(max_length=250, null=True)
@@ -124,10 +125,6 @@ def __unicode__(self):
def name(self):
return self.title
- @property
- def search_summary(self):
- return self.summary
-
def get_url(self):
"""
TODO: Once we can use reverse(), use reverse()
@@ -192,4 +189,3 @@ class Meta:
def __unicode__(self):
return self.name
-
diff --git a/settings.py b/settings.py
index 861791a075e..2efbf46bf6c 100644
--- a/settings.py
+++ b/settings.py
@@ -7,7 +7,7 @@
LOG_LEVEL = logging.DEBUG
ROOT = os.path.dirname(os.path.abspath(__file__))
-path = lambda *a: os.path.join(ROOT, *a)
+path = lambda * a: os.path.join(ROOT, * a)
ADMINS = (
# ('Your Name', 'your_email@domain.com'),
@@ -17,12 +17,18 @@
DATABASES = {
'default': {
- 'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
- 'NAME': 'kitsune', # Or path to database file if using sqlite3.
- 'USER': '', # Not used with sqlite3.
- 'PASSWORD': '', # Not used with sqlite3.
- 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
- 'PORT': '', # Set to empty string for default. Not used with sqlite3.
+ # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+ 'ENGINE': 'django.db.backends.mysql',
+ # Or path to database file if using sqlite3.
+ 'NAME': 'kitsune',
+ # Not used with sqlite3.
+ 'USER': '',
+ # Not used with sqlite3.
+ 'PASSWORD': '',
+ # Set to empty string for localhost. Not used with sqlite3.
+ 'HOST': '',
+ # Set to empty string for default. Not used with sqlite3.
+ 'PORT': '',
'OPTIONS': {'init_command': 'SET storage_engine=InnoDB'},
}
}
@@ -83,7 +89,7 @@
'django.core.context_processors.debug',
'django.core.context_processors.media',
'django.core.context_processors.request',
- 'django.contrib.messages.context_processors.messages'
+ 'django.contrib.messages.context_processors.messages',
)
MIDDLEWARE_CLASSES = (
@@ -135,8 +141,9 @@
#
# Search default settings
-SEARCH_DEFAULT_CATEGORIES = '1,17,18' # comma-separated string of category IDs
-SEARCH_DEFAULT_FORUM = '1' # default forum ID (eg: 1 on sumo, 5 on mosumo)
+# comma-separated tuple of category IDs
+SEARCH_DEFAULT_CATEGORIES = (1, 17, 18)
+SEARCH_DEFAULT_FORUMS = (1,) # default forum ID (eg: 1 on sumo, 5 on mosumo)
SEARCH_SUMMARY_LENGTH = 275
# because of markup cleanup, search summaries lengths vary quite a bit
# so we extract longer excerpts and perform truncation to the length above