<commit_before># -*- coding: iso8859-1 -*-
#
# Copyright (C) 2003, 2004 Edgewall Software
# Copyright (C) 2003, 2004 <NAME> <<EMAIL>>
#
# Trac 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 2 of the
# License, or (at your option) any later version.
#
# Trac 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, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: <NAME> <<EMAIL>>

from trac import perm
from trac.util import TracError, escape, shorten_line
from trac.Module import Module

import re
import time
import string


class Search(Module):
    template_name = 'search.cs'

    RESULTS_PER_PAGE = 10

    def query_to_sql(self, q, name):
        self.log.debug("Query: %s" % q)
        if q[0] == q[-1] == "'" or q[0] == q[-1] == '"':
            sql_q = "%s like '%%%s%%'" % (name, q[1:-1].replace('\'',
                                                                '\'\''))
        else:
            q = q.replace('\'', '\'\'')
            keywords = q.split(' ')
            x = map(lambda x, name=name: name + ' LIKE \'%' + x + '%\'', keywords)
            sql_q = string.join(x, ' AND ')
        self.log.debug("SQL Condition: %s" % sql_q)
        return sql_q
    
    def shorten_result(self, text='', keywords=[], maxlen=240, fuzz=60):
        if not text: text = ''
        text_low = text.lower()
        beg = -1
        for k in keywords:
            i = text_low.find(k.lower())
            if (i > -1 and i < beg) or beg == -1:
                beg = i
        excerpt_beg = 0
        if beg > fuzz:
            for sep in ".:;= ":
                eb = text.find(sep, beg - fuzz, beg - 1)
                if eb > -1:
                    eb += 1
                    break
            else:
                eb = beg - fuzz
            excerpt_beg = eb
        if excerpt_beg < 0: excerpt_beg = 0
        msg = text[excerpt_beg:beg+maxlen]
        if beg > fuzz:
            msg = '... ' + msg
        if beg < len(text)-maxlen:
            msg = msg + ' ...'
        return msg
    
    def perform_query(self, req, query, changeset, tickets, wiki, page=0):
        if not query:
            return ([], 0)
        keywords = query.split(' ')

        if changeset:
            changeset = self.perm.has_permission(perm.CHANGESET_VIEW)
        if tickets:
            tickets = self.perm.has_permission(perm.TICKET_VIEW)
        if wiki:
            wiki = self.perm.has_permission(perm.WIKI_VIEW)

        if changeset == tickets == wiki == 0:
            return ([], 0)

        if len(keywords) == 1:
            kwd = keywords[0]
            redir = None
            # Prepending a '!' disables quickjump feature
            if kwd[0] == '!':
                keywords[0] = kwd[1:]
                query = query[1:]
                req.hdf['search.q'] = query
            # Ticket quickjump
            elif kwd[0] == '#' and kwd[1:].isdigit():
                redir = self.env.href.ticket(kwd[1:])
            # Changeset quickjump
            elif kwd[0] == '[' and kwd[-1] == ']' and kwd[1:-1].isdigit():
                redir = self.env.href.changeset(kwd[1:-1])
            # Report quickjump
            elif kwd[0] == '{' and kwd[-1] == '}' and kwd[1:-1].isdigit():
                redir = self.env.href.report(kwd[1:-1])
            elif kwd[0].isupper() and kwd[1].islower():
                r = "((^|(?<=[^A-Za-z]))[!]?[A-Z][a-z/]+(?:[A-Z][a-z/]+)+)"
                if re.match (r, kwd):
                    redir = self.env.href.wiki(kwd)
            if redir:
                req.hdf['search.q'] = ''
                req.redirect(redir)
            elif len(query) < 3:
                raise TracError('Search query too short. '
                                'Query must be at least 3 characters long.',
                                'Search Error')<commit_msg>Improved search quickjump support, closes #952<commit_after># -*- coding: iso8859-1 -*-
#
# Copyright (C) 2003, 2004 Edgewall Software
# Copyright (C) 2003, 2004 <NAME> <<EMAIL>>
#
# Trac 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 2 of the
# License, or (at your option) any later version.
#
# Trac 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, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: <NAME> <<EMAIL>>

from trac import perm
from trac.util import TracError, escape, shorten_line
from trac.Module import Module

import re
import time
import string


class Search(Module):
    template_name = 'search.cs'

    RESULTS_PER_PAGE = 10

    def query_to_sql(self, q, name):
        self.log.debug("Query: %s" % q)
        if q[0] == q[-1] == "'" or q[0] == q[-1] == '"':
            sql_q = "%s like '%%%s%%'" % (name, q[1:-1].replace('\'',
                                                                '\'\''))
        else:
            q = q.replace('\'', '\'\'')
            keywords = q.split(' ')
            x = map(lambda x, name=name: name + ' LIKE \'%' + x + '%\'', keywords)
            sql_q = string.join(x, ' AND ')
        self.log.debug("SQL Condition: %s" % sql_q)
        return sql_q
    
    def shorten_result(self, text='', keywords=[], maxlen=240, fuzz=60):
        if not text: text = ''
        text_low = text.lower()
        beg = -1
        for k in keywords:
            i = text_low.find(k.lower())
            if (i > -1 and i < beg) or beg == -1:
                beg = i
        excerpt_beg = 0
        if beg > fuzz:
            for sep in ".:;= ":
                eb = text.find(sep, beg - fuzz, beg - 1)
                if eb > -1:
                    eb += 1
                    break
            else:
                eb = beg - fuzz
            excerpt_beg = eb
        if excerpt_beg < 0: excerpt_beg = 0
        msg = text[excerpt_beg:beg+maxlen]
        if beg > fuzz:
            msg = '... ' + msg
        if beg < len(text)-maxlen:
            msg = msg + ' ...'
        return msg
    
    def perform_query(self, req, query, changeset, tickets, wiki, page=0):
        if not query:
            return ([], 0)
        keywords = query.split(' ')

        if changeset:
            changeset = self.perm.has_permission(perm.CHANGESET_VIEW)
        if tickets:
            tickets = self.perm.has_permission(perm.TICKET_VIEW)
        if wiki:
            wiki = self.perm.has_permission(perm.WIKI_VIEW)

        if changeset == tickets == wiki == 0:
            return ([], 0)

        if len(keywords) == 1:
            kwd = keywords[0]
            redir = None
            # Prepending a '!' disables quickjump feature
            if kwd[0] == '!':
                keywords[0] = kwd[1:]
                query = query[1:]
                req.hdf['search.q'] = query
            # Ticket quickjump
            elif kwd[0] == '#' and kwd[1:].isdigit():
                redir = self.env.href.ticket(kwd[1:])
            elif kwd[0:len('ticket:')] == 'ticket:' and kwd[len('ticket:'):].isdigit():
                redir = self.env.href.ticket(kwd[len('ticket:'):])
            elif kwd[0:len('bug:')] == 'bug:' and kwd[len('bug:'):].isdigit():
                redir = self.env.href.ticket(kwd[len('bug:'):])
            # Changeset quickjump
            elif kwd[0] == '[' and kwd[-1] == ']' and kwd[1:-1].isdigit():
                redir = self.env.href.changeset(kwd[1:-1])
            elif kwd[0:len('changeset:')] == 'changeset:' and kwd[len('changeset:'):].isdigit():
                redir = self.env.href.changeset(kwd[len('changeset:'):])
            # Report quickjump
            elif kwd[0] == '{' and kwd[-1] == '}' and kwd[1:-1].isdigit():
                redir = self.env.href.report(kwd[1:-1])
            elif kwd[0:len('report:')] == 'report:' and kwd[len('report:'):].isdigit():
                redir = self.env.href.report(kwd[len('report:'):])
            # Milestone quickjump
            elif kwd[0:len('milestone:')] == 'milestone:':
                redir = self.env.href.milestone(kwd[len('milestone:'):])
            # Source quickjump
            elif kwd[0:len('source:')] == 'source:':
                redir = self.env.href.browser(kwd[len('source:'):])
            # Wiki quickjump
            elif kwd[0:len('wiki:')] == 'wiki:':
                r = "((^|(?<=[^A-Za-z]))[!]?[A-Z][a-z/]+(?:[A-Z][a-z/]+)+)"
                if re.match (r, kwd[len('wiki:'):]):
                    redir = self.env.href.wiki(kwd[len('wiki:'):])
            elif kwd[0].isupper() and kwd[1].islower():
                r = "((^|(?<=[^A-Za-z]))[!]?[A-Z][a-z/]+(?:[A-Z][a-z/]+)+)"
                if re.match (r, kwd):
                    redir = self.env.href.wiki(kwd)
            if redir:
                req.hdf['search.q'] = ''
                req.redirect(redir)
            elif len(query) < 3:
                raise TracError('Search query too short. '
                                'Query must be at least 3 characters long.',
                                'Search Error')
{'fraction_non_alphanumeric': 0.15187538430006148, 'fraction_numerical': 0.01762656282025005, 'mean_word_length': 1.6921379310344828, 'pattern_counts': {'":': 2, '<': 26, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '295802', 'n_tokens_mistral': 3241, 'n_tokens_neox': 3005, 'n_words': 831}