13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
14 # details. |
14 # details. |
15 # |
15 # |
16 # You should have received a copy of the GNU Lesser General Public License along |
16 # You should have received a copy of the GNU Lesser General Public License along |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
18 """a query preprocesser to handle quick search shortcuts for cubicweb |
18 """a query processor to handle quick search shortcuts for cubicweb""" |
19 |
|
20 |
|
21 """ |
|
22 |
19 |
23 __docformat__ = "restructuredtext en" |
20 __docformat__ = "restructuredtext en" |
24 |
21 |
25 import re |
22 import re |
26 from logging import getLogger |
23 from logging import getLogger |
280 etype = self._get_entity_type(word1) |
277 etype = self._get_entity_type(word1) |
281 # this is a valid RQL query : ("Person X", or "Person TMP1") |
278 # this is a valid RQL query : ("Person X", or "Person TMP1") |
282 if len(word2) == 1 and word2.isupper(): |
279 if len(word2) == 1 and word2.isupper(): |
283 return '%s %s' % (etype, word2), |
280 return '%s %s' % (etype, word2), |
284 # else, suppose it's a shortcut like : Person Smith |
281 # else, suppose it's a shortcut like : Person Smith |
285 rql = '%s %s WHERE %s' % (etype, etype[0], self._complete_rql(word2, etype)) |
282 restriction = self._complete_rql(word2, etype) |
|
283 if ' has_text ' in restriction: |
|
284 rql = '%s %s ORDERBY FTIRANK(%s) DESC WHERE %s' % ( |
|
285 etype, etype[0], etype[0], restriction) |
|
286 else: |
|
287 rql = '%s %s WHERE %s' % ( |
|
288 etype, etype[0], restriction) |
286 return rql, {'text': word2} |
289 return rql, {'text': word2} |
287 |
290 |
288 def _three_words_query(self, word1, word2, word3): |
291 def _three_words_query(self, word1, word2, word3): |
289 """Specific process for three words query (case (3) of preprocess_rql) |
292 """Specific process for three words query (case (3) of preprocess_rql) |
290 """ |
293 """ |
312 """ |
315 """ |
313 # check out all possilbe entity types for the relation represented |
316 # check out all possilbe entity types for the relation represented |
314 # by 'rtype' |
317 # by 'rtype' |
315 mainvar = etype[0] |
318 mainvar = etype[0] |
316 searchvar = mainvar + '1' |
319 searchvar = mainvar + '1' |
317 rql = '%s %s WHERE %s %s %s, %s' % (etype, mainvar, # Person P |
320 restriction = self._complete_rql(searchstr, etype, rtype=rtype, |
318 mainvar, rtype, searchvar, # P worksAt C |
321 var=searchvar) |
319 self._complete_rql(searchstr, etype, |
322 if ' has_text ' in restriction: |
320 rtype=rtype, var=searchvar)) |
323 rql = ('%s %s ORDERBY FTIRANK(%s) DESC ' |
|
324 'WHERE %s %s %s, %s' % (etype, mainvar, searchvar, |
|
325 mainvar, rtype, searchvar, # P worksAt C |
|
326 restriction)) |
|
327 else: |
|
328 rql = ('%s %s WHERE %s %s %s, %s' % (etype, mainvar, |
|
329 mainvar, rtype, searchvar, # P worksAt C |
|
330 restriction)) |
321 return rql, {'text': searchstr} |
331 return rql, {'text': searchstr} |
322 |
332 |
323 |
333 |
324 def _quoted_words_query(self, ori_rql): |
334 def _quoted_words_query(self, ori_rql): |
325 """Specific process when there's a "quoted" part |
335 """Specific process when there's a "quoted" part |
350 priority = 10 |
360 priority = 10 |
351 name = 'text' |
361 name = 'text' |
352 |
362 |
353 def preprocess_query(self, uquery): |
363 def preprocess_query(self, uquery): |
354 """suppose it's a plain text query""" |
364 """suppose it's a plain text query""" |
355 return 'Any X WHERE X has_text %(text)s', {'text': uquery} |
365 return 'Any X ORDERBY FTIRANK(X) DESC WHERE X has_text %(text)s', {'text': uquery} |
356 |
366 |
357 |
367 |
358 |
368 |
359 class MagicSearchComponent(Component): |
369 class MagicSearchComponent(Component): |
360 __regid__ = 'magicsearch' |
370 __regid__ = 'magicsearch' |
383 for proc in self.processors: |
393 for proc in self.processors: |
384 try: |
394 try: |
385 try: |
395 try: |
386 return proc.process_query(uquery) |
396 return proc.process_query(uquery) |
387 except TypeError, exc: # cw 3.5 compat |
397 except TypeError, exc: # cw 3.5 compat |
388 print "EXC", exc |
|
389 warn("[3.6] %s.%s.process_query() should now accept uquery " |
398 warn("[3.6] %s.%s.process_query() should now accept uquery " |
390 "as unique argument, use self._cw instead of req" |
399 "as unique argument, use self._cw instead of req" |
391 % (proc.__module__, proc.__class__.__name__), |
400 % (proc.__module__, proc.__class__.__name__), |
392 DeprecationWarning) |
401 DeprecationWarning) |
393 return proc.process_query(uquery, self._cw) |
402 return proc.process_query(uquery, self._cw) |