@@ -41,11 +41,17 @@ def searchable_tracs(request):
41
41
42
42
class SearchSchema (colander .MappingSchema ):
43
43
tracs = colander .SchemaNode (deform .Set (allow_empty = True ),
44
- widget = ChosenMultipleWidget (css_class = 'trac-select' ,
45
- placeholder = u'Select tracs' ),
44
+ widget = ChosenMultipleWidget (placeholder = u'Select tracs' ),
45
+ missing = colander .null ,
46
+ title = u'' )
47
+ realms = colander .SchemaNode (deform .Set (allow_empty = True ),
48
+ widget = ChosenMultipleWidget (placeholder = u'Select realms' ,
49
+ values = [('' , '' ),
50
+ ('ticket' , 'Ticket' ),
51
+ ('wiki' , 'Wiki' ),
52
+ ('changeset' ,'Changeset' )]),
46
53
missing = colander .null ,
47
54
title = u'' )
48
-
49
55
searchable = colander .SchemaNode (typ = colander .String (),
50
56
title = u'' ,
51
57
widget = deform .widget .TextInputWidget (
@@ -71,7 +77,6 @@ def search(request):
71
77
if not controls :
72
78
return {'form' : form .render (),
73
79
'results' :[]}
74
-
75
80
try :
76
81
appstruct = form .validate (controls )
77
82
except deform .ValidationFailure as e :
@@ -114,10 +119,11 @@ def search(request):
114
119
115
120
class FullTextSearch (object ):
116
121
117
- def __init__ (self , request , tracs = None , searchable = None ):
122
+ def __init__ (self , request , tracs = None , searchable = None , realms = None ):
118
123
self .request = request
119
124
self .viewable_tracs = list (tracs )
120
125
self .searchable = searchable .split (' ' ) # always a sequence
126
+ self .realms = list (realms )
121
127
self .solr_endpoint = request .registry .settings .get ('por.solr' )
122
128
123
129
@property
@@ -169,13 +175,32 @@ def query_exclude(items):
169
175
else :
170
176
return query_include (self .viewable_tracs )
171
177
178
+ def _build_realm_filter (self , si ):
179
+
180
+ Q = si .query ().Q
181
+
182
+ def query (items ):
183
+ if len (items ) > 2 :
184
+ return Q (realm = items .pop ()) | query (items )
185
+ elif len (items ) == 2 :
186
+ return Q (realm = items .pop ()) | Q (realm = items .pop ())
187
+ elif len (items ) == 1 :
188
+ return Q (realm = items .pop ())
189
+ else :
190
+ return ""
191
+ return query (self .realms )
192
+
172
193
def _do_search (self , sort_by = None ):
173
194
si = SolrInterface (self .solr_endpoint )
174
195
query = si .query ().field_limit (score = True )
175
196
176
197
for searchterm in self .searchable :
177
198
query = query .query (searchterm )
178
199
200
+ realm_query = self ._build_realm_filter (si )
201
+ if realm_query :
202
+ query = query .filter (realm_query )
203
+
179
204
trac_query = self ._build_trac_filter (si )
180
205
if trac_query :
181
206
query = query .filter (trac_query )
@@ -218,7 +243,12 @@ class FullTextSearchObject(object):
218
243
def __init__ (self , project , realm , id = None , score = None ,
219
244
title = None , author = None , changed = None , created = None ,
220
245
oneline = None , involved = None , popularity = None , comments = None ,
221
- solr_highlights = None , ** kwarg ):
246
+ parent_id = None , solr_highlights = None , ** kwarg ):
247
+
248
+ if not involved :
249
+ involved = ()
250
+ if not author :
251
+ author = ()
222
252
self .project = project
223
253
self .author = ', ' .join (author + involved )
224
254
self .created = created
@@ -230,6 +260,7 @@ def __init__(self, project, realm, id=None, score=None,
230
260
self ._oneline = oneline
231
261
self .id = id
232
262
self .score = score
263
+ self .parent_id = parent_id
233
264
234
265
@property
235
266
def title (self ):
@@ -252,4 +283,7 @@ def oneline(self):
252
283
return bleach .clean (text , ['span' ], ['class' ], strip = True )
253
284
254
285
def href (self ):
255
- return "trac/%s/%s/%s" % (self .project , self .realm , self .id )
286
+ if self .realm == 'changeset' :
287
+ return "trac/%s/%s/%s/%s" % (self .project , self .realm , self .id , self .parent_id )
288
+ else :
289
+ return "trac/%s/%s/%s" % (self .project , self .realm , self .id )
0 commit comments