Mercurial > kallithea
view kallithea/controllers/search.py @ 6553:e9ac5698281d
tg: minimize future diff by some mocking and replacing some pylons imports with tg
No actual tg dependency yet, just a temporary hack faking tg as an alias for
pylons.
Based on work by Alessandro Molina.
author | Mads Kiilerich <mads@kiilerich.com> |
---|---|
date | Sat, 24 Dec 2016 01:27:47 +0100 |
parents | 8b7c0ef62427 |
children | 2f9313074853 |
line wrap: on
line source
# -*- coding: utf-8 -*- # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. """ kallithea.controllers.search ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Search controller for Kallithea This file was forked by the Kallithea project in July 2014. Original author and date, and relevant copyright and licensing information is below: :created_on: Aug 7, 2010 :author: marcink :copyright: (c) 2013 RhodeCode GmbH, and others. :license: GPLv3, see LICENSE.md for more details. """ import logging import traceback import urllib from tg.i18n import ugettext as _ from tg import request, config, tmpl_context as c from whoosh.index import open_dir, EmptyIndexError from whoosh.qparser import QueryParser, QueryParserError from whoosh.query import Phrase, Prefix from webhelpers.util import update_params from kallithea.lib.auth import LoginRequired from kallithea.lib.base import BaseRepoController, render from kallithea.lib.indexers import CHGSETS_SCHEMA, SCHEMA, CHGSET_IDX_NAME, \ IDX_NAME, WhooshResultWrapper from kallithea.lib.page import Page from kallithea.lib.utils2 import safe_str, safe_int from kallithea.model.repo import RepoModel log = logging.getLogger(__name__) class SearchController(BaseRepoController): def __before__(self): super(SearchController, self).__before__() @LoginRequired() def index(self, repo_name=None): c.repo_name = repo_name c.formated_results = [] c.runtime = '' c.cur_query = request.GET.get('q', None) c.cur_type = request.GET.get('type', 'content') c.cur_search = search_type = {'content': 'content', 'commit': 'message', 'path': 'path', 'repository': 'repository' }.get(c.cur_type, 'content') index_name = { 'content': IDX_NAME, 'commit': CHGSET_IDX_NAME, 'path': IDX_NAME }.get(c.cur_type, IDX_NAME) schema_defn = { 'content': SCHEMA, 'commit': CHGSETS_SCHEMA, 'path': SCHEMA }.get(c.cur_type, SCHEMA) log.debug('IDX: %s', index_name) log.debug('SCHEMA: %s', schema_defn) if c.cur_query: cur_query = c.cur_query.lower() log.debug(cur_query) if c.cur_query: p = safe_int(request.GET.get('page'), 1) highlight_items = set() try: idx = open_dir(config['app_conf']['index_dir'], indexname=index_name) searcher = idx.searcher() qp = QueryParser(search_type, schema=schema_defn) if c.repo_name: # use "repository_rawname:" instead of "repository:" # for case-sensitive matching cur_query = u'repository_rawname:%s %s' % (c.repo_name, cur_query) try: query = qp.parse(unicode(cur_query)) # extract words for highlight if isinstance(query, Phrase): highlight_items.update(query.words) elif isinstance(query, Prefix): highlight_items.add(query.text) else: for i in query.all_terms(): if i[0] in ['content', 'message']: highlight_items.add(i[1]) matcher = query.matcher(searcher) log.debug('query: %s', query) log.debug('hl terms: %s', highlight_items) results = searcher.search(query) res_ln = len(results) c.runtime = '%s results (%.3f seconds)' % ( res_ln, results.runtime ) def url_generator(**kw): q = urllib.quote(safe_str(c.cur_query)) return update_params("?q=%s&type=%s" \ % (q, safe_str(c.cur_type)), **kw) repo_location = RepoModel().repos_path c.formated_results = Page( WhooshResultWrapper(search_type, searcher, matcher, highlight_items, repo_location), page=p, item_count=res_ln, items_per_page=10, url=url_generator ) except QueryParserError: c.runtime = _('Invalid search query. Try quoting it.') searcher.close() except (EmptyIndexError, IOError): log.error(traceback.format_exc()) log.error('Empty Index data') c.runtime = _('There is no index to search in. ' 'Please run whoosh indexer') except Exception: log.error(traceback.format_exc()) c.runtime = _('An error occurred during search operation.') # Return a rendered template return render('/search/search.html')