Esempio n. 1
0
    def get_search_results(self, req, query, filters):
        if not 'discussion' in filters:
            return

        # Create database context
        db = self.env.get_db_cnx()
        cursor = db.cursor()

        # Search in topics.
        columns = ('id', 'forum', 'time', 'subject', 'body', 'author')
        sql = "SELECT id, forum, time, subject, body, author FROM topic" \
          " WHERE subject || body LIKE '%%%s%%'" % (query)
        self.log.debug(sql)
        cursor.execute(sql)
        for row in cursor:
            row = dict(zip(columns, row))
            yield (self.env.href.discussion(row['forum'], row['id']) + '#-1',
                   "topic: %d: %s" %
                   (row['id'], util.shorten_line(row['subject'])), row['time'],
                   row['author'], shorten_result(row['body'], query.split()))

        # Search in messages
        columns = ('id', 'forum', 'topic', 'time', 'author', 'body', 'subject')
        sql = "SELECT id, forum, topic, time, author, body, (SELECT" \
          " subject FROM topic t WHERE t.id = message.topic) FROM message" \
          " WHERE body LIKE '%%%s%%'" % (query)
        self.log.debug(sql)
        cursor.execute(sql)
        for row in cursor:
            row = dict(zip(columns, row))
            yield (self.env.href.discussion(row['forum'], row['topic'],
                                            row['id']) + '#%s' % (row['id']),
                   "message: %d: %s" %
                   (row['id'], util.shorten_line(row['subject'])), row['time'],
                   row['author'], shorten_result(row['body'], query.split()))
Esempio n. 2
0
 def get_search_results(self, req, terms, filters):
     """
     Search through requirements.
     
     The search term may be <x y z> or x-y-z; both are interpreted as
     component, fp, and object.
     """
     
     if not 'requirement' in filters:
         return
     
     if re.match(r'^([a-zA-Z_\d]+)-([a-zA-Z_\d]+)-([a-zA-Z_\d]+)$', terms[0]):
         terms = string.split(terms[0], '-')
         
     db = self.env.get_db_cnx()
     sql, args = search_to_sql(db, ['b.newvalue'], terms)
     sql2, args2 = search_to_sql(db, ['a.component', 'a.fp', 'a.object',
                                      'a.description', 'a.creator'], terms)
     
     cursor = db.cursor()
     cursor.execute("SELECT DISTINCT a.component, a.fp, a.object, "
                    "a.description, a.creator, a.time "
                    "FROM requirement a "
                    "LEFT JOIN requirement_change b "
                    "ON a.component = b.component AND a.fp = b.fp AND a.object = b.object "
                    "WHERE (b.field='comment' AND %s ) OR %s" % (sql, sql2),
                    args + args2)
     
     for component, fp, object, desc, creator, date in cursor:
         requirement = '<%s %s %s> ' % (component, fp, object)
         yield (req.href.requirement('%s-%s-%s' % (component, fp, object)),
                requirement + shorten_line(desc),
                date, creator, shorten_result(desc, terms))
Esempio n. 3
0
    def get_search_results(self, req, query, filters):
        if not "discussion" in filters:
            return

        # Create database context
        db = self.env.get_db_cnx()
        cursor = db.cursor()

        # Search in topics.
        columns = ("id", "forum", "time", "subject", "body", "author")
        sql = "SELECT id, forum, time, subject, body, author FROM topic" " WHERE subject || body LIKE '%%%s%%'" % (
            query
        )
        self.log.debug(sql)
        cursor.execute(sql)
        for row in cursor:
            row = dict(zip(columns, row))
            yield (
                self.env.href.discussion(row["forum"], row["id"]) + "#-1",
                "topic: %d: %s" % (row["id"], util.shorten_line(row["subject"])),
                row["time"],
                row["author"],
                shorten_result(row["body"], query.split()),
            )

        # Search in messages
        columns = ("id", "forum", "topic", "time", "author", "body", "subject")
        sql = (
            "SELECT id, forum, topic, time, author, body, (SELECT"
            " subject FROM topic t WHERE t.id = message.topic) FROM message"
            " WHERE body LIKE '%%%s%%'" % (query)
        )
        self.log.debug(sql)
        cursor.execute(sql)
        for row in cursor:
            row = dict(zip(columns, row))
            yield (
                self.env.href.discussion(row["forum"], row["topic"], row["id"]) + "#%s" % (row["id"]),
                "message: %d: %s" % (row["id"], util.shorten_line(row["subject"])),
                row["time"],
                row["author"],
                shorten_result(row["body"], query.split()),
            )
Esempio n. 4
0
    def get_search_results(self, req, keywords, filters):
        if not 'discussion' in filters:
            return

        # Create database context
        db = self.env.get_db_cnx()
        cursor = db.cursor()

        # Search in topics.
        query = ' '.join(keywords)
        columns = ('id', 'forum', 'time', 'subject', 'body', 'author')
        sql = "SELECT id, forum, time, subject, body, author FROM topic" \
          " WHERE subject || body LIKE '%%%s%%'" % (query)
        self.log.debug(sql)
        cursor.execute(sql)
        for row in cursor:
            row = dict(zip(columns, row))
            yield (req.href.discussion(row['forum'], row['id']) + '#-1',
              "topic: %d: %s" % (row['id'], util.shorten_line(row['subject'])),
              row['time'], row['author'], shorten_result(row['body'],
              [query]))

        # Search in messages
        columns = ('id', 'forum', 'topic', 'time', 'author', 'body', 'subject')
        sql = "SELECT m.id, m.forum, m.topic, m.time, m.author, m.body," \
          " t.subject FROM message m LEFT JOIN (SELECT subject, id FROM" \
          " topic) t ON t.id = m.topic WHERE body LIKE '%%%s%%'" \
          % (query)
        self.log.debug(sql)
        cursor.execute(sql)
        for row in cursor:
            row = dict(zip(columns, row))
            yield (req.href.discussion(row['forum'], row['topic'], row['id'])
              + '#%s' % (row['id']), "message: %d: %s" % (row['id'],
              util.shorten_line(row['subject'])), row['time'], row['author'],
              shorten_result(row['body'], [query]))
Esempio n. 5
0
 def get_search_results(self, req, terms, filters):
     if not 'changeset' in filters:
         return
     repos = self.env.get_repository(req.authname)
     db = self.env.get_db_cnx()
     sql, args = search_to_sql(db, ['message', 'author'], terms)
     cursor = db.cursor()
     cursor.execute("SELECT rev,time,author,message "
                    "FROM revision WHERE " + sql, args)
     for rev, date, author, log in cursor:
         if not repos.authz.has_permission_for_changeset(rev):
             continue
         yield (req.href.changeset(rev),
                '[%s]: %s' % (rev, shorten_line(log)),
                date, author, shorten_result(log, terms))
Esempio n. 6
0
 def get_search_results(self, req, terms, filters):
     if not 'changeset' in filters:
         return
     repos = self.env.get_repository(req.authname)
     db = self.env.get_db_cnx()
     sql, args = search_to_sql(db, ['message', 'author'], terms)
     cursor = db.cursor()
     cursor.execute("SELECT rev,time,author,message "
                    "FROM revision WHERE " + sql, args)
     for rev, date, author, log in cursor:
         if not repos.authz.has_permission_for_changeset(rev):
             continue
         yield (req.href.changeset(rev),
                '[%s]: %s' % (rev, shorten_line(log)),
                date, author, shorten_result(log, terms))
Esempio n. 7
0
 def get_search_results(self, req, query, filters):
     if not 'changeset' in filters:
         return
     authzperm = SubversionAuthorizer(self.env, req.authname)
     db = self.env.get_db_cnx()
     sql, args = query_to_sql(db, query, 'message||author')
     cursor = db.cursor()
     cursor.execute("SELECT rev,time,author,message "
                    "FROM revision WHERE " + sql, args)
     for rev, date, author, log in cursor:
         if not authzperm.has_permission_for_changeset(rev):
             continue
         yield (self.env.href.changeset(rev),
                '[%s]: %s' % (rev, util.shorten_line(log)),
                date, author, shorten_result(log, query.split()))
Esempio n. 8
0
    def get_search_results(self, req, terms, filters):
        if not 'wiki' in filters:
            return
        db = self.env.get_db_cnx()
        sql_query, args = search_to_sql(db, ['w1.name', 'w1.author', 'w1.text'], terms)
        cursor = db.cursor()
        cursor.execute("SELECT w1.name,w1.time,w1.author,w1.text "
                       "FROM wiki w1,"
                       "(SELECT name,max(version) AS ver "
                       "FROM wiki GROUP BY name) w2 "
                       "WHERE w1.version = w2.ver AND w1.name = w2.name "
                       "AND " + sql_query, args)

        for name, date, author, text in cursor:
            yield (req.href.wiki(name), '%s: %s' % (name, shorten_line(text)),
                   date, author, shorten_result(text, terms))
Esempio n. 9
0
 def get_search_results(self, req, query, filters):
     if not 'ticket' in filters:
         return
     db = self.env.get_db_cnx()
     sql = "SELECT DISTINCT a.summary,a.description,a.reporter, " \
           "a.keywords,a.id,a.time FROM ticket a " \
           "LEFT JOIN ticket_change b ON a.id = b.ticket " \
           "WHERE (b.field='comment' AND %s ) OR %s" % \
           (query_to_sql(db, query, 'b.newvalue'),
            query_to_sql(db, query, 'summary||keywords||description||reporter||cc'))
     cursor = db.cursor()
     cursor.execute(sql)
     for summary, desc, author, keywords, tid, date in cursor:
         yield (self.env.href.ticket(tid),
                '#%d: %s' % (tid, util.escape(util.shorten_line(summary))),
                date, author,
                util.escape(shorten_result(desc, query.split())))
Esempio n. 10
0
 def get_search_results(self, req, query, filters):
     if not 'ticket' in filters:
         return
     db = self.env.get_db_cnx()
     sql, args = query_to_sql(db, query, 'b.newvalue')
     sql2, args2 = query_to_sql(db, query, 'summary||keywords||description||reporter||cc')
     cursor = db.cursor()
     cursor.execute("SELECT DISTINCT a.summary,a.description,a.reporter, "
                    "a.keywords,a.id,a.time FROM ticket a "
                    "LEFT JOIN ticket_change b ON a.id = b.ticket "
                    "WHERE (b.field='comment' AND %s ) OR %s" % (sql, sql2),
                    args + args2)
     for summary,desc,author,keywords,tid,date in cursor:
         yield (self.env.href.ticket(tid),
                '#%d: %s' % (tid, util.shorten_line(summary)),
                date, author,
                shorten_result(desc, query.split()))
Esempio n. 11
0
    def get_search_results(self, req, query, filters):
        if not 'wiki' in filters:
            return
        db = self.env.get_db_cnx()
        sql = "SELECT w1.name,w1.time,w1.author,w1.text " \
              "FROM wiki w1," \
              "(SELECT name,max(version) AS ver " \
              "FROM wiki GROUP BY name) w2 " \
              "WHERE w1.version = w2.ver AND w1.name = w2.name " \
              "AND %s" % \
              (query_to_sql(db, query, 'w1.name||w1.author||w1.text'),)

        cursor = db.cursor()
        cursor.execute(sql)
        for name, date, author, text in cursor:
            yield (self.env.href.wiki(name),
                   '%s: %s' % (name, escape(shorten_line(text))), date, author,
                   escape(shorten_result(text, query.split())))
Esempio n. 12
0
    def get_search_results(self, req, terms, filters):
        if not 'wiki' in filters:
            return
        db = self.env.get_db_cnx()
        sql_query, args = search_to_sql(db,
                                        ['w1.name', 'w1.author', 'w1.text'],
                                        terms)
        cursor = db.cursor()
        cursor.execute(
            "SELECT w1.name,w1.time,w1.author,w1.text "
            "FROM wiki w1,"
            "(SELECT name,max(version) AS ver "
            "FROM wiki GROUP BY name) w2 "
            "WHERE w1.version = w2.ver AND w1.name = w2.name "
            "AND " + sql_query, args)

        for name, date, author, text in cursor:
            yield (req.href.wiki(name), '%s: %s' % (name, shorten_line(text)),
                   date, author, shorten_result(text, terms))
Esempio n. 13
0
 def get_search_results(self, req, terms, filters):
     if not 'ticket' in filters:
         return
     db = self.env.get_db_cnx()
     sql, args = search_to_sql(db, ['b.newvalue'], terms)
     sql2, args2 = search_to_sql(db, ['summary', 'keywords', 'description',
                                      'reporter', 'cc'], terms)
     cursor = db.cursor()
     cursor.execute("SELECT DISTINCT a.summary,a.description,a.reporter, "
                    "a.keywords,a.id,a.time,a.status FROM ticket a "
                    "LEFT JOIN ticket_change b ON a.id = b.ticket "
                    "WHERE (b.field='comment' AND %s ) OR %s" % (sql, sql2),
                    args + args2)
     for summary, desc, author, keywords, tid, date, status in cursor:
         ticket = '#%d: ' % tid
         if status == 'closed':
             ticket = Markup('<span style="text-decoration: line-through">'
                             '#%s</span>: ', tid)
         yield (req.href.ticket(tid),
                ticket + shorten_line(summary),
                date, author, shorten_result(desc, terms))
Esempio n. 14
0
 def get_search_results(self, req, terms, filters):
     if not 'ticket' in filters:
         return
     db = self.env.get_db_cnx()
     sql, args = search_to_sql(db, ['b.newvalue'], terms)
     sql2, args2 = search_to_sql(db, ['summary', 'keywords', 'description',
                                      'reporter', 'cc'], terms)
     cursor = db.cursor()
     cursor.execute("SELECT DISTINCT a.summary,a.description,a.reporter, "
                    "a.keywords,a.id,a.time,a.status FROM ticket a "
                    "LEFT JOIN ticket_change b ON a.id = b.ticket "
                    "WHERE (b.field='comment' AND %s ) OR %s" % (sql, sql2),
                    args + args2)
     for summary, desc, author, keywords, tid, date, status in cursor:
         ticket = '#%d: ' % tid
         if status == 'closed':
             ticket = Markup('<span style="text-decoration: line-through">'
                             '#%s</span>: ', tid)
         yield (req.href.ticket(tid),
                ticket + shorten_line(summary),
                date, author, shorten_result(desc, terms))
Esempio n. 15
0
    def get_search_results(self, req, query, filters):
        if 'repo' not in filters or not req.perm.has_permission('REPO_SEARCH'):
            return

        if not self.indexer:
            raise TracError('RepoSearch plugin not configured correctly. '
                            'You need to set "repo-search.indexer".')

        db = self.env.get_db_cnx()
        to_unicode = Mimeview(self.env).to_unicode

        self._update_index()

        for hit in self.framework.search(' '.join(query)):
            node = self.repo.get_node(hit.uri)
            change = self.repo.get_changeset(node.rev)
            if node.kind == Node.DIRECTORY:
                yield (self.env.href.browser(node.path), node.path,
                       change.date, change.author, 'Directory')
            else:
                found = 0
                content = to_unicode(node.get_content().read(),
                                     node.get_content_type())
                for n, line in enumerate(content.splitlines()):
                    line = line.lower()
                    for q in query:
                        idx = line.find(q)
                        if idx != -1:
                            found = n + 1
                            break
                    if found:
                        break

                yield (self.env.href.browser(node.path) +
                       (found and '#L%i' % found or ''), node.path,
                       change.date, change.author,
                       shorten_result(content, query))
Esempio n. 16
0
    def get_search_results(self, req, query, filters):
        if not "wiki" in filters:
            return
        db = self.env.get_db_cnx()
        sql_query, args = query_to_sql(db, query, "w1.name||w1.author||w1.text")
        cursor = db.cursor()
        cursor.execute(
            "SELECT w1.name,w1.time,w1.author,w1.text "
            "FROM wiki w1,"
            "(SELECT name,max(version) AS ver "
            "FROM wiki GROUP BY name) w2 "
            "WHERE w1.version = w2.ver AND w1.name = w2.name "
            "AND " + sql_query,
            args,
        )

        for name, date, author, text in cursor:
            yield (
                self.env.href.wiki(name),
                "%s: %s" % (name, shorten_line(text)),
                date,
                author,
                shorten_result(text, query.split()),
            )
Esempio n. 17
0
    def get_search_results(self, req, query, filters):
        if 'repo' not in filters or not req.perm.has_permission('REPO_SEARCH'):
            return

        if not self.indexer:
            raise TracError('RepoSearch plugin not configured correctly. '
                            'You need to set "repo-search.indexer".')

        db = self.env.get_db_cnx()
        to_unicode = Mimeview(self.env).to_unicode

        self._update_index()

        for hit in self.framework.search(' '.join(query)):
            node = self.repo.get_node(hit.uri)
            change = self.repo.get_changeset(node.rev)
            if node.kind == Node.DIRECTORY:
                yield (self.env.href.browser(node.path),
                       node.path, change.date, change.author,
                       'Directory')
            else:
                found = 0
                content = to_unicode(node.get_content().read(), node.get_content_type())
                for n, line in enumerate(content.splitlines()):
                    line = line.lower()
                    for q in query:
                        idx = line.find(q)
                        if idx != -1:
                            found = n + 1
                            break
                    if found:
                        break

                yield (self.env.href.browser(node.path) + (found and '#L%i' % found or ''),
                       node.path, change.date, change.author,
                       shorten_result(content, query))
Esempio n. 18
0
class TracRepoSearchPlugin(Component):
    """ Search the source repository. """
    implements(ISearchSource, IPermissionRequestor)

    def _get_filters(self):
        includes = [
            glob for glob in self.env.config.get(
                'repo-search', 'include', '').split(os.path.pathsep) if glob
        ]
        excludes = [
            glob for glob in self.env.config.get(
                'repo-search', 'exclude', '').split(os.path.pathsep) if glob
        ]
        return (includes, excludes)

    def walk_repo(self, repo):
        """ Walk all nodes in the repo that match the filters. """
        includes, excludes = self._get_filters()

        def searchable(path):
            # Exclude paths
            for exclude in excludes:
                if fnmatch(path, exclude):
                    return 0

            # Include paths
            for include in includes:
                if fnmatch(path, include):
                    return 1

            return not includes

        def do_walk(path):
            node = repo.get_node(path)
            basename = posixpath.basename(path)

            if searchable(node.path):
                yield node

            if node.kind == Node.DIRECTORY:
                for subnode in node.get_entries():
                    for result in do_walk(subnode.path):
                        yield result

        for node in do_walk('/'):
            yield node

    # IPermissionRequestor methods
    def get_permission_actions(self):
        yield 'REPO_SEARCH'

    # ISearchSource methods
    def get_search_filters(self, req):
        if req.perm.has_permission('REPO_SEARCH'):
            yield ('repo', 'Source Repository', 0)

    def get_search_results(self, req, query, filters):
        if 'repo' not in filters:
            return
        repo = self.env.get_repository(req.authname)
        if not isinstance(query, list):
            query = query.split()
        query = [q.lower() for q in query]
        db = self.env.get_db_cnx()
        include, excludes = self._get_filters()

        to_unicode = Mimeview(self.env).to_unicode

        # Use indexer if possible, otherwise fall back on brute force search.
        try:
            from tracreposearch.indexer import Indexer
            self.indexer = Indexer(self.env)
            self.indexer.reindex()
            walker = lambda repo, query: [
                repo.get_node(filename)
                for filename in self.indexer.find_words(query)
            ]
        except TracError, e:
            self.env.log.warning(e)
            self.env.log.warning('Falling back on full repository walk')

            def full_walker(repo, query):
                for node in self.walk_repo(repo):
                    # Search content
                    matched = 1
                    content = node.get_content()
                    if not content:
                        continue
                    content = to_unicode(content.read().lower(),
                                         node.get_content_type())
                    for term in query:
                        if term not in content:
                            matched = 0
                            break
                    if matched:
                        yield node

            walker = full_walker

        if not req.perm.has_permission('REPO_SEARCH'):
            return

        def match_name(name):
            for term in query:
                if term not in name:
                    return 0
            return 1

        for node in walker(repo, query):
            change = repo.get_changeset(node.rev)
            if node.kind == Node.DIRECTORY:
                yield (self.env.href.browser(node.path), node.path,
                       change.date, change.author, 'Directory')
            else:
                found = 0
                content = to_unicode(node.get_content().read(),
                                     node.get_content_type())
                for n, line in enumerate(content.splitlines()):
                    line = line.lower()
                    for q in query:
                        idx = line.find(q)
                        if idx != -1:
                            found = n + 1
                            break
                    if found:
                        break

                yield (self.env.href.browser(node.path) +
                       (found and '#L%i' % found or ''), node.path,
                       change.date, change.author,
                       shorten_result(content, query))