File Explorer

/proc/self/root/proc/thread-self/root/usr/lib/python3.9/site-packages/dnf/cli/commands

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

search.py6.2 KB · 161 lines
# search.py# Search CLI command.## Copyright (C) 2012-2016 Red Hat, Inc.## This copyrighted material is made available to anyone wishing to use,# modify, copy, or redistribute it subject to the terms and conditions of# the GNU General Public License v.2, or (at your option) any later version.# This program is distributed in the hope that it will be useful, but WITHOUT# ANY WARRANTY expressed or implied, including the implied warranties 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., 51 Franklin Street, Fifth Floor, Boston, MA# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the# source code or documentation are not subject to the GNU General Public# License and may only be used or replicated with the express permission of# Red Hat, Inc.# from __future__ import absolute_importfrom __future__ import print_functionfrom __future__ import unicode_literals import collections from dnf.cli import commandsfrom dnf.cli.option_parser import OptionParserfrom dnf.i18n import ucd, _, C_ import dnf.i18nimport dnf.match_counterimport dnf.utilimport hawkeyimport logging logger = logging.getLogger('dnf')  class SearchCommand(commands.Command):    """A class containing methods needed by the cli to execute the    search command.    """     aliases = ('search', 'se')    summary = _('search package details for the given string')     @staticmethod    def set_argparser(parser):        parser.add_argument('--all', action='store_true',                            help=_("search also package description and URL"))        parser.add_argument('query_string', nargs='+', metavar=_('KEYWORD'),                            choices=['all'], default=None,                            action=OptionParser.PkgNarrowCallback,                            help=_("Keyword to search for"))     def _search(self, args):        """Search for simple text tags in a package object."""         TRANS_TBL = collections.OrderedDict((            ('name', C_('long', 'Name')),            ('summary', C_('long', 'Summary')),            ('description', C_('long', 'Description')),            ('url', _('URL')),        ))         def _translate_attr(attr):            try:                return TRANS_TBL[attr]            except:                return attr         def _print_section_header(exact_match, attrs, keys):            trans_attrs = map(_translate_attr, attrs)            # TRANSLATORS: separator used between package attributes (eg. Name & Summary & URL)            trans_attrs_str = _(' & ').join(trans_attrs)            if exact_match:                # TRANSLATORS: %s  - translated package attributes,                #              %%s - found keys (in listed attributes)                section_text = _('%s Exactly Matched: %%s') % trans_attrs_str            else:                # TRANSLATORS: %s  - translated package attributes,                #              %%s - found keys (in listed attributes)                section_text = _('%s Matched: %%s') % trans_attrs_str            formatted = self.base.output.fmtSection(section_text % ", ".join(keys))            print(ucd(formatted))         counter = dnf.match_counter.MatchCounter()        for arg in args:            self._search_counted(counter, 'name', arg)            self._search_counted(counter, 'summary', arg)         if self.opts.all:            for arg in args:                self._search_counted(counter, 'description', arg)                self._search_counted(counter, 'url', arg)        else:            needles = len(args)            pkgs = list(counter.keys())            for pkg in pkgs:                if len(counter.matched_needles(pkg)) != needles:                    del counter[pkg]         used_attrs = None        matched_needles = None        exact_match = False        print_section_header = False        limit = None        if not self.base.conf.showdupesfromrepos:            limit = self.base.sack.query().filterm(pkg=counter.keys()).latest()         seen = set()        for pkg in counter.sorted(reverse=True, limit_to=limit):            if not self.base.conf.showdupesfromrepos:                if pkg.name + pkg.arch in seen:                    continue                seen.add(pkg.name + pkg.arch)             if used_attrs != counter.matched_keys(pkg):                used_attrs = counter.matched_keys(pkg)                print_section_header = True            if matched_needles != counter.matched_needles(pkg):                matched_needles = counter.matched_needles(pkg)                print_section_header = True            if exact_match != (counter.matched_haystacks(pkg) == matched_needles):                exact_match = counter.matched_haystacks(pkg) == matched_needles                print_section_header = True            if print_section_header:                _print_section_header(exact_match, used_attrs, matched_needles)                print_section_header = False            self.base.output.matchcallback(pkg, counter.matched_haystacks(pkg), args)         if len(counter) == 0:            logger.info(_('No matches found.'))     def _search_counted(self, counter, attr, needle):        fdict = {'%s__substr' % attr : needle}        if dnf.util.is_glob_pattern(needle):            fdict = {'%s__glob' % attr : needle}        q = self.base.sack.query().filterm(hawkey.ICASE, **fdict)        for pkg in q.run():            counter.add(pkg, attr, needle)        return counter     def pre_configure(self):        if not self.opts.quiet:            self.cli.redirect_logger(stdout=logging.WARNING, stderr=logging.INFO)     def configure(self):        if not self.opts.quiet:            self.cli.redirect_repo_progress()        demands = self.cli.demands        demands.available_repos = True        demands.fresh_metadata = False        demands.sack_activation = True        self.opts.all = self.opts.all or self.opts.query_string_action     def run(self):        logger.debug(_('Searching Packages: '))        return self._search(self.opts.query_string)