##// END OF EJS Templates
fixes issues #566 non-ascii search params are crashing paginator...
marcink -
r2842:14852cad beta
parent child Browse files
Show More
@@ -1,143 +1,144
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.search
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Search controller for RhodeCode
7 7
8 8 :created_on: Aug 7, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software: you can redistribute it and/or modify
14 14 # it under the terms of the GNU General Public License as published by
15 15 # the Free Software Foundation, either version 3 of the License, or
16 16 # (at your option) any later version.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25 import logging
26 26 import traceback
27 27
28 28 from pylons.i18n.translation import _
29 29 from pylons import request, config, tmpl_context as c
30 30
31 31 from rhodecode.lib.auth import LoginRequired
32 32 from rhodecode.lib.base import BaseController, render
33 33 from rhodecode.lib.indexers import CHGSETS_SCHEMA, SCHEMA, CHGSET_IDX_NAME, \
34 34 IDX_NAME, WhooshResultWrapper
35 35
36 36 from webhelpers.paginate import Page
37 37 from webhelpers.util import update_params
38 38
39 39 from whoosh.index import open_dir, EmptyIndexError
40 40 from whoosh.qparser import QueryParser, QueryParserError
41 41 from whoosh.query import Phrase, Wildcard, Term, Prefix
42 42 from rhodecode.model.repo import RepoModel
43 from rhodecode.lib.utils2 import safe_str
43 44
44 45 log = logging.getLogger(__name__)
45 46
46 47
47 48 class SearchController(BaseController):
48 49
49 50 @LoginRequired()
50 51 def __before__(self):
51 52 super(SearchController, self).__before__()
52 53
53 54 def index(self, search_repo=None):
54 55 c.repo_name = search_repo
55 56 c.formated_results = []
56 57 c.runtime = ''
57 58 c.cur_query = request.GET.get('q', None)
58 59 c.cur_type = request.GET.get('type', 'content')
59 60 c.cur_search = search_type = {'content': 'content',
60 61 'commit': 'message',
61 62 'path': 'path',
62 63 'repository': 'repository'
63 64 }.get(c.cur_type, 'content')
64 65
65 66 index_name = {
66 67 'content': IDX_NAME,
67 68 'commit': CHGSET_IDX_NAME,
68 69 'path': IDX_NAME
69 70 }.get(c.cur_type, IDX_NAME)
70 71
71 72 schema_defn = {
72 73 'content': SCHEMA,
73 74 'commit': CHGSETS_SCHEMA,
74 75 'path': SCHEMA
75 76 }.get(c.cur_type, SCHEMA)
76 77
77 78 log.debug('IDX: %s' % index_name)
78 79 log.debug('SCHEMA: %s' % schema_defn)
79 80
80 81 if c.cur_query:
81 82 cur_query = c.cur_query.lower()
82 83 log.debug(cur_query)
83 84
84 85 if c.cur_query:
85 86 p = int(request.params.get('page', 1))
86 87 highlight_items = set()
87 88 try:
88 89 idx = open_dir(config['app_conf']['index_dir'],
89 90 indexname=index_name)
90 91 searcher = idx.searcher()
91 92
92 93 qp = QueryParser(search_type, schema=schema_defn)
93 94 if c.repo_name:
94 95 cur_query = u'repository:%s %s' % (c.repo_name, cur_query)
95 96 try:
96 97 query = qp.parse(unicode(cur_query))
97 98 # extract words for highlight
98 99 if isinstance(query, Phrase):
99 100 highlight_items.update(query.words)
100 101 elif isinstance(query, Prefix):
101 102 highlight_items.add(query.text)
102 103 else:
103 104 for i in query.all_terms():
104 105 if i[0] in ['content', 'message']:
105 106 highlight_items.add(i[1])
106 107
107 108 matcher = query.matcher(searcher)
108 109
109 110 log.debug('query: %s' % query)
110 111 log.debug('hl terms: %s' % highlight_items)
111 112 results = searcher.search(query)
112 113 res_ln = len(results)
113 114 c.runtime = '%s results (%.3f seconds)' % (
114 115 res_ln, results.runtime
115 116 )
116 117
117 118 def url_generator(**kw):
118 119 return update_params("?q=%s&type=%s" \
119 % (c.cur_query, c.cur_type), **kw)
120 % (safe_str(c.cur_query), safe_str(c.cur_type)), **kw)
120 121 repo_location = RepoModel().repos_path
121 122 c.formated_results = Page(
122 123 WhooshResultWrapper(search_type, searcher, matcher,
123 124 highlight_items, repo_location),
124 125 page=p,
125 126 item_count=res_ln,
126 127 items_per_page=10,
127 128 url=url_generator
128 129 )
129 130
130 131 except QueryParserError:
131 132 c.runtime = _('Invalid search query. Try quoting it.')
132 133 searcher.close()
133 134 except (EmptyIndexError, IOError):
134 135 log.error(traceback.format_exc())
135 136 log.error('Empty Index data')
136 137 c.runtime = _('There is no index to search in. '
137 138 'Please run whoosh indexer')
138 139 except (Exception):
139 140 log.error(traceback.format_exc())
140 141 c.runtime = _('An error occurred during this search operation')
141 142
142 143 # Return a rendered template
143 144 return render('/search/search.html')
General Comments 0
You need to be logged in to leave comments. Login now