<commit_before># Copyright (C) 2015-2016 Red Hat, Inc.
# (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; If not, see <http://www.gnu.org/licenses/>.
#
# Author: <NAME> <<EMAIL>>
#         <NAME> <<EMAIL>>

import os
import errno
import re

from lsm import (
    IPlugin, Client, Capabilities, VERSION, LsmError, ErrorNumber, uri_parse,
    System, Pool, size_human_2_size_bytes, search_property, Volume, Disk,
    LocalDisk, Battery, int_div)

from lsm.plugin.hpsa.utils import cmd_exec, ExecError

def _handle_errors(method):
    def _wrapper(*args, **kwargs):
        try:
            return method(*args, **kwargs)
        except LsmError:
            raise
        except KeyError as key_error:
            raise LsmError(
                ErrorNumber.PLUGIN_BUG,
                "Expected key missing from SmartArray ssacli output:%s, "
                "please try to upgrade ssacli tool"
                % key_error)
        except ExecError as exec_error:
            if 'No controllers detected' in exec_error.stdout:
                raise LsmError(
                    ErrorNumber.NOT_FOUND_SYSTEM,
                    "No HP SmartArray deteceted by ssacli.")
            else:
                raise LsmError(ErrorNumber.PLUGIN_BUG, str(exec_error))
        except Exception as common_error:
            raise LsmError(
                ErrorNumber.PLUGIN_BUG,
                "Got unexpected error %s, please try to upgrade ssacli tool"
                % common_error)

    return _wrapper


def _sysfs_file_read(path):
    """
    Return the content of file with terminate \0 and \n removed.
    Return None if error.
    """
    try:
        with open(path) as f:
            return f.read().strip()
    except:
        return None


def _sys_status_of(hp_ctrl_status):
    """
    Base on data of "ssacli ctrl all show status"
    """
    status_info = ''
    status = System.STATUS_UNKNOWN
    check_list = [
        'Controller Status', 'Cache Status', 'Battery/Capacitor Status']
    for key_name in check_list:
        if key_name in hp_ctrl_status:
            if hp_ctrl_status[key_name] == 'Not Configured':
                status = System.STATUS_OK
            elif hp_ctrl_status[key_name] == 'OK':
                status = System.STATUS_OK
            else:
                status = System.STATUS_OTHER
            status_info += ' "%s"=[%s]' % (str(key_name),
                                          str(hp_ctrl_status[key_name]))

    return status, status_info


# This fixes an HPSSACLI  bug where "Mirror Group N:" items are not
# properly indented. This will indent (shunt) them to the appropriate level.
def _fix_mirror_group_lines(output_lines):
    mg_indent_level = None
    for line_num in range(len(output_lines)):
        cur_line = output_lines[line_num]
        cur_indent_level = len(cur_line) - len(cur_line.lstrip())
        if cur_line.lstrip().startswith('Mirror Group '):
            mg_indent_level = cur_indent_level
        elif ((mg_indent_level is not None) and
              (cur_indent_level < mg_indent_level)):
            shunted_line = ' '*2*(mg_indent_level-cur_indent_level) + cur_line
            output_lines[line_num] = shunted_line
        elif mg_indent_level is not None:
            mg_indent_level = None


def _parse_ssacli_output(output):
    """
    Got a output string of ssacli to dictionary(nested).
    Workflow:
    0. Check out top and the second indention level's space count.
    1. Check current line and next line to determine whether current line is
       a start of new section.
    2. Skip all un-required sections and their data and sub-sections.
    3. If current line is the start of new section, create an empty dictionary
       where following subsections or data could be stored in.
    """
    required_sections = ['Array:', 'unassigned', 'HBA Drives', 'array',
                         'Controller Status', 'Cache Status',
                         'Battery/Capacitor Status', 'Unassigned', 'Array']

    output_lines = [
        l for l in output.split("\n")
        if l and not l.startswith('Note:')]

    _fix_mirror_group_lines(output_lines)

    data = {}<commit_msg>hpsa: Handle 'Warning:' in output<commit_after># Copyright (C) 2015-2016 Red Hat, Inc.
# (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; If not, see <http://www.gnu.org/licenses/>.
#
# Author: <NAME> <<EMAIL>>
#         <NAME> <<EMAIL>>

import os
import errno
import re

from lsm import (
    IPlugin, Client, Capabilities, VERSION, LsmError, ErrorNumber, uri_parse,
    System, Pool, size_human_2_size_bytes, search_property, Volume, Disk,
    LocalDisk, Battery, int_div)

from lsm.plugin.hpsa.utils import cmd_exec, ExecError

def _handle_errors(method):
    def _wrapper(*args, **kwargs):
        try:
            return method(*args, **kwargs)
        except LsmError:
            raise
        except KeyError as key_error:
            raise LsmError(
                ErrorNumber.PLUGIN_BUG,
                "Expected key missing from SmartArray ssacli output:%s, "
                "please try to upgrade ssacli tool"
                % key_error)
        except ExecError as exec_error:
            if 'No controllers detected' in exec_error.stdout:
                raise LsmError(
                    ErrorNumber.NOT_FOUND_SYSTEM,
                    "No HP SmartArray deteceted by ssacli.")
            else:
                raise LsmError(ErrorNumber.PLUGIN_BUG, str(exec_error))
        except Exception as common_error:
            raise LsmError(
                ErrorNumber.PLUGIN_BUG,
                "Got unexpected error %s, please try to upgrade ssacli tool"
                % common_error)

    return _wrapper


def _sysfs_file_read(path):
    """
    Return the content of file with terminate \0 and \n removed.
    Return None if error.
    """
    try:
        with open(path) as f:
            return f.read().strip()
    except:
        return None


def _sys_status_of(hp_ctrl_status):
    """
    Base on data of "ssacli ctrl all show status"
    """
    status_info = ''
    status = System.STATUS_UNKNOWN
    check_list = [
        'Controller Status', 'Cache Status', 'Battery/Capacitor Status']
    for key_name in check_list:
        if key_name in hp_ctrl_status:
            if hp_ctrl_status[key_name] == 'Not Configured':
                status = System.STATUS_OK
            elif hp_ctrl_status[key_name] == 'OK':
                status = System.STATUS_OK
            else:
                status = System.STATUS_OTHER
            status_info += ' "%s"=[%s]' % (str(key_name),
                                          str(hp_ctrl_status[key_name]))

    return status, status_info


# This fixes an HPSSACLI  bug where "Mirror Group N:" items are not
# properly indented. This will indent (shunt) them to the appropriate level.
def _fix_mirror_group_lines(output_lines):
    mg_indent_level = None
    for line_num in range(len(output_lines)):
        cur_line = output_lines[line_num]
        cur_indent_level = len(cur_line) - len(cur_line.lstrip())
        if cur_line.lstrip().startswith('Mirror Group '):
            mg_indent_level = cur_indent_level
        elif ((mg_indent_level is not None) and
              (cur_indent_level < mg_indent_level)):
            shunted_line = ' '*2*(mg_indent_level-cur_indent_level) + cur_line
            output_lines[line_num] = shunted_line
        elif mg_indent_level is not None:
            mg_indent_level = None


def _sanitize_output(output_lines, return_warning=False):
    """
    Check for and process 'Warning: ' and 'Note:', strip empty lines
    :param output_lines:
    :return: array of strings or a tuple which is an array of strings and
             the warning message if found.
    """
    warning_msg = None

    num_lines = len(output_lines)
    sanitized = []
    i = 0
    while i < num_lines:
        if output_lines[i]:
            # Newer versions report things like media errors
            if output_lines[i].startswith('Warning:'):
                start = i + 1
                warning = output_lines[i]

                # Append all lines until next empty
                for z in range(start, num_lines):
                    i += 1
                    if output_lines[z]:
                        warning += ' ' + output_lines[z]
                    else:
                        break

                if warning_msg is None:
                    warning_msg = warning[9:]

            elif output_lines[i].startswith('Note:'):
                # Discard
                pass
            else:
                sanitized.append(output_lines[i])

        i += 1

    if return_warning:
        return sanitized, warning_msg

    return sanitized


def _parse_ssacli_output(output):
    """
    Got a output string of ssacli to dictionary(nested).
    Workflow:
    0. Check out top and the second indention level's space count.
    1. Check current line and next line to determine whether current line is
       a start of new section.
    2. Skip all un-required sections and their data and sub-sections.
    3. If current line is the start of new section, create an empty dictionary
       where following subsections or data could be stored in.
    """
    required_sections = ['Array:', 'unassigned', 'HBA Drives', 'array',
                         'Controller Status', 'Cache Status',
                         'Battery/Capacitor Status', 'Unassigned', 'Array']

    output_lines = _sanitize_output(output.split("\n"))
    _fix_mirror_group_lines(output_lines)

    data = {}
{'fraction_non_alphanumeric': 0.07885703683087485, 'fraction_numerical': 0.005102514147880138, 'mean_word_length': 2.2736106893410266, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '191043', 'n_tokens_mistral': 3100, 'n_tokens_neox': 2962, 'n_words': 1021}