6
6
from sunburnt import SolrInterface
7
7
from pyramid .view import view_config
8
8
from pyramid .url import current_route_url
9
- from por .models .dashboard import Trac
9
+ from por .models .dashboard import Trac , User
10
10
from por .models import DBSession
11
11
from por .dashboard .lib .widgets import SearchButton , PorInlineForm
12
12
from deform_bootstrap .widget import ChosenMultipleWidget
@@ -41,18 +41,29 @@ def searchable_tracs(request):
41
41
42
42
43
43
class SearchSchema (colander .MappingSchema ):
44
+
44
45
tracs = colander .SchemaNode (deform .Set (allow_empty = True ),
45
- widget = ChosenMultipleWidget (placeholder = u'Select tracs' ),
46
- missing = colander .null ,
47
- title = u'' )
46
+ widget = ChosenMultipleWidget (placeholder = u'Select tracs' ,
47
+ style = "width:250px" ),
48
+ missing = colander .null ,
49
+ title = u'' )
50
+
48
51
realms = colander .SchemaNode (deform .Set (allow_empty = True ),
49
- widget = ChosenMultipleWidget (placeholder = u'Select realms' ,
50
- values = [('' , '' ),
51
- ('ticket' , 'Ticket' ),
52
- ('wiki' , 'Wiki' ),
53
- ('changeset' ,'Changeset' )]),
54
- missing = colander .null ,
55
- title = u'' )
52
+ widget = ChosenMultipleWidget (placeholder = u'Select realms' ,
53
+ style = "width:250px" ,
54
+ values = [('' , '' ),
55
+ ('ticket' , 'Ticket' ),
56
+ ('wiki' , 'Wiki' ),
57
+ ('changeset' ,'Changeset' )]),
58
+ missing = colander .null ,
59
+ title = u'' )
60
+
61
+ authors = colander .SchemaNode (deform .Set (allow_empty = True ),
62
+ widget = ChosenMultipleWidget (placeholder = u'Select author' ,
63
+ style = "width:250px" ),
64
+ missing = colander .null ,
65
+ title = u'' )
66
+
56
67
searchable = colander .SchemaNode (typ = colander .String (),
57
68
title = u'' ,
58
69
widget = deform .widget .TextInputWidget (
@@ -72,7 +83,12 @@ def search(request):
72
83
)
73
84
74
85
tracs = searchable_tracs (request )
75
- form ['tracs' ].widget .values = [('' , '' )] + [(t .trac_name , t .project_name ) for t in tracs ]
86
+ form ['tracs' ].widget .values = [('' , '' )] \
87
+ + [(t .trac_name , t .project_name ) for t in tracs ]
88
+
89
+ users = DBSession .query (User ).order_by (User .fullname )
90
+ form ['authors' ].widget .values = [('' , '' )] \
91
+ + [(a .email , a .fullname ) for a in users ]
76
92
77
93
controls = request .GET .items ()
78
94
if not controls :
@@ -96,37 +112,45 @@ def search(request):
96
112
97
113
if results :
98
114
docs = [FullTextSearchObject (** doc ) for doc in results ]
99
- base_query = dict (request .params )
100
115
records_len = results .result .numFound
101
116
if not fs .page_start + fs .page_size >= records_len : # end of set
102
- next_query = base_query .copy ()
103
- next_query ['page_start' ] = fs .page_start + fs .page_size
117
+ next_query = add_param (request , 'page_start' , fs .page_start + fs .page_size )
104
118
next_url = current_route_url (request , _query = next_query )
105
119
106
120
if not fs .page_start == 0 :
107
121
previous_page = fs .page_start - fs .page_size
108
122
if previous_page < 0 :
109
123
previous_page = 0
110
- previous_query = base_query .copy ()
111
- previous_query ['page_start' ] = previous_page
124
+ previous_query = add_param (request , 'page_start' , previous_page )
112
125
previous_url = current_route_url (request , _query = previous_query )
113
126
114
127
return {'docs' : docs ,
115
128
'next' : next_url ,
116
129
'form' : form .render (appstruct = appstruct ),
117
130
'previous' : previous_url ,
131
+ 'add_param' : add_param ,
118
132
'results' : results }
119
133
120
134
135
+ def add_param (request , key , value ):
136
+ base_query = request .params .copy ()
137
+ base_query [key ] = value
138
+ return base_query
139
+
140
+
121
141
class FullTextSearch (object ):
122
142
123
- def __init__ (self , request , tracs = None , searchable = None , realms = None ):
143
+ def __init__ (self , request , tracs = None , searchable = None ,
144
+ realms = None , authors = None ):
124
145
if not realms :
125
146
realms = []
147
+ if not authors :
148
+ authors = []
126
149
self .request = request
127
- self .viewable_tracs = list (tracs )
128
150
self .searchable = searchable .split (' ' ) # always a sequence
151
+ self .viewable_tracs = list (tracs )
129
152
self .realms = list (realms )
153
+ self .authors = list (authors )
130
154
self .solr_endpoint = request .registry .settings .get ('por.solr' )
131
155
132
156
@property
@@ -193,6 +217,21 @@ def query(items):
193
217
return ""
194
218
return query (self .realms )
195
219
220
+ def _build_author_filter (self , si ):
221
+
222
+ Q = si .query ().Q
223
+
224
+ def query (items ):
225
+ if len (items ) > 2 :
226
+ return Q (author = items .pop ()) | query (items )
227
+ elif len (items ) == 2 :
228
+ return Q (author = items .pop ()) | Q (author = items .pop ())
229
+ elif len (items ) == 1 :
230
+ return Q (author = items .pop ())
231
+ else :
232
+ return ""
233
+ return query (self .authors )
234
+
196
235
def _do_search (self , sort_by = None ):
197
236
si = SolrInterface (self .solr_endpoint )
198
237
query = si .query ().field_limit (score = True )
@@ -204,6 +243,10 @@ def _do_search(self, sort_by=None):
204
243
if realm_query :
205
244
query = query .filter (realm_query )
206
245
246
+ author_query = self ._build_author_filter (si )
247
+ if author_query :
248
+ query = query .filter (author_query )
249
+
207
250
trac_query = self ._build_trac_filter (si )
208
251
if trac_query :
209
252
query = query .filter (trac_query )
@@ -253,7 +296,7 @@ def __init__(self, project, realm, id=None, score=None,
253
296
if not author :
254
297
author = ()
255
298
self .project = project
256
- self .author = ', ' .join (author + involved )
299
+ self .author = ', ' .join (author )
257
300
self .created = created
258
301
self .popularity = popularity
259
302
self .comments = comments
0 commit comments