예제 #1
0
    def format(cls, entry, *args, **kwargs):
        attrs = kwargs.get('attributes', [])
        attribute_transform_functions = kwargs.get(
            'attribute_transform_functions', {})
        key = kwargs.get('key', None)
        if key:
            output = jsutil.get_value(entry.result, key)
        else:
            # drop entry to the dict so that jsutil can operate
            entry = vars(entry)
            output = ''
            for attr in attrs:
                value = jsutil.get_value(entry, attr)
                value = strutil.strip_carriage_returns(strutil.unescape(value))
                if (isinstance(value, six.string_types) and len(value) > 0
                        and value[0] in ['{', '[']
                        and value[len(value) - 1] in ['}', ']']):
                    new_value = ast.literal_eval(value)
                    if type(new_value) in [dict, list]:
                        value = new_value
                if type(value) in [dict, list]:
                    # 1. To get a nice overhang indent get safe_dump to generate output with
                    #    the attribute key and then remove the attribute key from the string.
                    # 2. Drop the trailing newline
                    # 3. Set width to maxint so pyyaml does not split text. Anything longer
                    #    and likely we will see other issues like storage :P.
                    formatted_value = yaml.safe_dump({attr: value},
                                                     default_flow_style=False,
                                                     width=PLATFORM_MAXINT,
                                                     indent=2)[len(attr) +
                                                               2:-1]
                    value = ('\n' if isinstance(value, dict) else
                             '') + formatted_value
                    value = strutil.dedupe_newlines(value)

                # transform the value of our attribute so things like 'status'
                # and 'timestamp' are formatted nicely
                transform_function = attribute_transform_functions.get(
                    attr, lambda value: value)
                value = transform_function(value=value)

                output += ('\n' if output else '') + '%s: %s' % \
                    (DisplayColors.colorize(attr, DisplayColors.BLUE), value)

        if six.PY3:
            return strutil.unescape(str(output))
        else:
            # Assume Python 2
            return strutil.unescape(
                str(output)).decode('unicode_escape').encode('utf-8')
예제 #2
0
    def format(cls, subject, *args, **kwargs):
        attributes = kwargs.get('attributes', None)
        attribute_display_order = kwargs.get('attribute_display_order',
                                             DEFAULT_ATTRIBUTE_DISPLAY_ORDER)
        attribute_transform_functions = kwargs.get('attribute_transform_functions', {})

        if not attributes or 'all' in attributes:
            attributes = sorted([attr for attr in subject.__dict__
                                 if not attr.startswith('_')])

        for attr in attribute_display_order[::-1]:
            if attr in attributes:
                attributes.remove(attr)
                attributes = [attr] + attributes
        table = PrettyTable()
        table.field_names = ['Property', 'Value']
        table.max_width['Property'] = 20
        table.max_width['Value'] = 60
        table.padding_width = 1
        table.align = 'l'
        table.valign = 't'
        for attribute in attributes:
            value = cls._get_attribute_value(subject, attribute)
            if type(value) is dict or type(value) is list:
                value = json.dumps(value, indent=4)
            value = strutil.unescape(value)
            transfor_function = attribute_transform_functions.get(attribute,
                                                                  lambda value: value)
            value = transfor_function(value=value)
            table.add_row([attribute, value])
        return table
예제 #3
0
 def format(cls, entry, *args, **kwargs):
     attrs = kwargs.get('attributes', [])
     key = kwargs.get('key', None)
     if key:
         output = jsutil.get_value(entry.result, key)
     else:
         # drop entry to the dict so that jsutil can operate
         entry = vars(entry)
         output = ''
         for attr in attrs:
             value = jsutil.get_value(entry, attr)
             if (isinstance(value, basestring) and len(value) > 0 and
                     value[0] in ['{', '['] and value[len(value) - 1] in ['}', ']']):
                 new_value = ast.literal_eval(value)
                 if type(new_value) in [dict, list]:
                     value = new_value
             if type(value) in [dict, list]:
                 # 1. To get a nice overhang indent get safe_dump to generate output with
                 #    the attribute key and then remove the attribute key from the string.
                 # 2. Drop the trailing newline
                 # 3. Set width to maxint so pyyaml does not split text. Anything longer
                 #    and likely we will see other issues like storage :P.
                 formatted_value = yaml.safe_dump({attr: value},
                                                  default_flow_style=False,
                                                  width=sys.maxint,
                                                  indent=2)[len(attr) + 2:-1]
                 value = ('\n' if isinstance(value, dict) else '') + formatted_value
             output += ('\n' if output else '') + '%s: %s' % \
                 (DisplayColors.colorize(attr, DisplayColors.BLUE), value)
     return strutil.unescape(output)
예제 #4
0
파일: execution.py 프로젝트: lyandut/st2
    def format(cls, entry, *args, **kwargs):
        attrs = kwargs.get('attributes', [])
        attribute_transform_functions = kwargs.get('attribute_transform_functions', {})
        key = kwargs.get('key', None)
        if key:
            output = jsutil.get_value(entry.result, key)
        else:
            # drop entry to the dict so that jsutil can operate
            entry = vars(entry)
            output = ''
            for attr in attrs:
                value = jsutil.get_value(entry, attr)
                value = strutil.strip_carriage_returns(strutil.unescape(value))
                if (isinstance(value, six.string_types) and len(value) > 0 and
                        value[0] in ['{', '['] and value[len(value) - 1] in ['}', ']']):
                    new_value = ast.literal_eval(value)
                    if type(new_value) in [dict, list]:
                        value = new_value
                if type(value) in [dict, list]:
                    # 1. To get a nice overhang indent get safe_dump to generate output with
                    #    the attribute key and then remove the attribute key from the string.
                    # 2. Drop the trailing newline
                    # 3. Set width to maxint so pyyaml does not split text. Anything longer
                    #    and likely we will see other issues like storage :P.
                    formatted_value = yaml.safe_dump({attr: value},
                                                     default_flow_style=False,
                                                     width=PLATFORM_MAXINT,
                                                     indent=2)[len(attr) + 2:-1]
                    value = ('\n' if isinstance(value, dict) else '') + formatted_value
                    value = strutil.dedupe_newlines(value)

                # transform the value of our attribute so things like 'status'
                # and 'timestamp' are formatted nicely
                transform_function = attribute_transform_functions.get(attr,
                                                                       lambda value: value)
                value = transform_function(value=value)

                output += ('\n' if output else '') + '%s: %s' % \
                    (DisplayColors.colorize(attr, DisplayColors.BLUE), value)

        if six.PY3:
            return strutil.unescape(str(output))
        else:
            # Assume Python 2
            return strutil.unescape(str(output)).decode('unicode_escape').encode('utf-8')
예제 #5
0
파일: table.py 프로젝트: wingiti/st2
    def format(cls, subject, *args, **kwargs):
        attributes = kwargs.get("attributes", None)
        attribute_display_order = kwargs.get(
            "attribute_display_order", DEFAULT_ATTRIBUTE_DISPLAY_ORDER
        )
        attribute_transform_functions = kwargs.get("attribute_transform_functions", {})

        if not attributes or "all" in attributes:
            attributes = sorted(
                [attr for attr in subject.__dict__ if not attr.startswith("_")]
            )

        for attr in attribute_display_order[::-1]:
            if attr in attributes:
                attributes.remove(attr)
                attributes = [attr] + attributes
        table = PrettyTable()
        table.field_names = ["Property", "Value"]
        table.max_width["Property"] = 20
        table.max_width["Value"] = 60
        table.padding_width = 1
        table.align = "l"
        table.valign = "t"

        for attribute in attributes:
            if "." in attribute:
                field_names = attribute.split(".")
                value = cls._get_attribute_value(subject, field_names.pop(0))
                for name in field_names:
                    value = cls._get_attribute_value(value, name)
                    if type(value) is str:
                        break
            else:
                value = cls._get_attribute_value(subject, attribute)

            transform_function = attribute_transform_functions.get(
                attribute, lambda value: value
            )
            value = transform_function(value=value)

            if type(value) is dict or type(value) is list:
                value = json.dumps(value, indent=4)

            value = strutil.strip_carriage_returns(strutil.unescape(value))
            table.add_row([attribute, value])
        return table
예제 #6
0
    def format(cls, subject, *args, **kwargs):
        attributes = kwargs.get('attributes', None)
        attribute_display_order = kwargs.get('attribute_display_order',
                                             DEFAULT_ATTRIBUTE_DISPLAY_ORDER)
        attribute_transform_functions = kwargs.get('attribute_transform_functions', {})

        if not attributes or 'all' in attributes:
            attributes = sorted([attr for attr in subject.__dict__
                                 if not attr.startswith('_')])

        for attr in attribute_display_order[::-1]:
            if attr in attributes:
                attributes.remove(attr)
                attributes = [attr] + attributes
        table = PrettyTable()
        table.field_names = ['Property', 'Value']
        table.max_width['Property'] = 20
        table.max_width['Value'] = 60
        table.padding_width = 1
        table.align = 'l'
        table.valign = 't'

        for attribute in attributes:
            if '.' in attribute:
                field_names = attribute.split('.')
                value = cls._get_attribute_value(subject, field_names.pop(0))
                for name in field_names:
                    value = cls._get_attribute_value(value, name)
                    if type(value) is str:
                        break
            else:
                value = cls._get_attribute_value(subject, attribute)

            transform_function = attribute_transform_functions.get(attribute,
                                                                   lambda value: value)
            value = transform_function(value=value)

            if type(value) is dict or type(value) is list:
                value = json.dumps(value, indent=4)

            value = strutil.unescape(value)
            table.add_row([attribute, value])
        return table
예제 #7
0
 def format(cls, entry, *args, **kwargs):
     attrs = kwargs.get('attributes', [])
     key = kwargs.get('key', None)
     if key:
         output = jsutil.get_value(entry.result, key)
     else:
         output = ''
         for attr in attrs:
             value = getattr(entry, attr, None)
             if (isinstance(value, basestring) and len(value) > 0
                     and value[0] in ['{', '[']
                     and value[len(value) - 1] in ['}', ']']):
                 new_value = ast.literal_eval(value)
                 if type(new_value) in [dict, list]:
                     value = new_value
             if type(value) in [dict, list]:
                 value = ('\n' if isinstance(value, dict) else
                          '') + json.dumps(value, indent=4)
             output += ('\n' if output else
                        '') + '%s: %s' % (attr.upper(), value)
     return strutil.unescape(output)
예제 #8
0
 def format(cls, entry, *args, **kwargs):
     attrs = kwargs.get('attributes', [])
     key = kwargs.get('key', None)
     if key:
         output = jsutil.get_value(entry.result, key)
     else:
         # drop entry to the dict so that jsutil can operate
         entry = vars(entry)
         output = ''
         for attr in attrs:
             value = jsutil.get_value(entry, attr)
             if (isinstance(value, basestring) and len(value) > 0 and
                     value[0] in ['{', '['] and value[len(value) - 1] in ['}', ']']):
                 new_value = ast.literal_eval(value)
                 if type(new_value) in [dict, list]:
                     value = new_value
             if type(value) in [dict, list]:
                 value = ('\n' if isinstance(value, dict) else '') + json.dumps(value, indent=4)
             output += ('\n' if output else '') + '%s: %s' % \
                 (DisplayColors.colorize(attr, DisplayColors.BLUE), value)
     return strutil.unescape(output)
예제 #9
0
 def test_unicode_string(self):
     in_str = '\u8c03\u7528CMS\u63a5\u53e3\u5220\u9664\u865a\u62df\u76ee\u5f55'
     out_str = strutil.unescape(in_str)
     self.assertEqual(out_str, in_str)
예제 #10
0
 def test_unescape(self):
     in_str = 'Action execution result double escape \\"stuffs\\".\\r\\n'
     expected = 'Action execution result double escape \"stuffs\".\r\n'
     out_str = strutil.unescape(in_str)
     self.assertEqual(out_str, expected)
예제 #11
0
파일: execution.py 프로젝트: StackStorm/st2
    def format(cls, entry, *args, **kwargs):
        attrs = kwargs.get('attributes', [])
        attribute_transform_functions = kwargs.get('attribute_transform_functions', {})
        key = kwargs.get('key', None)
        if key:
            output = jsutil.get_value(entry.result, key)
        else:
            # drop entry to the dict so that jsutil can operate
            entry = vars(entry)
            output = ''
            for attr in attrs:
                value = jsutil.get_value(entry, attr)
                value = strutil.strip_carriage_returns(strutil.unescape(value))
                # TODO: This check is inherently flawed since it will crash st2client
                # if the leading character is objectish start and last character is objectish
                # end but the string isn't supposed to be a object. Try/Except will catch
                # this for now, but this should be improved.
                if (isinstance(value, six.string_types) and len(value) > 0 and
                        value[0] in ['{', '['] and value[len(value) - 1] in ['}', ']']):
                    try:
                        new_value = ast.literal_eval(value)
                    except:
                        new_value = value
                    if type(new_value) in [dict, list]:
                        value = new_value
                if type(value) in [dict, list]:
                    # 1. To get a nice overhang indent get safe_dump to generate output with
                    #    the attribute key and then remove the attribute key from the string.
                    # 2. Drop the trailing newline
                    # 3. Set width to maxint so pyyaml does not split text. Anything longer
                    #    and likely we will see other issues like storage :P.
                    formatted_value = yaml.safe_dump({attr: value},
                                                     default_flow_style=False,
                                                     width=PLATFORM_MAXINT,
                                                     indent=2)[len(attr) + 2:-1]
                    value = ('\n' if isinstance(value, dict) else '') + formatted_value
                    value = strutil.dedupe_newlines(value)

                # transform the value of our attribute so things like 'status'
                # and 'timestamp' are formatted nicely
                transform_function = attribute_transform_functions.get(attr,
                                                                       lambda value: value)
                value = transform_function(value=value)

                output += ('\n' if output else '') + '%s: %s' % \
                    (DisplayColors.colorize(attr, DisplayColors.BLUE), value)

            output_schema = entry.get('action', {}).get('output_schema')
            schema_check = get_config()['general']['silence_schema_output']
            if not output_schema and kwargs.get('with_schema'):
                rendered_schema = {
                    'output_schema': schema.render_output_schema_from_output(entry['result'])
                }

                rendered_schema = yaml.safe_dump(rendered_schema, default_flow_style=False)
                output += '\n'
                output += _print_bordered(
                    "Based on the action output the following inferred schema was built:"
                    "\n\n"
                    "%s" % rendered_schema
                )
            elif not output_schema and not schema_check:
                output += (
                    "\n\n** This action does not have an output_schema. "
                    "Run again with --with-schema to see a suggested schema."
                )

        if six.PY3:
            return strutil.unescape(str(output))
        else:
            # Assume Python 2
            try:
                result = strutil.unescape(str(output)).decode('unicode_escape').encode('utf-8')
            except UnicodeDecodeError:
                # String contains a value which is not an unicode escape sequence, ignore the error
                result = strutil.unescape(str(output))
            return result
예제 #12
0
    def format(cls, entries, *args, **kwargs):
        attributes = kwargs.get('attributes', [])
        attribute_transform_functions = kwargs.get(
            'attribute_transform_functions', {})
        widths = kwargs.get('widths', [])
        widths = widths or []

        if not widths and attributes:
            # Dynamically calculate column size based on the terminal size
            lines, cols = get_terminal_size()

            if attributes[0] == 'id':
                # consume iterator and save as entries so collection is accessible later.
                entries = [e for e in entries]
                # first column contains id, make sure it's not broken up
                first_col_width = cls._get_required_column_width(
                    values=[e.id for e in entries],
                    minimum_width=MIN_ID_COL_WIDTH)
                cols = (cols - first_col_width)
                col_width = int(math.floor((cols / len(attributes))))
            else:
                col_width = int(math.floor((cols / len(attributes))))
                first_col_width = col_width
            widths = []
            subtract = 0
            for index in range(0, len(attributes)):
                attribute_name = attributes[index]

                if index == 0:
                    widths.append(first_col_width)
                    continue

                if attribute_name in COLORIZED_ATTRIBUTES:
                    current_col_width = COLORIZED_ATTRIBUTES[attribute_name][
                        'col_width']
                    subtract += (current_col_width - col_width)
                else:
                    # Make sure we subtract the added width from the last column so we account
                    # for the fixed width columns and make sure table is not wider than the
                    # terminal width.
                    if index == (len(attributes) - 1) and subtract:
                        current_col_width = (col_width - subtract)

                        if current_col_width <= MIN_COL_WIDTH:
                            # Make sure column width is always grater than MIN_COL_WIDTH
                            current_col_width = MIN_COL_WIDTH
                    else:
                        current_col_width = col_width

                widths.append(current_col_width)

        if not attributes or 'all' in attributes:
            entries = list(entries) if entries else []

            if len(entries) >= 1:
                attributes = entries[0].__dict__.keys()
                attributes = sorted(
                    [attr for attr in attributes if not attr.startswith('_')])
            else:
                # There are no entries so we can't infer available attributes
                attributes = []

        # Determine table format.
        if len(attributes) == len(widths):
            # Customize width for each column.
            columns = zip(attributes, widths)
        else:
            # If only 1 width value is provided then
            # apply it to all columns else fix at 28.
            width = widths[0] if len(widths) == 1 else 28
            columns = zip(attributes,
                          [width for i in range(0, len(attributes))])

        # Format result to table.
        table = PrettyTable()
        for column in columns:
            table.field_names.append(column[0])
            table.max_width[column[0]] = column[1]
        table.padding_width = 1
        table.align = 'l'
        table.valign = 't'
        for entry in entries:
            # TODO: Improve getting values of nested dict.
            values = []
            for field_name in table.field_names:
                if '.' in field_name:
                    field_names = field_name.split('.')
                    value = getattr(entry, field_names.pop(0), {})
                    for name in field_names:
                        value = cls._get_field_value(value, name)
                        if type(value) is str:
                            break
                    value = strutil.strip_carriage_returns(
                        strutil.unescape(value))
                    values.append(value)
                else:
                    value = cls._get_simple_field_value(entry, field_name)
                    transform_function = attribute_transform_functions.get(
                        field_name, lambda value: value)
                    value = transform_function(value=value)
                    value = strutil.strip_carriage_returns(
                        strutil.unescape(value))
                    values.append(value)
            table.add_row(values)

        # width for the note
        global table_width
        try:
            table_width = len(table.get_string().split("\n")[0])
        except IndexError:
            table_width = 0

        return table
예제 #13
0
    def format(cls, entry, *args, **kwargs):
        attrs = kwargs.get('attributes', [])
        attribute_transform_functions = kwargs.get(
            'attribute_transform_functions', {})
        key = kwargs.get('key', None)
        if key:
            output = jsutil.get_value(entry.result, key)
        else:
            # drop entry to the dict so that jsutil can operate
            entry = vars(entry)
            output = ''
            for attr in attrs:
                value = jsutil.get_value(entry, attr)
                value = strutil.strip_carriage_returns(strutil.unescape(value))
                # TODO: This check is inherently flawed since it will crash st2client
                # if the leading character is objectish start and last character is objectish
                # end but the string isn't supposed to be a object. Try/Except will catch
                # this for now, but this should be improved.
                if (isinstance(value, six.string_types) and len(value) > 0
                        and value[0] in ['{', '[']
                        and value[len(value) - 1] in ['}', ']']):
                    try:
                        new_value = ast.literal_eval(value)
                    except:
                        new_value = value
                    if type(new_value) in [dict, list]:
                        value = new_value
                if type(value) in [dict, list]:
                    # 1. To get a nice overhang indent get safe_dump to generate output with
                    #    the attribute key and then remove the attribute key from the string.
                    # 2. Drop the trailing newline
                    # 3. Set width to maxint so pyyaml does not split text. Anything longer
                    #    and likely we will see other issues like storage :P.
                    formatted_value = yaml.safe_dump({attr: value},
                                                     default_flow_style=False,
                                                     width=PLATFORM_MAXINT,
                                                     indent=2)[len(attr) +
                                                               2:-1]
                    value = ('\n' if isinstance(value, dict) else
                             '') + formatted_value
                    value = strutil.dedupe_newlines(value)

                # transform the value of our attribute so things like 'status'
                # and 'timestamp' are formatted nicely
                transform_function = attribute_transform_functions.get(
                    attr, lambda value: value)
                value = transform_function(value=value)

                output += ('\n' if output else '') + '%s: %s' % \
                    (DisplayColors.colorize(attr, DisplayColors.BLUE), value)

            output_schema = entry.get('action', {}).get('output_schema')
            schema_check = get_config()['general']['silence_schema_output']
            if not output_schema and kwargs.get('with_schema'):
                rendered_schema = {
                    'output_schema':
                    schema.render_output_schema_from_output(entry['result'])
                }

                rendered_schema = yaml.safe_dump(rendered_schema,
                                                 default_flow_style=False)
                output += '\n'
                output += _print_bordered(
                    "Based on the action output the following inferred schema was built:"
                    "\n\n"
                    "%s" % rendered_schema)
            elif not output_schema and not schema_check:
                output += (
                    "\n\n** This action does not have an output_schema. "
                    "Run again with --with-schema to see a suggested schema.")

        if six.PY3:
            return strutil.unescape(str(output))
        else:
            # Assume Python 2
            try:
                result = strutil.unescape(
                    str(output)).decode('unicode_escape').encode('utf-8')
            except UnicodeDecodeError:
                # String contains a value which is not an unicode escape sequence, ignore the error
                result = strutil.unescape(str(output))
            return result
예제 #14
0
    def format(cls, entries, *args, **kwargs):
        attributes = kwargs.get('attributes', [])
        attribute_transform_functions = kwargs.get('attribute_transform_functions', {})
        widths = kwargs.get('widths', [])
        widths = widths or []

        if not widths and attributes:
            # Dynamically calculate column size based on the terminal size
            lines, cols = get_terminal_size()

            if attributes[0] == 'id':
                # consume iterator and save as entries so collection is accessible later.
                entries = [e for e in entries]
                # first column contains id, make sure it's not broken up
                first_col_width = cls._get_required_column_width(values=[e.id for e in entries],
                                                                 minimum_width=MIN_ID_COL_WIDTH)
                cols = (cols - first_col_width)
                col_width = int(math.floor((cols / len(attributes))))
            else:
                col_width = int(math.floor((cols / len(attributes))))
                first_col_width = col_width

            widths = []
            for index in range(0, len(attributes)):
                if index == 0:
                    widths.append(first_col_width)
                else:
                    widths.append(col_width)

        if not attributes or 'all' in attributes:
            attributes = sorted([attr for attr in entries[0].__dict__
                                 if not attr.startswith('_')])

        # Determine table format.
        if len(attributes) == len(widths):
            # Customize width for each column.
            columns = zip(attributes, widths)
        else:
            # If only 1 width value is provided then
            # apply it to all columns else fix at 28.
            width = widths[0] if len(widths) == 1 else 28
            columns = zip(attributes,
                          [width for i in range(0, len(attributes))])

        # Format result to table.
        table = PrettyTable()
        for column in columns:
            table.field_names.append(column[0])
            table.max_width[column[0]] = column[1]
        table.padding_width = 1
        table.align = 'l'
        table.valign = 't'
        for entry in entries:
            # TODO: Improve getting values of nested dict.
            values = []
            for field_name in table.field_names:
                if '.' in field_name:
                    field_names = field_name.split('.')
                    value = getattr(entry, field_names.pop(0), {})
                    for name in field_names:
                        value = cls._get_field_value(value, name)
                        if type(value) is str:
                            break
                    value = strutil.unescape(value)
                    values.append(value)
                else:
                    value = cls._get_simple_field_value(entry, field_name)
                    transform_function = attribute_transform_functions.get(field_name,
                                                                          lambda value: value)
                    value = transform_function(value=value)
                    value = strutil.unescape(value)
                    values.append(value)
            table.add_row(values)
        return table
예제 #15
0
파일: table.py 프로젝트: lyandut/st2
    def format(cls, entries, *args, **kwargs):
        attributes = kwargs.get('attributes', [])
        attribute_transform_functions = kwargs.get('attribute_transform_functions', {})
        widths = kwargs.get('widths', [])
        widths = widths or []

        if not widths and attributes:
            # Dynamically calculate column size based on the terminal size
            lines, cols = get_terminal_size()

            if attributes[0] == 'id':
                # consume iterator and save as entries so collection is accessible later.
                entries = [e for e in entries]
                # first column contains id, make sure it's not broken up
                first_col_width = cls._get_required_column_width(values=[e.id for e in entries],
                                                                 minimum_width=MIN_ID_COL_WIDTH)
                cols = (cols - first_col_width)
                col_width = int(math.floor((cols / len(attributes))))
            else:
                col_width = int(math.floor((cols / len(attributes))))
                first_col_width = col_width
            widths = []
            subtract = 0
            for index in range(0, len(attributes)):
                attribute_name = attributes[index]

                if index == 0:
                    widths.append(first_col_width)
                    continue

                if attribute_name in COLORIZED_ATTRIBUTES:
                    current_col_width = COLORIZED_ATTRIBUTES[attribute_name]['col_width']
                    subtract += (current_col_width - col_width)
                else:
                    # Make sure we subtract the added width from the last column so we account
                    # for the fixed width columns and make sure table is not wider than the
                    # terminal width.
                    if index == (len(attributes) - 1) and subtract:
                        current_col_width = (col_width - subtract)

                        if current_col_width <= MIN_COL_WIDTH:
                            # Make sure column width is always grater than MIN_COL_WIDTH
                            current_col_width = MIN_COL_WIDTH
                    else:
                        current_col_width = col_width

                widths.append(current_col_width)

        if not attributes or 'all' in attributes:
            entries = list(entries) if entries else []

            if len(entries) >= 1:
                attributes = list(entries[0].__dict__.keys())
                attributes = sorted([attr for attr in attributes if not attr.startswith('_')])
            else:
                # There are no entries so we can't infer available attributes
                attributes = []

        # Determine table format.
        if len(attributes) == len(widths):
            # Customize width for each column.
            columns = zip(attributes, widths)
        else:
            # If only 1 width value is provided then
            # apply it to all columns else fix at 28.
            width = widths[0] if len(widths) == 1 else 28
            columns = zip(attributes,
                          [width for i in range(0, len(attributes))])

        # Format result to table.
        table = PrettyTable()
        for column in columns:
            table.field_names.append(column[0])
            table.max_width[column[0]] = column[1]
        table.padding_width = 1
        table.align = 'l'
        table.valign = 't'
        for entry in entries:
            # TODO: Improve getting values of nested dict.
            values = []
            for field_name in table.field_names:
                if '.' in field_name:
                    field_names = field_name.split('.')
                    value = getattr(entry, field_names.pop(0), {})
                    for name in field_names:
                        value = cls._get_field_value(value, name)
                        if type(value) is str:
                            break
                    value = strutil.strip_carriage_returns(strutil.unescape(value))
                    values.append(value)
                else:
                    value = cls._get_simple_field_value(entry, field_name)
                    transform_function = attribute_transform_functions.get(field_name,
                                                                           lambda value: value)
                    value = transform_function(value=value)
                    value = strutil.strip_carriage_returns(strutil.unescape(value))
                    values.append(value)
            table.add_row(values)

        # width for the note
        try:
            cls.table_width = len(table.get_string().split("\n")[0])
        except IndexError:
            cls.table_width = 0

        return table
예제 #16
0
 def test_unescape(self):
     in_str = 'Action execution result double escape \\"stuffs\\".\\r\\n'
     expected = 'Action execution result double escape \"stuffs\".\r\n'
     out_str = strutil.unescape(in_str)
     self.assertEqual(out_str, expected)
예제 #17
0
 def test_unicode_string(self):
     in_str = '\u8c03\u7528CMS\u63a5\u53e3\u5220\u9664\u865a\u62df\u76ee\u5f55'
     out_str = strutil.unescape(in_str)
     self.assertEqual(out_str, in_str)
예제 #18
0
    def format(cls, entry, *args, **kwargs):
        attrs = kwargs.get("attributes", [])
        attribute_transform_functions = kwargs.get(
            "attribute_transform_functions", {})
        key = kwargs.get("key", None)
        if key:
            output = jsutil.get_value(entry.result, key)
        else:
            # drop entry to the dict so that jsutil can operate
            entry = vars(entry)
            output = ""
            for attr in attrs:
                value = jsutil.get_value(entry, attr)
                value = strutil.strip_carriage_returns(strutil.unescape(value))

                # transform the value of our attribute so things like 'status'
                # and 'timestamp' are formatted nicely
                transform_function = attribute_transform_functions.get(
                    attr, lambda value: value)
                value = transform_function(value=value)

                # TODO: This check is inherently flawed since it will crash st2client
                # if the leading character is objectish start and last character is objectish
                # end but the string isn't supposed to be a object. Try/Except will catch
                # this for now, but this should be improved.
                if (isinstance(value, six.string_types) and len(value) > 0
                        and value[0] in ["{", "["]
                        and value[len(value) - 1] in ["}", "]"]):
                    try:
                        new_value = ast.literal_eval(value)
                    except:
                        new_value = value
                    if type(new_value) in [dict, list]:
                        value = new_value
                if isinstance(value, (dict, list)):
                    # 1. To get a nice overhang indent get safe_dump to generate output with
                    #    the attribute key and then remove the attribute key from the string.
                    # 2. Drop the trailing newline
                    # 3. Set width to maxint so pyyaml does not split text. Anything longer
                    #    and likely we will see other issues like storage :P.
                    # NOTE: We use C version of the safe dumper which is faster.
                    # Keep in mind that using YamlSafeDumper is the same as using yaml.safe_dumps
                    # (same class is used underneath when using yaml.safe_dump) so the code is safe.
                    formatted_value = yaml.dump(
                        {attr: value},
                        default_flow_style=False,
                        width=PLATFORM_MAXINT,
                        indent=2,
                        Dumper=YamlSafeDumper,
                    )[len(attr) + 2:-1]

                    if isinstance(value, list):
                        # Indent list values with 2 spaces for a nicer display.
                        lines = formatted_value.split("\n")
                        formatted_value = []
                        for line in lines:
                            formatted_value.append("  %s" % (line))

                        formatted_value = "\n".join(formatted_value)

                    value = ("\n" if isinstance(value, (dict, list)) else
                             "") + formatted_value
                    value = strutil.dedupe_newlines(value)

                # transform the value of our attribute so things like 'status'
                # and 'timestamp' are formatted nicely
                transform_function = attribute_transform_functions.get(
                    attr, lambda value: value)
                value = transform_function(value=value)

                output += ("\n" if output else "") + "%s: %s" % (
                    DisplayColors.colorize(attr, DisplayColors.BLUE),
                    value,
                )

            output_schema = entry.get("action", {}).get("output_schema")
            schema_check = get_config()["general"]["silence_schema_output"]
            if not output_schema and kwargs.get("with_schema"):
                rendered_schema = {
                    "output_schema":
                    schema.render_output_schema_from_output(entry["result"])
                }

                rendered_schema = yaml.safe_dump(rendered_schema,
                                                 default_flow_style=False)
                output += "\n"
                output += _print_bordered(
                    "Based on the action output the following inferred schema was built:"
                    "\n\n"
                    "%s" % rendered_schema)
            elif not output_schema and not schema_check:
                output += (
                    "\n\n** This action does not have an output_schema. "
                    "Run again with --with-schema to see a suggested schema.")

        if six.PY3:
            return strutil.unescape(str(output))
        else:
            # Assume Python 2
            try:
                result = (strutil.unescape(
                    str(output)).decode("unicode_escape").encode("utf-8"))
            except UnicodeDecodeError:
                # String contains a value which is not an unicode escape sequence, ignore the error
                result = strutil.unescape(str(output))
            return result