##// END OF EJS Templates
#589 search urlgenerator didn't properly escape special chars on url
marcink -
r2913:bfffaa9a beta
parent child Browse files
Show More
@@ -1,144 +1,146
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 import urllib
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 43 from rhodecode.lib.utils2 import safe_str, safe_int
44 44
45
45 46 log = logging.getLogger(__name__)
46 47
47 48
48 49 class SearchController(BaseController):
49 50
50 51 @LoginRequired()
51 52 def __before__(self):
52 53 super(SearchController, self).__before__()
53 54
54 55 def index(self, search_repo=None):
55 56 c.repo_name = search_repo
56 57 c.formated_results = []
57 58 c.runtime = ''
58 59 c.cur_query = request.GET.get('q', None)
59 60 c.cur_type = request.GET.get('type', 'content')
60 61 c.cur_search = search_type = {'content': 'content',
61 62 'commit': 'message',
62 63 'path': 'path',
63 64 'repository': 'repository'
64 65 }.get(c.cur_type, 'content')
65 66
66 67 index_name = {
67 68 'content': IDX_NAME,
68 69 'commit': CHGSET_IDX_NAME,
69 70 'path': IDX_NAME
70 71 }.get(c.cur_type, IDX_NAME)
71 72
72 73 schema_defn = {
73 74 'content': SCHEMA,
74 75 'commit': CHGSETS_SCHEMA,
75 76 'path': SCHEMA
76 77 }.get(c.cur_type, SCHEMA)
77 78
78 79 log.debug('IDX: %s' % index_name)
79 80 log.debug('SCHEMA: %s' % schema_defn)
80 81
81 82 if c.cur_query:
82 83 cur_query = c.cur_query.lower()
83 84 log.debug(cur_query)
84 85
85 86 if c.cur_query:
86 87 p = safe_int(request.params.get('page', 1), 1)
87 88 highlight_items = set()
88 89 try:
89 90 idx = open_dir(config['app_conf']['index_dir'],
90 91 indexname=index_name)
91 92 searcher = idx.searcher()
92 93
93 94 qp = QueryParser(search_type, schema=schema_defn)
94 95 if c.repo_name:
95 96 cur_query = u'repository:%s %s' % (c.repo_name, cur_query)
96 97 try:
97 98 query = qp.parse(unicode(cur_query))
98 99 # extract words for highlight
99 100 if isinstance(query, Phrase):
100 101 highlight_items.update(query.words)
101 102 elif isinstance(query, Prefix):
102 103 highlight_items.add(query.text)
103 104 else:
104 105 for i in query.all_terms():
105 106 if i[0] in ['content', 'message']:
106 107 highlight_items.add(i[1])
107 108
108 109 matcher = query.matcher(searcher)
109 110
110 111 log.debug('query: %s' % query)
111 112 log.debug('hl terms: %s' % highlight_items)
112 113 results = searcher.search(query)
113 114 res_ln = len(results)
114 115 c.runtime = '%s results (%.3f seconds)' % (
115 116 res_ln, results.runtime
116 117 )
117 118
118 119 def url_generator(**kw):
120 q = urllib.quote(safe_str(c.cur_query))
119 121 return update_params("?q=%s&type=%s" \
120 % (safe_str(c.cur_query), safe_str(c.cur_type)), **kw)
122 % (q, safe_str(c.cur_type)), **kw)
121 123 repo_location = RepoModel().repos_path
122 124 c.formated_results = Page(
123 125 WhooshResultWrapper(search_type, searcher, matcher,
124 126 highlight_items, repo_location),
125 127 page=p,
126 128 item_count=res_ln,
127 129 items_per_page=10,
128 130 url=url_generator
129 131 )
130 132
131 133 except QueryParserError:
132 134 c.runtime = _('Invalid search query. Try quoting it.')
133 135 searcher.close()
134 136 except (EmptyIndexError, IOError):
135 137 log.error(traceback.format_exc())
136 138 log.error('Empty Index data')
137 139 c.runtime = _('There is no index to search in. '
138 140 'Please run whoosh indexer')
139 141 except (Exception):
140 142 log.error(traceback.format_exc())
141 143 c.runtime = _('An error occurred during this search operation')
142 144
143 145 # Return a rendered template
144 146 return render('/search/search.html')
General Comments 0
You need to be logged in to leave comments. Login now