Blame dnf/cli/commands/repolist.py

Packit 6f3914
# repolist.py
Packit 6f3914
# repolist CLI command.
Packit 6f3914
#
Packit 6f3914
# Copyright (C) 2014-2016 Red Hat, Inc.
Packit 6f3914
#
Packit 6f3914
# This copyrighted material is made available to anyone wishing to use,
Packit 6f3914
# modify, copy, or redistribute it subject to the terms and conditions of
Packit 6f3914
# the GNU General Public License v.2, or (at your option) any later version.
Packit 6f3914
# This program is distributed in the hope that it will be useful, but WITHOUT
Packit 6f3914
# ANY WARRANTY expressed or implied, including the implied warranties of
Packit 6f3914
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit 6f3914
# Public License for more details.  You should have received a copy of the
Packit 6f3914
# GNU General Public License along with this program; if not, write to the
Packit 6f3914
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit 6f3914
# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
Packit 6f3914
# source code or documentation are not subject to the GNU General Public
Packit 6f3914
# License and may only be used or replicated with the express permission of
Packit 6f3914
# Red Hat, Inc.
Packit 6f3914
#
Packit 6f3914
Packit 6f3914
from __future__ import absolute_import
Packit 6f3914
from __future__ import unicode_literals
Packit 6f3914
from dnf.cli import commands
Packit 6f3914
from dnf.i18n import _, ucd, fill_exact_width, exact_width
Packit 6f3914
from dnf.cli.option_parser import OptionParser
Packit 6f3914
import dnf.cli.format
Packit 6f3914
import dnf.pycomp
Packit 6f3914
import dnf.util
Packit 6f3914
import fnmatch
Packit 6f3914
import hawkey
Packit 6f3914
import logging
Packit 6f3914
import operator
Packit 6f3914
Packit 6f3914
logger = logging.getLogger('dnf')
Packit 6f3914
Packit 6f3914
Packit 6f3914
def _expire_str(repo, md):
Packit 6f3914
    last = dnf.util.normalize_time(repo._repo.getTimestamp()) if md else _("unknown")
Packit 6f3914
    if repo.metadata_expire <= -1:
Packit 6f3914
        return _("Never (last: %s)") % last
Packit 6f3914
    elif not repo.metadata_expire:
Packit 6f3914
        return _("Instant (last: %s)") % last
Packit 6f3914
    else:
Packit 6f3914
        num = _num2ui_num(repo.metadata_expire)
Packit 6f3914
        return _("%s second(s) (last: %s)") % (num, last)
Packit 6f3914
Packit 6f3914
Packit 6f3914
def _num2ui_num(num):
Packit 6f3914
    return ucd(dnf.pycomp.format("%d", num, True))
Packit 6f3914
Packit 6f3914
Packit 6f3914
def _repo_match(repo, patterns):
Packit 6f3914
    rid = repo.id.lower()
Packit 6f3914
    rnm = repo.name.lower()
Packit 6f3914
    for pat in patterns:
Packit 6f3914
        if fnmatch.fnmatch(rid, pat):
Packit 6f3914
            return True
Packit 6f3914
        if fnmatch.fnmatch(rnm, pat):
Packit 6f3914
            return True
Packit 6f3914
    return False
Packit 6f3914
Packit 6f3914
Packit 6f3914
def _repo_size(sack, repo):
Packit 6f3914
    ret = 0
Packit 6f3914
    for pkg in sack.query(flags=hawkey.IGNORE_EXCLUDES).filterm(reponame__eq=repo.id):
Packit 6f3914
        ret += pkg._size
Packit 6f3914
    return dnf.cli.format.format_number(ret)
Packit 6f3914
Packit 6f3914
Packit 6f3914
class RepoListCommand(commands.Command):
Packit 6f3914
    """A class containing methods needed by the cli to execute the
Packit 6f3914
    repolist command.
Packit 6f3914
    """
Packit 6f3914
Packit 6f3914
    aliases = ('repolist', 'repoinfo')
Packit 6f3914
    summary = _('display the configured software repositories')
Packit 6f3914
Packit 6f3914
    @staticmethod
Packit 6f3914
    def set_argparser(parser):
Packit 6f3914
        repolimit = parser.add_mutually_exclusive_group()
Packit 6f3914
        repolimit.add_argument('--all', dest='_repos_action',
Packit 6f3914
                               action='store_const', const='all', default=None,
Packit 6f3914
                               help=_("show all repos"))
Packit 6f3914
        repolimit.add_argument('--enabled', dest='_repos_action',
Packit 6f3914
                               action='store_const', const='enabled',
Packit 6f3914
                               help=_("show enabled repos (default)"))
Packit 6f3914
        repolimit.add_argument('--disabled', dest='_repos_action',
Packit 6f3914
                               action='store_const', const='disabled',
Packit 6f3914
                               help=_("show disabled repos"))
Packit 6f3914
        parser.add_argument('repos', nargs='*', default='enabled-default', metavar="REPOSITORY",
Packit 6f3914
                            choices=['all', 'enabled', 'disabled'],
Packit 6f3914
                            action=OptionParser.PkgNarrowCallback,
Packit 6f3914
                            help=_("Repository specification"))
Packit 6f3914
Packit 6f3914
    def pre_configure(self):
Packit 6f3914
        if not self.opts.verbose and not self.opts.quiet:
Packit 6f3914
            self.cli.redirect_logger(stdout=logging.WARNING, stderr=logging.INFO)
Packit 6f3914
Packit 6f3914
    def configure(self):
Packit 6f3914
        if not self.opts.verbose and not self.opts.quiet:
Packit 6f3914
            self.cli.redirect_repo_progress()
Packit 6f3914
        demands = self.cli.demands
Packit 6f3914
        if any((self.opts.verbose, ('repoinfo' in self.opts.command))):
Packit 6f3914
            demands.available_repos = True
Packit 6f3914
            demands.sack_activation = True
Packit 6f3914
Packit 6f3914
        if self.opts._repos_action:
Packit 6f3914
            self.opts.repos_action = self.opts._repos_action
Packit 6f3914
Packit 6f3914
    def run(self):
Packit 6f3914
        arg = self.opts.repos_action
Packit 6f3914
        extcmds = [x.lower() for x in self.opts.repos]
Packit 6f3914
Packit 6f3914
        verbose = self.base.conf.verbose
Packit 6f3914
Packit 6f3914
        repos = list(self.base.repos.values())
Packit 6f3914
        repos.sort(key=operator.attrgetter('id'))
Packit 6f3914
        term = self.output.term
Packit 6f3914
        on_ehibeg = term.FG_COLOR['green'] + term.MODE['bold']
Packit 6f3914
        on_dhibeg = term.FG_COLOR['red']
Packit 6f3914
        on_hiend = term.MODE['normal']
Packit 6f3914
        tot_num = 0
Packit 6f3914
        cols = []
Packit 6f3914
        if not repos:
Packit 6f3914
            logger.warning(_('No repositories available'))
Packit 6f3914
            return
Packit 6f3914
        include_status = arg == 'all' or (arg == 'enabled-default' and extcmds)
Packit 6f3914
Packit 6f3914
        for repo in repos:
Packit 6f3914
            if len(extcmds) and not _repo_match(repo, extcmds):
Packit 6f3914
                continue
Packit 6f3914
            (ehibeg, dhibeg, hiend) = '', '', ''
Packit 6f3914
            ui_enabled = ''
Packit 6f3914
            ui_endis_wid = 0
Packit 6f3914
            ui_excludes_num = ''
Packit 6f3914
            if include_status:
Packit 6f3914
                (ehibeg, dhibeg, hiend) = (on_ehibeg, on_dhibeg, on_hiend)
Packit 6f3914
            if repo.enabled:
Packit 6f3914
                enabled = True
Packit 6f3914
                if arg == 'disabled':
Packit 6f3914
                    continue
Packit 6f3914
                if any((include_status, verbose, 'repoinfo' in self.opts.command)):
Packit 6f3914
                    ui_enabled = ehibeg + _('enabled') + hiend
Packit 6f3914
                    ui_endis_wid = exact_width(_('enabled'))
Packit 6f3914
                if verbose or ('repoinfo' in self.opts.command):
Packit 6f3914
                    ui_size = _repo_size(self.base.sack, repo)
Packit 6f3914
            else:
Packit 6f3914
                enabled = False
Packit 6f3914
                if arg == 'enabled' or (arg == 'enabled-default' and not extcmds):
Packit 6f3914
                    continue
Packit 6f3914
                ui_enabled = dhibeg + _('disabled') + hiend
Packit 6f3914
                ui_endis_wid = exact_width(_('disabled'))
Packit 6f3914
Packit 6f3914
            if not any((verbose, ('repoinfo' in self.opts.command))):
Packit 6f3914
                rid = ucd(repo.id)
Packit 6f3914
                cols.append((rid, repo.name, (ui_enabled, ui_endis_wid)))
Packit 6f3914
            else:
Packit 6f3914
                if enabled:
Packit 6f3914
                    md = repo.metadata
Packit 6f3914
                else:
Packit 6f3914
                    md = None
Packit 6f3914
                out = [self.output.fmtKeyValFill(_("Repo-id            : "), repo.id),
Packit 6f3914
                       self.output.fmtKeyValFill(_("Repo-name          : "), repo.name)]
Packit 6f3914
Packit 6f3914
                if include_status:
Packit 6f3914
                    out += [self.output.fmtKeyValFill(_("Repo-status        : "),
Packit 6f3914
                                                      ui_enabled)]
Packit 6f3914
                if md and repo._repo.getRevision():
Packit 6f3914
                    out += [self.output.fmtKeyValFill(_("Repo-revision      : "),
Packit 6f3914
                                                      repo._repo.getRevision())]
Packit 6f3914
                if md and repo._repo.getContentTags():
Packit 6f3914
                    tags = repo._repo.getContentTags()
Packit 6f3914
                    out += [self.output.fmtKeyValFill(_("Repo-tags          : "),
Packit 6f3914
                                                      ", ".join(sorted(tags)))]
Packit 6f3914
Packit 6f3914
                if md and repo._repo.getDistroTags():
Packit 6f3914
                    distroTagsDict = {k: v for (k, v) in repo._repo.getDistroTags()}
Packit 6f3914
                    for (distro, tags) in distroTagsDict.items():
Packit 6f3914
                        out += [self.output.fmtKeyValFill(
Packit 6f3914
                            _("Repo-distro-tags      : "),
Packit 6f3914
                            "[%s]: %s" % (distro, ", ".join(sorted(tags))))]
Packit 6f3914
Packit 6f3914
                if md:
Packit 6f3914
                    num = len(self.base.sack.query(flags=hawkey.IGNORE_EXCLUDES).filterm(
Packit 6f3914
                        reponame__eq=repo.id))
Packit 6f3914
                    num_available = len(self.base.sack.query().filterm(reponame__eq=repo.id))
Packit 6f3914
                    ui_num = _num2ui_num(num)
Packit 6f3914
                    ui_num_available = _num2ui_num(num_available)
Packit 6f3914
                    tot_num += num
Packit 6f3914
                    out += [
Packit 6f3914
                        self.output.fmtKeyValFill(
Packit 6f3914
                            _("Repo-updated       : "),
Packit 6f3914
                            dnf.util.normalize_time(repo._repo.getMaxTimestamp())),
Packit 6f3914
                        self.output.fmtKeyValFill(_("Repo-pkgs          : "), ui_num),
Packit 6f3914
                        self.output.fmtKeyValFill(_("Repo-available-pkgs: "), ui_num_available),
Packit 6f3914
                        self.output.fmtKeyValFill(_("Repo-size          : "), ui_size)]
Packit 6f3914
Packit 6f3914
                if repo.metalink:
Packit 6f3914
                    out += [self.output.fmtKeyValFill(_("Repo-metalink      : "),
Packit 6f3914
                                                      repo.metalink)]
Packit 6f3914
                    if enabled:
Packit 6f3914
                        ts = repo._repo.getTimestamp()
Packit 6f3914
                        out += [self.output.fmtKeyValFill(
Packit 6f3914
                            _("  Updated          : "), dnf.util.normalize_time(ts))]
Packit 6f3914
                elif repo.mirrorlist:
Packit 6f3914
                    out += [self.output.fmtKeyValFill(_("Repo-mirrors       : "),
Packit 6f3914
                                                      repo.mirrorlist)]
Packit 6f3914
                baseurls = repo.baseurl
Packit 6f3914
                if baseurls:
Packit 6f3914
                    out += [self.output.fmtKeyValFill(_("Repo-baseurl       : "),
Packit 6f3914
                                                      ", ".join(baseurls))]
Packit 6f3914
                elif enabled:
Packit 6f3914
                    mirrors = repo._repo.getMirrors()
Packit 6f3914
                    if mirrors:
Packit 6f3914
                        url = "%s (%d more)" % (mirrors[0], len(mirrors) - 1)
Packit 6f3914
                        out += [self.output.fmtKeyValFill(_("Repo-baseurl       : "), url)]
Packit 6f3914
Packit 6f3914
                expire = _expire_str(repo, md)
Packit 6f3914
                out += [self.output.fmtKeyValFill(_("Repo-expire        : "), expire)]
Packit 6f3914
Packit 6f3914
                if repo.excludepkgs:
Packit 6f3914
                    # TRANSLATORS: Packages that are excluded - their names like (dnf systemd)
Packit 6f3914
                    out += [self.output.fmtKeyValFill(_("Repo-exclude       : "),
Packit 6f3914
                                                      ", ".join(repo.excludepkgs))]
Packit 6f3914
Packit 6f3914
                if repo.includepkgs:
Packit 6f3914
                    out += [self.output.fmtKeyValFill(_("Repo-include       : "),
Packit 6f3914
                                                      ", ".join(repo.includepkgs))]
Packit 6f3914
Packit 6f3914
                if ui_excludes_num:
Packit 6f3914
                    # TRANSLATORS: Number of packages that where excluded (5)
Packit 6f3914
                    out += [self.output.fmtKeyValFill(_("Repo-excluded      : "),
Packit 6f3914
                                                      ui_excludes_num)]
Packit 6f3914
Packit 6f3914
                if repo.repofile:
Packit 6f3914
                    out += [self.output.fmtKeyValFill(_("Repo-filename      : "),
Packit 6f3914
                                                      repo.repofile)]
Packit 6f3914
Packit 6f3914
                print("\n" + "\n".join(map(ucd, out)))
Packit 6f3914
Packit 6f3914
        if not verbose and cols:
Packit 6f3914
            #  Work out the first (id) and last (enabled/disabled/count),
Packit 6f3914
            # then chop the middle (name)...
Packit 6f3914
Packit 6f3914
            id_len = exact_width(_('repo id'))
Packit 6f3914
            nm_len = 0
Packit 6f3914
            st_len = 0
Packit 6f3914
Packit 6f3914
            for (rid, rname, (ui_enabled, ui_endis_wid)) in cols:
Packit 6f3914
                if id_len < exact_width(rid):
Packit 6f3914
                    id_len = exact_width(rid)
Packit 6f3914
                if nm_len < exact_width(rname):
Packit 6f3914
                    nm_len = exact_width(rname)
Packit 6f3914
                if st_len < ui_endis_wid:
Packit 6f3914
                    st_len = ui_endis_wid
Packit 6f3914
                # Need this as well as above for: fill_exact_width()
Packit 6f3914
            if include_status:
Packit 6f3914
                if exact_width(_('status')) > st_len:
Packit 6f3914
                    left = term.columns - (id_len + len(_('status')) + 2)
Packit 6f3914
                else:
Packit 6f3914
                    left = term.columns - (id_len + st_len + 2)
Packit 6f3914
            else:  # Don't output a status column.
Packit 6f3914
                left = term.columns - (id_len + 1)
Packit 6f3914
Packit 6f3914
            if left < nm_len:  # Name gets chopped
Packit 6f3914
                nm_len = left
Packit 6f3914
            else:  # Share the extra...
Packit 6f3914
                left -= nm_len
Packit 6f3914
                id_len += left // 2
Packit 6f3914
                nm_len += left - (left // 2)
Packit 6f3914
Packit 6f3914
            txt_rid = fill_exact_width(_('repo id'), id_len)
Packit 6f3914
            if include_status:
Packit 6f3914
                txt_rnam = fill_exact_width(_('repo name'), nm_len, nm_len)
Packit 6f3914
            else:
Packit 6f3914
                txt_rnam = _('repo name')
Packit 6f3914
            if not include_status:  # Don't output a status column.
Packit 6f3914
                print("%s %s" % (txt_rid, txt_rnam))
Packit 6f3914
            else:
Packit 6f3914
                print("%s %s %s" % (txt_rid, txt_rnam, _('status')))
Packit 6f3914
            for (rid, rname, (ui_enabled, ui_endis_wid)) in cols:
Packit 6f3914
                if not include_status:  # Don't output a status column.
Packit 6f3914
                    print("%s %s" % (fill_exact_width(rid, id_len), rname))
Packit 6f3914
                    continue
Packit 6f3914
Packit 6f3914
                print("%s %s %s" % (fill_exact_width(rid, id_len),
Packit 6f3914
                                    fill_exact_width(rname, nm_len, nm_len),
Packit 6f3914
                                    ui_enabled))
Packit 6f3914
        if any((verbose, ('repoinfo' in self.opts.command))):
Packit 6f3914
            msg = _('Total packages: {}')
Packit 6f3914
            print(msg.format(_num2ui_num(tot_num)))