<commit_before>import subprocess
import re

from .parser import BlockParser
from .parser import colon_field
from .parser import once_per_block
from .parser import ignore_rule
from .parser import rule
from .parser import yesnobool
from .parser import oknokbool
from .parser import parse_bytes
from .parser import parse_time


class MegaCLIBase(object):
    def __init__(self, megacli_path):
        self.megacli_path = megacli_path

    def run_command(self, *args):
        exit_re = re.compile('^Exit Code: (.*)$')
        p = subprocess.Popen(
            [self.megacli_path] + list(args),
            shell=False,
            stdout=subprocess.PIPE
        )
        for line in p.communicate()[0].split('\n'):
            emd = exit_re.match(line)
            if emd:
                # exit code is usually meaningless
                rv = int(emd.groups()[0], 16)
                rv = rv
            else:
                yield line

    def extract_by_regex(self, regex, lines, one_only=False):
        if isinstance(regex, basestring):
            regex = re.compile(regex)
        result = []
        for line in lines:
            md = regex.match(line)
            if md:
                if one_only:
                    return md.groups()
                else:
                    result.append(md.groups)
        if one_only:
            raise Exception('Expected one match for %s, got %d. Input was %s' % (
                regex,
                len(result),
                '\n'.join(lines)
            ))
        return result

    @property
    def controller_count(self):
        return int(self.extract_by_regex(
            r'^Controller Count: ([^.]+)\.$',
            self.run_command('-adpCount'),
            one_only=True
        )[0])

    @property
    def controllers(self):
        for i in range(self.controller_count):
            yield MegaCLIController(i, self)


class Component(object):
    REQUIRED_FIELDS = tuple()

    def __init__(self, parent, props=None):
        if props is None:
            self.props = {}
        else:
            self.props = props
        self.parent = parent

    def __setitem__(self, key, value):
        self.props[key] = value

    def __getitem__(self, key):
        return self.props[key]

    @property
    def identifier(self):
        return NotImplementedError()

    @property
    def health_status(self):
        return NotImplementedError()

    @property
    def health_messages(self):
        for bad_key, bad_value in sorted(self.health_status[0].items()):
            yield '%s was unexpectedly %r' % (bad_key, bad_value)

    @property
    def healthy(self):
        return self.health_status[1]

    def __str__(self):
        return self.identifier

    @classmethod
    def from_output(kls, lines, parent):
        lds = []
        for d in kls.PARSER.parse(lines):
            args = []
            for f in kls.REQUIRED_FIELDS:
                args.append(d.pop(f))
            args.extend([parent, d])
            lds.append(kls(*args))
        return lds


class Disk(Component):
    ERROR_COUNT_KEYS = (
        'Media Error Count',
        'Predictive Failure Count',
        'Other Error Count'
    )
    ERROR_BOOL_KEYS = ('Drive has flagged a S.M.A.R.T alert', )
    REQUIRED_FIELDS = ('Enclosure Device ID', 'Slot Number')

    PARSER = BlockParser(rules=[<commit_msg>stop monitoring Other Error Count for now<commit_after>import subprocess
import re

from .parser import BlockParser
from .parser import colon_field
from .parser import once_per_block
from .parser import ignore_rule
from .parser import rule
from .parser import yesnobool
from .parser import oknokbool
from .parser import parse_bytes
from .parser import parse_time


class MegaCLIBase(object):
    def __init__(self, megacli_path):
        self.megacli_path = megacli_path

    def run_command(self, *args):
        exit_re = re.compile('^Exit Code: (.*)$')
        p = subprocess.Popen(
            [self.megacli_path] + list(args),
            shell=False,
            stdout=subprocess.PIPE
        )
        for line in p.communicate()[0].split('\n'):
            emd = exit_re.match(line)
            if emd:
                # exit code is usually meaningless
                rv = int(emd.groups()[0], 16)
                rv = rv
            else:
                yield line

    def extract_by_regex(self, regex, lines, one_only=False):
        if isinstance(regex, basestring):
            regex = re.compile(regex)
        result = []
        for line in lines:
            md = regex.match(line)
            if md:
                if one_only:
                    return md.groups()
                else:
                    result.append(md.groups)
        if one_only:
            raise Exception('Expected one match for %s, got %d. Input was %s' % (
                regex,
                len(result),
                '\n'.join(lines)
            ))
        return result

    @property
    def controller_count(self):
        return int(self.extract_by_regex(
            r'^Controller Count: ([^.]+)\.$',
            self.run_command('-adpCount'),
            one_only=True
        )[0])

    @property
    def controllers(self):
        for i in range(self.controller_count):
            yield MegaCLIController(i, self)


class Component(object):
    REQUIRED_FIELDS = tuple()

    def __init__(self, parent, props=None):
        if props is None:
            self.props = {}
        else:
            self.props = props
        self.parent = parent

    def __setitem__(self, key, value):
        self.props[key] = value

    def __getitem__(self, key):
        return self.props[key]

    @property
    def identifier(self):
        return NotImplementedError()

    @property
    def health_status(self):
        return NotImplementedError()

    @property
    def health_messages(self):
        for bad_key, bad_value in sorted(self.health_status[0].items()):
            yield '%s was unexpectedly %r' % (bad_key, bad_value)

    @property
    def healthy(self):
        return self.health_status[1]

    def __str__(self):
        return self.identifier

    @classmethod
    def from_output(kls, lines, parent):
        lds = []
        for d in kls.PARSER.parse(lines):
            args = []
            for f in kls.REQUIRED_FIELDS:
                args.append(d.pop(f))
            args.extend([parent, d])
            lds.append(kls(*args))
        return lds


class Disk(Component):
    ERROR_COUNT_KEYS = (
        'Media Error Count',
        'Predictive Failure Count',
    )
    ERROR_BOOL_KEYS = ('Drive has flagged a S.M.A.R.T alert', )
    REQUIRED_FIELDS = ('Enclosure Device ID', 'Slot Number')

    PARSER = BlockParser(rules=[
{'fraction_non_alphanumeric': 0.10077288941736029, 'fraction_numerical': 0.002080856123662307, 'mean_word_length': 1.8830334190231361, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7213279', 'n_tokens_mistral': 2024, 'n_tokens_neox': 1939, 'n_words': 510}