1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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
|