Esempio n. 1
0
    def _fmtColumns(self, columns, msg=u'', end=u'', text_width=utf8_width):
        """Return a row of data formatted into a string for output.
        Items can overflow their columns. 

        :param columns: a list of tuples containing the data to
           output.  Each tuple contains first the item to be output,
           then the amount of space allocated for the column, and then
           optionally a type of highlighting for the item
        :param msg: a string to begin the line of output with
        :param end: a string to end the line of output with
        :param text_width: a function to find the width of the items
           in the columns.  This defaults to utf8 but can be changed
           to len() if you know it'll be fine
        :return: a row of data formatted into a string for output
        """
        total_width = len(msg)
        data = []
        for col_data in columns[:-1]:
            (val, width) = col_data

            if not width: # Don't count this column, invisible text
                msg += u"%s"
                data.append(val)
                continue

            (align, width) = self._fmt_column_align_width(width)
            val_width = text_width(val)
            if val_width <= width:
                #  Don't use utf8_width_fill() because it sucks performance
                # wise for 1,000s of rows. Also allows us to use len(), when
                # we can.
                msg += u"%s%s "
                if (align == u'-'):
                    data.extend([val, " " * (width - val_width)])
                else:
                    data.extend([" " * (width - val_width), val])
            else:
                msg += u"%s\n" + " " * (total_width + width + 1)
                data.append(val)
            total_width += width
            total_width += 1
        (val, width) = columns[-1]
        (align, width) = self._fmt_column_align_width(width)
        val = utf8_width_fill(val, width, left=(align == u'-'))
        msg += u"%%s%s" % end
        data.append(val)
        return msg % tuple(data)
Esempio n. 2
0
    def _formatTransaction(self, tsInfo):
        """Return a string containing a human-readable formatted
        summary of the transaction.
        
        :param tsInfo: :class:`yum.transactioninfo.TransactionData`
           instance that contains information about the transaction
        :return: a string that contains a formatted summary of the
           transaction
           """
        # Sort the packages in the transaction into different lists,
        # e.g. installed, updated etc
        tsInfo.makelists(True, True)

        # For each package list, pkglist_lines will contain a tuple
        # that contains the name of the list, and a list of tuples
        # with information about each package in the list
        pkglist_lines = []
        data  = {'n' : {}, 'v' : {}, 'r' : {}}
        a_wid = 0 # Arch can't get "that big" ... so always use the max.


        def _add_line(lines, data, a_wid, po, obsoletes=[]):
            # Create a tuple of strings that contain the name, arch,
            # version, repository, size, and obsoletes of the package
            # given in po.  Then, append this tuple to lines.  The
            # strings are formatted so that the tuple can be easily
            # joined together for output.

            
            (n,a,e,v,r) = po.pkgtup
            
            # Retrieve the version, repo id, and size of the package
            # in human-readable form
            evr = po.printVer()
            repoid = po.ui_from_repo
            size = self._format_number(float(po.size))

            if a is None: # gpgkeys are weird
                a = 'noarch'

            lines.append((n, a, evr, repoid, size, obsoletes))
            #  Create a dict of field_length => number of packages, for
            # each field.
            for (d, v) in (("n",len(n)), ("v",len(evr)), ("r",len(repoid))):
                data[d].setdefault(v, 0)
                data[d][v] += 1
            a_wid = max(a_wid, len(a))

            return a_wid

        

        # Iterate through the different groups of packages
        for (action, pkglist) in [(_('Installing'), tsInfo.installed),
                            (_('Updating'), tsInfo.updated),
                            (_('Removing'), tsInfo.removed),
                            (_('Reinstalling'), tsInfo.reinstalled),
                            (_('Downgrading'), tsInfo.downgraded),
                            (_('Installing for dependencies'), tsInfo.depinstalled),
                            (_('Updating for dependencies'), tsInfo.depupdated),
                            (_('Removing for dependencies'), tsInfo.depremoved)]:
            # Create a list to hold the tuples of strings for each package
            lines = []

            # Append the tuple for each package to lines, and update a_wid
            for txmbr in pkglist:
                a_wid = _add_line(lines, data, a_wid, txmbr.po, txmbr.obsoletes)

            # Append the lines instance for this package list to pkglist_lines
            pkglist_lines.append((action, lines))

        # # Iterate through other package lists
        # for (action, pkglist) in [(_('Skipped (dependency problems)'),
        #                            self.skipped_packages),
        #                           (_('Not installed'), self._not_found_i.values()),
        #                           (_('Not available'), self._not_found_a.values())]:
        #     lines = []
        #     for po in pkglist:
        #         a_wid = _add_line(lines, data, a_wid, po)

        #     pkglist_lines.append((action, lines))

        if not data['n']:
            return u''
        else:
            # Change data to a list with the correct number of
            # columns, in the correct order
            data    = [data['n'],    {}, data['v'], data['r'], {}]

            
             
            # Calculate the space needed for each column
            columns = [1,         a_wid,         1,         1,  5]

            columns = self._calcColumns(data, self.opts.output_width,
                                        columns, remainder_column = 2, indent="  ")

            (n_wid, a_wid, v_wid, r_wid, s_wid) = columns
            assert s_wid == 5

            # out will contain the output as a list of strings, that
            # can be later joined together
            out = [u"""
%s
%s
%s
""" % ('=' * self.opts.output_width,
       self._fmtColumns(((_('Package'), -n_wid), (_('Arch'), -a_wid),
                        (_('Version'), -v_wid), (_('Repository'), -r_wid),
                        (_('Size'), s_wid)), u" "),
       '=' * self.opts.output_width)]

        # Add output for each package list in pkglist_lines
        for (action, lines) in pkglist_lines:
            #If the package list is empty, skip it
            if not lines:
                continue

            # Add the name of the package list
            totalmsg = u"%s:\n" % action
            # Add a line of output about an individual package
            for (n, a, evr, repoid, size, obsoletes) in lines:
                columns = ((n,   -n_wid), (a,      -a_wid),
                           (evr, -v_wid), (repoid, -r_wid), (size, s_wid))
                msg = self._fmtColumns(columns, u" ", u"\n")
                for obspo in sorted(obsoletes):
                    appended = _('     replacing  %s.%s %s\n')
                    appended %= (obspo.name,
                                 obspo.arch, obspo.printVer())
                    msg = msg+appended
                totalmsg = totalmsg + msg

            # Append the line about the individual package to out
            out.append(totalmsg)

        # Add a summary of the transaction
        out.append(_("""
Transaction Summary
%s
""") % ('=' * self.opts.output_width))
        summary_data =  (
            (_('Install'), len(tsInfo.installed),
             len(tsInfo.depinstalled)),
            (_('Upgrade'), len(tsInfo.updated),
             len(tsInfo.depupdated)),
            (_('Remove'), len(tsInfo.removed),
             len(tsInfo.depremoved)),
            (_('Reinstall'), len(tsInfo.reinstalled), 0),
            (_('Downgrade'), len(tsInfo.downgraded), 0),
            # (_('Skipped (dependency problems)'), len(self.skipped_packages), 0),
            # (_('Not installed'), len(self._not_found_i.values()), 0),
            # (_('Not available'), len(self._not_found_a.values()), 0),
        )
        max_msg_action   = 0
        max_msg_count    = 0
        max_msg_pkgs     = 0
        max_msg_depcount = 0
        for action, count, depcount in summary_data:
            if not count and not depcount:
                continue

            msg_pkgs = P_('Package', 'Packages', count)
            len_msg_action   = utf8_width(action)
            len_msg_count    = utf8_width(str(count))
            len_msg_pkgs     = utf8_width(msg_pkgs)

            if depcount:
                len_msg_depcount = utf8_width(str(depcount))
            else:
                len_msg_depcount = 0

            max_msg_action   = max(len_msg_action,   max_msg_action)
            max_msg_count    = max(len_msg_count,    max_msg_count)
            max_msg_pkgs     = max(len_msg_pkgs,     max_msg_pkgs)
            max_msg_depcount = max(len_msg_depcount, max_msg_depcount)

        for action, count, depcount in summary_data:
            msg_pkgs = P_('Package', 'Packages', count)
            if depcount:
                msg_deppkgs = P_('Dependent package', 'Dependent packages',
                                 depcount)
                if count:
                    msg = '%s  %*d %s (+%*d %s)\n'
                    out.append(msg % (utf8_width_fill(action, max_msg_action),
                                      max_msg_count, count,
                                      utf8_width_fill(msg_pkgs, max_msg_pkgs),
                                      max_msg_depcount, depcount, msg_deppkgs))
                else:
                    msg = '%s  %*s %s ( %*d %s)\n'
                    out.append(msg % (utf8_width_fill(action, max_msg_action),
                                      max_msg_count, '',
                                      utf8_width_fill('', max_msg_pkgs),
                                      max_msg_depcount, depcount, msg_deppkgs))
            elif count:
                msg = '%s  %*d %s\n'
                out.append(msg % (utf8_width_fill(action, max_msg_action),
                                  max_msg_count, count, msg_pkgs))

        return ''.join(out)