HEX
Server: Apache
System: Linux sg241.singhost.net 2.6.32-896.16.1.lve1.4.51.el6.x86_64 #1 SMP Wed Jan 17 13:19:23 EST 2018 x86_64
User: honghock (909)
PHP: 8.0.30
Disabled: passthru,system,shell_exec,show_source,exec,popen,proc_open
Upload Files
File: //usr/lib/python2.7/site-packages/salt/output/__init__.py
# -*- coding: utf-8 -*-
'''
Used to manage the outputter system. This package is the modular system used
for managing outputters.
'''

# Import Python libs
from __future__ import absolute_import, print_function, unicode_literals

import errno
import logging
import io
import os
import re
import sys
import traceback

# Import Salt libs
import salt.loader
import salt.utils.files
import salt.utils.platform
import salt.utils.stringutils

# Import 3rd-party libs
from salt.ext import six

# Are you really sure !!!
# dealing with unicode is not as simple as setting defaultencoding
# which can break other python modules imported by salt in bad ways...
# reloading sys is not either a good idea...
# reload(sys)
# sys.setdefaultencoding('utf-8')

log = logging.getLogger(__name__)


def try_printout(data, out, opts, **kwargs):
    '''
    Safely get the string to print out, try the configured outputter, then
    fall back to nested and then to raw
    '''
    try:
        printout = get_printout(out, opts)(data, **kwargs)
        if printout is not None:
            return printout.rstrip()
    except (KeyError, AttributeError, TypeError):
        log.debug(traceback.format_exc())
        try:
            printout = get_printout('nested', opts)(data, **kwargs)
            if printout is not None:
                return printout.rstrip()
        except (KeyError, AttributeError, TypeError):
            log.error('Nested output failed: ', exc_info=True)
            printout = get_printout('raw', opts)(data, **kwargs)
            if printout is not None:
                return printout.rstrip()


def get_progress(opts, out, progress):
    '''
    Get the progress bar from the given outputter
    '''
    return salt.loader.raw_mod(opts,
                                out,
                                'rawmodule',
                                mod='output')['{0}.progress_iter'.format(out)](progress)


def update_progress(opts, progress, progress_iter, out):
    '''
    Update the progress iterator for the given outputter
    '''
    # Look up the outputter
    try:
        progress_outputter = salt.loader.outputters(opts)[out]
    except KeyError:  # Outputter is not loaded
        log.warning('Progress outputter not available.')
        return False
    progress_outputter(progress, progress_iter)


def progress_end(progress_iter):
    try:
        progress_iter.stop()
    except Exception:  # pylint: disable=broad-except
        pass
    return None


def display_output(data, out=None, opts=None, **kwargs):
    '''
    Print the passed data using the desired output
    '''
    if opts is None:
        opts = {}
    display_data = try_printout(data, out, opts, **kwargs)

    output_filename = opts.get('output_file', None)
    log.trace('data = %s', data)
    try:
        # output filename can be either '' or None
        if output_filename:
            if not hasattr(output_filename, 'write'):
                ofh = salt.utils.files.fopen(output_filename, 'a')  # pylint: disable=resource-leakage
                fh_opened = True
            else:
                # Filehandle/file-like object
                ofh = output_filename
                fh_opened = False

            try:
                fdata = display_data
                if isinstance(fdata, six.text_type):
                    try:
                        fdata = fdata.encode('utf-8')
                    except (UnicodeDecodeError, UnicodeEncodeError):
                        # try to let the stream write
                        # even if we didn't encode it
                        pass
                if fdata:
                    ofh.write(salt.utils.stringutils.to_str(fdata))
                    ofh.write('\n')
            finally:
                if fh_opened:
                    ofh.close()
            return
        if display_data:
            salt.utils.stringutils.print_cli(display_data)
    except IOError as exc:
        # Only raise if it's NOT a broken pipe
        if exc.errno != errno.EPIPE:
            six.reraise(*sys.exc_info())


def get_printout(out, opts=None, **kwargs):
    '''
    Return a printer function
    '''
    if opts is None:
        opts = {}

    if 'output' in opts and opts['output'] != 'highstate':
        # new --out option, but don't choke when using --out=highstate at CLI
        # See Issue #29796 for more information.
        out = opts['output']

    # Handle setting the output when --static is passed.
    if not out and opts.get('static'):
        if opts.get('output'):
            out = opts['output']
        elif opts.get('fun', '').split('.')[0] == 'state':
            # --static doesn't have an output set at this point, but if we're
            # running a state function and "out" hasn't already been set, we
            # should set the out variable to "highstate". Otherwise state runs
            # are set to "nested" below. See Issue #44556 for more information.
            out = 'highstate'

    if out == 'text':
        out = 'txt'
    elif out is None or out == '':
        out = 'nested'
    if opts.get('progress', False):
        out = 'progress'

    opts.update(kwargs)
    if 'color' not in opts:
        def is_pipe():
            '''
            Check if sys.stdout is a pipe or not
            '''
            try:
                fileno = sys.stdout.fileno()
            except (AttributeError, io.UnsupportedOperation):
                fileno = -1  # sys.stdout is StringIO or fake
            return not os.isatty(fileno)

        if opts.get('force_color', False):
            opts['color'] = True
        elif opts.get('no_color', False) or is_pipe() or salt.utils.platform.is_windows():
            opts['color'] = False
        else:
            opts['color'] = True
    else:
        if opts.get('force_color', False):
            opts['color'] = True
        elif opts.get('no_color', False) or salt.utils.platform.is_windows():
            opts['color'] = False
        else:
            pass

    outputters = salt.loader.outputters(opts)
    if out not in outputters:
        # Since the grains outputter was removed we don't need to fire this
        # error when old minions are asking for it
        if out != 'grains':
            log.error(
                'Invalid outputter %s specified, fall back to nested',
                out,
            )
        return outputters['nested']
    return outputters[out]


def out_format(data, out, opts=None, **kwargs):
    '''
    Return the formatted outputter string for the passed data
    '''
    return try_printout(data, out, opts, **kwargs)


def string_format(data, out, opts=None, **kwargs):
    '''
    Return the formatted outputter string, removing the ANSI escape sequences.
    '''
    raw_output = try_printout(data, out, opts, **kwargs)
    ansi_escape = re.compile(r'\x1b[^m]*m')
    return ansi_escape.sub('', raw_output)


def html_format(data, out, opts=None, **kwargs):
    '''
    Return the formatted string as HTML.
    '''
    ansi_escaped_string = string_format(data, out, opts, **kwargs)
    return ansi_escaped_string.replace(' ', '&nbsp;').replace('\n', '<br />')


def strip_esc_sequence(txt):
    '''
    Replace ESC (ASCII 27/Oct 33) to prevent unsafe strings
    from writing their own terminal manipulation commands
    '''
    if isinstance(txt, six.string_types):
        try:
            return txt.replace('\033', '?')
        except UnicodeDecodeError:
            return txt.replace(str('\033'), str('?'))  # future lint: disable=blacklisted-function
    else:
        return txt