pyplusplus._logging_.multi_line_formatter

Package pyplusplus :: Package _logging_ :: Module multi_line_formatter |

# Source Code for Module pyplusplus._logging_.multi_line_formatter

     1  # Copyright 2004-2008 Roman Yakovenko.
     2  # Distributed under the Boost Software License, Version 1.0. (See
     3  # accompanying file LICENSE_1_0.txt or copy at
     4  # http://www.boost.org/LICENSE_1_0.txt)
     5
     6  # Initial version by Matthias Baas (baas@ira.uka.de).
     7
     8  """defines a class that helps to format user messages"""
     9
    10  import os, logging, textwrap
    11
    12 -class multi_line_formatter_t(logging.Formatter):
    13      """Custom log formatter to split long message into several lines.
    14
    15      This formatter is used for the default stream handler that outputs
    16      its messages to stdout.
    17      """
    18
    19 -    def __init__(self, fmt=None, datefmt=None, width=None):
    20          """Constructor.
    21
    22          See the Python standard library reference for a documentation
    23          of fmt and datefmt.
    24          width is the maximum width of the generated text blocks.
    25          """
    26          logging.Formatter.__init__(self, fmt, datefmt)
    27          if None == width:
    28              try:
    29                  import curses
    30                  curses.setupterm()
    31                  self._width = curses.tigetnum('cols')
    32                  # Leave a border of two blanks to prevent that full lines
    33                  # wrap to the next line
    34                  self._width -= 2
    35              except:
    36                  self._width = 70   # default to 70
    37
    38 -    def format(self, record):
    39          """This method overwrites the original one.
    40
    41          The first thing that is done in the original format() method
    42          is the creation of the record.message attribute:
    43
    44            record.message = record.getMessage()
    45
    46          Now this method temporarily replaces the getMessage() method of
    47          the record by a version that returns a pregenerated message that
    48          spans several lines. Then the original format() method is called
    49          which will invoke the 'fake' method.
    50          """
    51          # Get the original single-line message
    52          message = record.getMessage()
    53          # Distribute the message among several lines...
    54          message = self.formatMessage(message, width=self._width)
    55          # ...and temporarily replace the getMessage() method so that the
    56          # reformatted message is used
    57          mth = record.getMessage
    58          record.getMessage = lambda x=message: x
    59          # Invoke the inherited format() method
    60          res = logging.Formatter.format(self, record)
    61          # Restore the original method
    62          record.getMessage = mth
    63          return res
    64
    65      @staticmethod
    66 -    def formatMessage(msgline, width=70):
    67          """Format a long single line message so that it is easier to read.
    68
    69          msgline is a string containing a single message. It can either be
    70          a plain message string which is reformatted using the textwrap
    71          module or it can be of the form <decl>;<msg> where <decl> is the
    72          declaration string and <msg> an arbitrary message. Lines of this
    73          form will be separated so that the declaration and the message
    74          appear in individual text blocks, where every line of message will start
    75          with '>' character.
    76
    77          width is the maximum width of any text blocks (without indendation).
    78          """
    79          txts = msgline.split(";")
    80          # Ensure that there are no more than two items in txts
    81          if len( txts ) != 2:
    82              #If message is not in format we expected, just return it
    83              return os.linesep.join( textwrap.wrap( msgline, width ) )
    84
    85          lines = [ txts[0] ] #I don't want to break declaration string to few lines
    86
    87          # Insert a separator if there are two parts (=decl and msg)
    88          # Apply the text wrapper to shorten the maximum line length
    89          wrapped_lines = textwrap.wrap( txts[1], width )
    90          lines.extend( map( lambda s: "> " + s.strip(), wrapped_lines ) )
    91
    92          return os.linesep.join(lines)
    93