summaryrefslogtreecommitdiffstats
path: root/forum/search/state_manager.py
diff options
context:
space:
mode:
Diffstat (limited to 'forum/search/state_manager.py')
-rw-r--r--forum/search/state_manager.py152
1 files changed, 152 insertions, 0 deletions
diff --git a/forum/search/state_manager.py b/forum/search/state_manager.py
new file mode 100644
index 00000000..cb1908c6
--- /dev/null
+++ b/forum/search/state_manager.py
@@ -0,0 +1,152 @@
+#search state manager object
+#that lives in the session and takes care of the state
+#persistece during the search session
+from forum import const
+import logging
+
+ACTIVE_COMMANDS = (
+ 'sort', 'search', 'query',
+ 'reset_query', 'reset_author', 'reset_tags',
+ 'tags', 'scope', 'page_size', 'start_over',
+ 'page'
+)
+
+def some_in(what, where):
+ for element in what:
+ if element in where:
+ return True
+ return False
+
+class SearchState(object):
+ def __init__(self):
+ self.scope= const.DEFAULT_POST_SCOPE
+ self.query = None
+ self.tags = None
+ self.author = None
+ self.sort = const.DEFAULT_POST_SORT_METHOD
+ self.page_size = const.DEFAULT_QUESTIONS_PAGE_SIZE
+ self.page = 1
+ self.logged_in = False
+ logging.debug('new search state initialized')
+
+ def __str__(self):
+ out = 'scope=%s\n' % self.scope
+ out += 'query=%s\n' % self.query
+ if self.tags:
+ out += 'tags=%s\n' % ','.join(self.tags)
+ out += 'author=%s\n' % self.author
+ out += 'sort=%s\n' % self.sort
+ out += 'page_size=%d\n' % self.page_size
+ out += 'page=%d\n' % self.page
+ out += 'logged_in=%s\n' % str(self.logged_in)
+ return out
+
+ def set_logged_out(self):
+ if self.scope == 'favorite':
+ self.scope = None
+ self.logged_in = False
+
+ def set_logged_in(self):
+ self.logged_in = True
+
+ def reset(self):
+ #re-initialize, but keep login state
+ is_logged_in = self.logged_in
+ self.__init__()
+ self.logged_in = is_logged_in
+
+ def update_value(self, key, store):
+ if key in store:
+ old_value = getattr(self, key)
+ new_value = store[key]
+ if new_value != old_value:
+ setattr(self, key, new_value)
+ self.reset_page()
+
+ def relax_stickiness(self, input, view_log):
+ if view_log.get_previous(1) == 'questions':
+ if not some_in(ACTIVE_COMMANDS, input):
+ self.reset()
+ #todo also relax if 'all' scope was clicked twice
+
+ def update_from_user_input(self,input,raw_input = {}):
+ #todo: this function will probably not
+ #fit the case of multiple parameters entered at the same tiem
+ if 'start_over' in input:
+ self.reset()
+
+ if 'page' in input:
+ self.page = input['page']
+ #special case - on page flip no other input is accepted
+ return
+
+ if 'page_size' in input:
+ self.update_value('page_size',input)
+ self.reset_page()#todo may be smarter here - start with ~same q
+ #same as with page - return right away
+ return
+
+ if 'scope' in input:
+ if input['scope'] == 'favorite' and self.logged_in == False:
+ self.reset_scope()
+ else:
+ self.update_value('scope',input)
+
+ if 'tags' in input:
+ if self.tags:
+ old_tags = self.tags.copy()
+ self.tags = self.tags.union(input['tags'])
+ if self.tags != old_tags:
+ self.reset_page()
+ else:
+ self.tags = input['tags']
+
+ #all resets just return
+ if 'reset_tags' in input:
+ if self.tags:
+ self.tags = None
+ self.reset_page()
+ return
+
+ #todo: handle case of deleting tags one-by-one
+ if 'reset_author' in input:
+ if self.author:
+ self.author = None
+ self.reset_page()
+ return
+
+ if 'reset_query' in input:
+ self.reset_query()
+ return
+
+ self.update_value('author',input)
+
+ if 'query' in input:
+ self.update_value('query',input)
+ self.sort = 'relevant'
+ elif 'search' in raw_input:#a case of use nulling search query by hand
+ self.reset_query()
+ return
+
+
+ if 'sort' in input:
+ if input['sort'] == 'relevant' and self.query is None:
+ self.reset_sort()
+ else:
+ self.update_value('sort',input)
+
+ def reset_page(self):
+ self.page = 1
+
+ def reset_query(self):
+ if self.query:
+ self.query = None
+ self.reset_page()
+ if self.sort == 'relevant':
+ self.reset_sort()
+
+ def reset_sort(self):
+ self.sort = const.DEFAULT_POST_SORT_METHOD
+
+ def reset_scope(self):
+ self.scope = const.DEFAULT_POST_SCOPE