summaryrefslogtreecommitdiffstats
path: root/askbot/search/state_manager.py
diff options
context:
space:
mode:
Diffstat (limited to 'askbot/search/state_manager.py')
-rw-r--r--askbot/search/state_manager.py85
1 files changed, 82 insertions, 3 deletions
diff --git a/askbot/search/state_manager.py b/askbot/search/state_manager.py
index b50a0405..f45f4bcc 100644
--- a/askbot/search/state_manager.py
+++ b/askbot/search/state_manager.py
@@ -9,7 +9,7 @@ import logging
ACTIVE_COMMANDS = (
'sort', 'search', 'query',
- 'reset_query', 'reset_author', 'reset_tags',
+ 'reset_query', 'reset_author', 'reset_tags', 'remove_tag',
'tags', 'scope', 'page_size', 'start_over',
'page'
)
@@ -24,6 +24,7 @@ class SearchState(object):
def __init__(self):
self.scope = const.DEFAULT_POST_SCOPE
self.query = None
+ self.search = None
self.tags = None
self.author = None
self.sort = const.DEFAULT_POST_SORT_METHOD
@@ -35,6 +36,9 @@ class SearchState(object):
def __str__(self):
out = 'scope=%s\n' % self.scope
out += 'query=%s\n' % self.query
+ if hasattr(self, 'search'):
+ manual_search = (self.search == 'search')
+ out += 'manual_search = %s\n' % str(manual_search)
if self.tags:
out += 'tags=%s\n' % ','.join(self.tags)
out += 'author=%s\n' % self.author
@@ -87,7 +91,7 @@ class SearchState(object):
self.reset()
#todo also relax if 'all' scope was clicked twice
- def update_from_user_input(self, input_dict, unprocessed_input = {}):
+ def update_from_user_input(self, input_dict):
#todo: this function will probably not
#fit the case of multiple parameters entered at the same tiem
if 'start_over' in input_dict:
@@ -119,6 +123,11 @@ class SearchState(object):
else:
self.tags = input_dict['tags']
+ if 'remove_tag' in input_dict and self.tags:
+ rm_set = set([input_dict['remove_tag']])
+ self.tags -= rm_set
+ return
+
#all resets just return
if 'reset_tags' in input_dict:
if self.tags:
@@ -135,6 +144,8 @@ class SearchState(object):
if 'reset_query' in input_dict:
self.reset_query()
+ if input_dict.get('sort', None) == 'relevance-desc':
+ self.reset_sort()
return
self.update_value('author', input_dict)
@@ -142,9 +153,16 @@ class SearchState(object):
if 'query' in input_dict:
self.update_value('query', input_dict)
self.sort = 'relevance-desc'
- elif 'search' in unprocessed_input:#a case of use nulling search query by hand
+ elif 'search' in input_dict:
+ #a case of use nulling search query by hand
+ #this branch corresponds to hitting search button manually
+ #when the search query is empty
self.reset_query()
return
+ elif askbot_settings.DECOUPLE_TEXT_QUERY_FROM_SEARCH_STATE:
+ #no query in the request and the setting instructs to
+ #not have the text search query sticky
+ self.reset_query()
if 'sort' in input_dict:
if input_dict['sort'] == 'relevance-desc' and self.query is None:
@@ -157,10 +175,29 @@ class SearchState(object):
if self.sort == 'relevance-desc':
self.reset_sort()
+ def update(self, input_dict, view_log, user):
+ """update the search state according to the
+ user input and the queue of the page hits that
+ user made"""
+ if 'preserve_state' in input_dict:
+ return
+
+ if view_log.should_reset_search_state():
+ self.reset()
+
+ if user.is_authenticated():
+ self.set_logged_in()
+
+ self.update_from_user_input(input_dict)
+ self.relax_stickiness(input_dict, view_log)
+
def reset_page(self):
self.page = 1
def reset_query(self):
+ """reset the search query string and
+ the associated "sort by relevance command"
+ """
if self.query:
self.query = None
self.reset_page()
@@ -172,3 +209,45 @@ class SearchState(object):
def reset_scope(self):
self.scope = const.DEFAULT_POST_SCOPE
+
+class ViewLog(object):
+ """The ViewLog helper obejcts store the trail of the page visits for a
+ given user. The trail is recorded only up to a certain depth.
+
+ The purpose to record this info is to reset the search state
+ when the user walks "too far away" from the search page.
+
+ These objects must be modified only in this middlware.
+ """
+ def __init__(self):
+ self.views = []
+ self.depth = 3 #todo maybe move this to const.py
+
+ def get_previous(self, num):
+ """get a previous record from a certain depth"""
+ if num > self.depth - 1:
+ raise Exception("view log depth exceeded")
+ elif num < 0:
+ raise Exception("num must be positive")
+ elif num <= len(self.views) - 1:
+ return self.views[num]
+ else:
+ return None
+
+ def should_reset_search_state(self):
+ """return True if user stepped too far from the home page
+ and False otherwise"""
+ return False
+ if self.get_previous(1) != 'questions':
+ if self.get_previous(2) != 'questions':
+ return True
+ return False
+
+ def set_current(self, view_name):
+ """insert a new record"""
+ self.views.insert(0, view_name)
+ if len(self.views) > self.depth:
+ self.views.pop()
+
+ def __str__(self):
+ return str(self.views) + ' depth=%d' % self.depth