示例#1
0
def format_name(name, indent, max_length):
    """
    Formats a potentially long name for multi-line display, giving
    it a columned effect.  Assumes the first line is already
    properly indented.
    """
    if not name or not max_length or (max_length -
                                      indent) <= 2 or not isinstance(
                                          name, six.string_types):
        return name
    if not isinstance(name, six.text_type):
        name = name.decode("utf-8")
    words = name.split()
    lines = []
    # handle emtpty names
    if not words:
        return name

    # Preserve leading whitespace in front of the first word
    leading_space = len(name) - len(name.lstrip())
    words[0] = name[0:leading_space] + words[0]
    # If there is leading whitespace, we've already indented the word and don't
    # want to double count.
    current = indent - leading_space
    if current < 0:
        current = 0

    def add_line():
        lines.append(' '.join(line))

    line = []
    # Split here and build it back up by word, this way we get word wrapping
    while words:
        word = words.pop(0)
        if current + utf8_width(word) <= max_length:
            current += utf8_width(
                word) + 1  # Have to account for the extra space
            line.append(word)
        else:
            if line:
                add_line()
            # If the word will not fit, break it
            if indent + utf8_width(word) > max_length:
                split_index = 0
                while (utf8_width(word[:split_index + 1]) + indent <=
                       max_length):
                    split_index += 1
                words.insert(0, word[split_index:])
                word = word[:split_index]
            line = [word]
            if indent and lines:
                line.insert(0, ' ' * (indent - 1))
            current = indent + utf8_width(word) + 1

    add_line()
    return '\n'.join(lines)
def format_name(name, indent, max_length):
    """
    Formats a potentially long name for multi-line display, giving
    it a columned effect.  Assumes the first line is already
    properly indented.
    """
    if not name or not max_length or (max_length - indent) <= 2 or not isinstance(name, basestring):
        return name
    if not isinstance(name, unicode):
        name = name.decode("utf-8")
    words = name.split()
    lines = []
    # handle emtpty names
    if not words:
        return name

    # Preserve leading whitespace in front of the first word
    leading_space = len(name) - len(name.lstrip())
    words[0] = name[0:leading_space] + words[0]
    # If there is leading whitespace, we've already indented the word and don't
    # want to double count.
    current = indent - leading_space
    if current < 0:
        current = 0

    def add_line():
        lines.append(' '.join(line))

    line = []
    # Split here and build it back up by word, this way we get word wrapping
    while words:
        word = words.pop(0)
        if current + utf8_width(word) <= max_length:
            current += utf8_width(word) + 1  # Have to account for the extra space
            line.append(word)
        else:
            if line:
                add_line()
            # If the word will not fit, break it
            if indent + utf8_width(word) > max_length:
                split_index = 0
                while(utf8_width(word[:split_index + 1]) + indent <= max_length):
                    split_index += 1
                words.insert(0, word[split_index:])
                word = word[:split_index]
            line = [word]
            if indent and lines:
                line.insert(0, ' ' * (indent - 1))
            current = indent + utf8_width(word) + 1

    add_line()
    return '\n'.join(lines)
示例#3
0
    def _importplugins(self, types):
        '''Load plugins matching the given types.
        '''

        # Initialise plugin dict
        self._plugins = {}
        self._pluginfuncs = {}
        for slot in SLOTS:
            self._pluginfuncs[slot] = []

        # Import plugins
        self._used_disable_plugin = set()
        self._used_enable_plugin = set()
        for dir in self.searchpath:
            if not os.path.isdir(dir):
                continue
            for modulefile in sorted(glob.glob('%s/*.py' % dir)):
                self._loadplugin(modulefile, types)

        # If we are in verbose mode we get the full 'Loading "blah" plugin' lines
        if (self._plugins and
                not self.verbose_logger.isEnabledFor(logginglevels.DEBUG_3)):
            # Mostly copied from YumOutput._outKeyValFill()
            key = _("Loaded plugins: ")
            val = ", ".join(sorted(self._plugins))
            nxt = ' ' * (utf8_width(key) - 2) + ': '
            width = 80
            if hasattr(self.base, 'term'):
                width = self.base.term.columns
            self.verbose_logger.log(
                logginglevels.INFO_2,
                fill(val,
                     width=width,
                     initial_indent=key,
                     subsequent_indent=nxt))

        if self.disabledPlugins:
            for wc in self.disabledPlugins:
                if wc not in self._used_disable_plugin:
                    self.verbose_logger.log(logginglevels.INFO_2,
                                            _("No plugin match for: %s") % wc)
        del self._used_disable_plugin
        if self.enabledPlugins:
            for wc in self.enabledPlugins:
                if wc not in self._used_enable_plugin:
                    self.verbose_logger.log(logginglevels.INFO_2,
                                            _("No plugin match for: %s") % wc)
        del self._used_enable_plugin
示例#4
0
    def _importplugins(self, types):
        '''Load plugins matching the given types.
        '''

        # Initialise plugin dict
        self._plugins = {}
        self._pluginfuncs = {}
        for slot in SLOTS:
            self._pluginfuncs[slot] = []

        # Import plugins 
        self._used_disable_plugin = set()
        self._used_enable_plugin  = set()
        for dir in self.searchpath:
            if not os.path.isdir(dir):
                continue
            for modulefile in sorted(glob.glob('%s/*.py' % dir)):
                self._loadplugin(modulefile, types)

        # If we are in verbose mode we get the full 'Loading "blah" plugin' lines
        if (self._plugins and
            not self.verbose_logger.isEnabledFor(logginglevels.DEBUG_3)):
            # Mostly copied from YumOutput._outKeyValFill()
            key = _("Loaded plugins: ")
            val = ", ".join(sorted(self._plugins))
            nxt = ' ' * (utf8_width(key) - 2) + ': '
            width = 80
            if hasattr(self.base, 'term'):
                width = self.base.term.columns
            self.verbose_logger.log(logginglevels.INFO_2,
                                    fill(val, width=width, initial_indent=key,
                                         subsequent_indent=nxt))

        if self.disabledPlugins:
            for wc in self.disabledPlugins:
                if wc not in self._used_disable_plugin:
                    self.verbose_logger.log(logginglevels.INFO_2,
                                            _("No plugin match for: %s") % wc)
        del self._used_disable_plugin
        if self.enabledPlugins:
            for wc in self.enabledPlugins:
                if wc not in self._used_enable_plugin:
                    self.verbose_logger.log(logginglevels.INFO_2,
                                            _("No plugin match for: %s") % wc)
        del self._used_enable_plugin
示例#5
0
文件: utils.py 项目: rhauser/ayum
      resultmsgs = [exception2msg(e)]
  except KeyboardInterrupt:
      return self.exUserCancel()
  except IOError, e:
      return self.exIOError(e)
 
  # Act on the depsolve result
  if result == 0:
      # Normal exit
      if self.unlock(): return 200
      return 0
  elif result == 1:
      # Fatal error
      for msg in resultmsgs:
          prefix = _('Error: %s')
          prefix2nd = (' ' * (utf8_width(prefix) - 2))
          self.logger.critical(prefix, msg.replace('\n', '\n' + prefix2nd))
      if not self.conf.skip_broken:
          self.verbose_logger.info(_(" You could try using --skip-broken to work around the problem"))
      if not self._rpmdb_warn_checks(out=self.verbose_logger.info, warn=False):
          self.verbose_logger.info(_(" You could try running: rpm -Va --nofiles --nodigest"))
      if self.unlock(): return 200
      return 1
  elif result == 2:
      # Continue on
      pass
  else:
      self.logger.critical(_('Unknown Error(s): Exit Code: %d:'), result)
      for msg in resultmsgs:
          self.logger.critical(msg)
      if self.unlock(): return 200
def ljust_wide(in_str, padding):
    return in_str + ' ' * (padding - utf8_width(in_str))
def ljust_wide(in_str, padding):
    return in_str + ' ' * (padding - utf8_width(in_str))
示例#8
0
        resultmsgs = [unicode(e)]
    except KeyboardInterrupt:
        return exUserCancel()
    except IOError, e:
        return exIOError(e)

    # Act on the depsolve result
    if result == 0:
        # Normal exit
        if unlock(): return 200
        return 0
    elif result == 1:
        # Fatal error
        for msg in resultmsgs:
            prefix = _('Error: %s')
            prefix2nd = (' ' * (utf8_width(prefix) - 2))
            logger.critical(prefix, msg.replace('\n', '\n' + prefix2nd))
        if not base.conf.skip_broken:
            verbose_logger.info(
                _(" You could try using --skip-broken to work around the problem"
                  ))
        if not base._rpmdb_warn_checks(out=verbose_logger.info, warn=False):
            verbose_logger.info(
                _(" You could try running: rpm -Va --nofiles --nodigest"))
        if unlock(): return 200
        return 1
    elif result == 2:
        # Continue on
        pass
    else:
        logger.critical(_('Unknown Error(s): Exit Code: %d:'), result)
示例#9
0
        except KeyboardInterrupt:
            return self.exUserCancel()
        except IOError, e:
            return self.exIOError(e)

        # Act on the depsolve result
        if result == 0:
            # Normal exit
            if self.unlock():
                return 200
            return 0
        elif result == 1:
            # Fatal error
            for msg in resultmsgs:
                prefix = _("Error: %s")
                prefix2nd = " " * (utf8_width(prefix) - 2)
                self.logger.critical(prefix, msg.replace("\n", "\n" + prefix2nd))
            if not self.conf.skip_broken:
                self.verbose_logger.info(_(" You could try using --skip-broken to work around the problem"))
            if not self._rpmdb_warn_checks(out=self.verbose_logger.info, warn=False):
                self.verbose_logger.info(_(" You could try running: rpm -Va --nofiles --nodigest"))
            if self.unlock():
                return 200
            return 1
        elif result == 2:
            # Continue on
            pass
        else:
            self.logger.critical(_("Unknown Error(s): Exit Code: %d:"), result)
            for msg in resultmsgs:
                self.logger.critical(msg)
示例#10
0
文件: yum-cron.py 项目: pnasrat/yum
    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)
示例#11
0
文件: yum-cron.py 项目: pnasrat/yum
    def _calcColumns(self, data, total_width, columns=None, remainder_column=0, indent=''):
        """Dynamically calculate the widths of the columns that the
        fields in data should be placed into for output.
        
        :param data: a list of dictionaries that represent the data to
           be output.  Each dictionary in the list corresponds to annn
           column of output. The keys of the dictionary are the
           lengths of the items to be output, and the value associated
           with a key is the number of items of that length.
        :param total_width: the total width of the output.
        :param columns: a list containing the minimum amount of space
           that must be allocated for each row. This can be used to
           ensure that there is space available in a column if, for
           example, the actual lengths of the items being output
           cannot be given in *data*
        :param remainder_column: number of the column to receive a few
           extra spaces that may remain after other allocation has
           taken place
        :param indent: string that will be prefixed to a line of
           output to create e.g. an indent
        :return: a list of the widths of the columns that the fields
           in data should be placed into for output
        """
        if total_width is None:
            total_width = self.term.columns

        cols = len(data)
        # Convert the data to ascending list of tuples, (field_length, pkgs)
        pdata = data
        data  = [None] * cols # Don't modify the passed in data
        for d in range(0, cols):
            data[d] = sorted(pdata[d].items())

        #  We start allocating 1 char to everything but the last column, and a
        # space between each (again, except for the last column). Because
        # at worst we are better with:
        # |one two three|
        # | four        |
        # ...than:
        # |one two three|
        # |            f|
        # |our          |
        # ...the later being what we get if we pre-allocate the last column, and
        # thus. the space, due to "three" overflowing it's column by 2 chars.
        if columns is None:
            columns = [1] * (cols - 1)
            columns.append(0)

        total_width -= (sum(columns) + (cols - 1) +
                        utf8_width(indent))
        if not columns[-1]:
            total_width += 1
        while total_width > 0:
            # Find which field all the spaces left will help best
            helps = 0
            val   = 0
            for d in xrange(0, cols):
                thelps = self._calc_columns_spaces_helps(columns[d], data[d],
                                                         total_width)
                if not thelps:
                    continue
                #  We prefer to overflow: the last column, and then earlier
                # columns. This is so that in the best case (just overflow the
                # last) ... grep still "works", and then we make it prettier.
                if helps and (d == (cols - 1)) and (thelps / 2) < helps:
                    continue
                if thelps < helps:
                    continue
                helps = thelps
                val   = d

            #  If we found a column to expand, move up to the next level with
            # that column and start again with any remaining space.
            if helps:
                diff = data[val].pop(0)[0] - columns[val]
                if not columns[val] and (val == (cols - 1)):
                    #  If we are going from 0 => N on the last column, take 1
                    # for the space before the column.
                    total_width  -= 1
                columns[val] += diff
                total_width  -= diff
                continue

            overflowed_columns = 0
            for d in xrange(0, cols):
                if not data[d]:
                    continue
                overflowed_columns += 1
            if overflowed_columns:
                #  Split the remaining spaces among each overflowed column
                # equally
                norm = total_width / overflowed_columns
                for d in xrange(0, cols):
                    if not data[d]:
                        continue
                    columns[d] += norm
                    total_width -= norm

            #  Split the remaining spaces among each column equally, except the
            # last one. And put the rest into the remainder column
            cols -= 1
            norm = total_width / cols
            for d in xrange(0, cols):
                columns[d] += norm
            columns[remainder_column] += total_width - (cols * norm)
            total_width = 0

        return columns