diff options
Diffstat (limited to 'askbot/search/state_manager.py')
-rw-r--r-- | askbot/search/state_manager.py | 85 |
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 |