<commit_before>"""Provide the Config class.
"""

import os
import os.path
import getpass
import argparse
import ConfigParser
from icat.exception import *

__all__ = ['Configuration', 'Config']


cfgdirs = [ "/etc/icat", 
            os.path.expanduser("~/.config/icat"), 
            os.path.expanduser("~/.icat"), "" ]
"""Search path for the configuration file"""
cfgfile = "icat.cfg"
"""Configuration file name"""
defaultsection = None


class ConfigVariable(object):
    """Describe a configuration variable.
    """
    def __init__(self, name, envvar, optional, default, subst):
        self.name = name
        self.envvar = envvar
        self.optional = optional
        self.default = default
        self.subst = subst


class ConfigSource(object):
    """A configuration source.

    This is the base class for all configuration sources, such as
    command line arguments, configuration files, and environment
    variables.
    """
    def get(self, variable):
        raise NotImplementedError


class ConfigSourceCmdArgs(ConfigSource):
    """Get configuration from command line arguments.
    """
    def __init__(self, argparser, args=None):
        super(ConfigSourceCmdArgs, self).__init__()
        self.args = argparser.parse_args(args)

    def get(self, variable):
        return getattr(self.args, variable.name, None)


class ConfigSourceEnvironment(ConfigSource):
    """Get configuration from environment variables.
    """
    def get(self, variable):
        if variable.envvar:
            return os.environ.get(variable.envvar, None)
        else:
            return None


class ConfigSourceFile(ConfigSource):
    """Get configuration from a configuration file.
    """
    def __init__(self, defaultFiles):
        super(ConfigSourceFile, self).__init__()
        self.confparser = ConfigParser.RawConfigParser()
        self.defaultFiles = defaultFiles
        self.section = None

    def read(self, filename):
        if filename:
            readfile = self.confparser.read(filename)
            if not readfile:
                raise ConfigError("Could not read config file '%s'." % filename)
        elif filename is None:
            readfile = self.confparser.read(self.defaultFiles)
        else:
            readfile = filename
        return readfile

    def setsection(self, section):
        if section and not self.confparser.has_section(section):
            raise ConfigError("Could not read config section '%s'." % section)
        self.section = section
        return section

    def get(self, variable):
        value = None
        if self.section:
            try:
                value = self.confparser.get(self.section, variable.name)
            except ConfigParser.NoOptionError:
                pass
        return value


class ConfigSourceDefault(ConfigSource):
    """Handle the case that some variable is not set from any other source.
    """
    def get(self, variable):
        value = variable.default
        if value is None and not variable.optional:
            raise ConfigError("Config option '%s' not given." % variable.name)
        return value


class Configuration(object):
    """Provide a name space to store the configuration.

    `Config.getconfig` returns a ``Configuration`` object having the
    configuration values stored in the respective attributes.
    """
    def __init__(self, config):
        super(Configuration, self).__init__()
        self._config = config

    def __str__(self):
        typename = type(self).__name__
        arg_strings = []
        vars = [var.name for var in self._config.confvariables] \
            + self._config.ReservedVariables
        for f in vars:
            if hasattr(self, f):
                arg_strings.append('%s=%r' % (f, getattr(self, f)))
        return '%s(%s)' % (typename, ', '.join(arg_strings))

    def as_dict(self):
        """Return the configuration as a dict."""
        vars = [var.name for var in self._config.confvariables] \
            + self._config.ReservedVariables
        return { f:getattr(self, f) for f in vars if hasattr(self, f) }


class Config(object):
    """Set configuration variables.

    Allow configuration variables to be set via command line
    arguments, environment variables, configuration files, and default
    values, in this order.  The first value found will be taken.
    Command line arguments and configuration files are read using the
    standard Python library modules ``argparse`` and ``ConfigParser``
    respectively, see the documentation of these modules for details
    on how to setup custom arguments or for the format of the
    configuration files.

    The following set of configuration variables that an ICAT client
    typically needs is predefined:

      ``configFile``
        Name of the configuration file to read.

        =========================  ==================================
        command line               ``-c``, ``--configfile``
        environment                ``ICAT_CFG``
        default                    ``~/.config/icat/icat.cfg``, 
                                   ``~/.icat/icat.cfg``, ``icat.cfg``
        mandatory                  no
        =========================  ==================================

      ``configSection``
        Name of the section in the configuration file to apply.  If
        not set, no values will be read from the configuration file.

        =========================  ==================================
        command line               ``-s``, ``--configsection``
        environment                ``ICAT_CFG_SECTION``
        default                    ``None``<commit_msg>Add /etc/icat/icat.cfg to the documentation of the list of default values for the configfile.<commit_after>"""Provide the Config class.
"""

import os
import os.path
import getpass
import argparse
import ConfigParser
from icat.exception import *

__all__ = ['Configuration', 'Config']


cfgdirs = [ "/etc/icat", 
            os.path.expanduser("~/.config/icat"), 
            os.path.expanduser("~/.icat"), "" ]
"""Search path for the configuration file"""
cfgfile = "icat.cfg"
"""Configuration file name"""
defaultsection = None


class ConfigVariable(object):
    """Describe a configuration variable.
    """
    def __init__(self, name, envvar, optional, default, subst):
        self.name = name
        self.envvar = envvar
        self.optional = optional
        self.default = default
        self.subst = subst


class ConfigSource(object):
    """A configuration source.

    This is the base class for all configuration sources, such as
    command line arguments, configuration files, and environment
    variables.
    """
    def get(self, variable):
        raise NotImplementedError


class ConfigSourceCmdArgs(ConfigSource):
    """Get configuration from command line arguments.
    """
    def __init__(self, argparser, args=None):
        super(ConfigSourceCmdArgs, self).__init__()
        self.args = argparser.parse_args(args)

    def get(self, variable):
        return getattr(self.args, variable.name, None)


class ConfigSourceEnvironment(ConfigSource):
    """Get configuration from environment variables.
    """
    def get(self, variable):
        if variable.envvar:
            return os.environ.get(variable.envvar, None)
        else:
            return None


class ConfigSourceFile(ConfigSource):
    """Get configuration from a configuration file.
    """
    def __init__(self, defaultFiles):
        super(ConfigSourceFile, self).__init__()
        self.confparser = ConfigParser.RawConfigParser()
        self.defaultFiles = defaultFiles
        self.section = None

    def read(self, filename):
        if filename:
            readfile = self.confparser.read(filename)
            if not readfile:
                raise ConfigError("Could not read config file '%s'." % filename)
        elif filename is None:
            readfile = self.confparser.read(self.defaultFiles)
        else:
            readfile = filename
        return readfile

    def setsection(self, section):
        if section and not self.confparser.has_section(section):
            raise ConfigError("Could not read config section '%s'." % section)
        self.section = section
        return section

    def get(self, variable):
        value = None
        if self.section:
            try:
                value = self.confparser.get(self.section, variable.name)
            except ConfigParser.NoOptionError:
                pass
        return value


class ConfigSourceDefault(ConfigSource):
    """Handle the case that some variable is not set from any other source.
    """
    def get(self, variable):
        value = variable.default
        if value is None and not variable.optional:
            raise ConfigError("Config option '%s' not given." % variable.name)
        return value


class Configuration(object):
    """Provide a name space to store the configuration.

    `Config.getconfig` returns a ``Configuration`` object having the
    configuration values stored in the respective attributes.
    """
    def __init__(self, config):
        super(Configuration, self).__init__()
        self._config = config

    def __str__(self):
        typename = type(self).__name__
        arg_strings = []
        vars = [var.name for var in self._config.confvariables] \
            + self._config.ReservedVariables
        for f in vars:
            if hasattr(self, f):
                arg_strings.append('%s=%r' % (f, getattr(self, f)))
        return '%s(%s)' % (typename, ', '.join(arg_strings))

    def as_dict(self):
        """Return the configuration as a dict."""
        vars = [var.name for var in self._config.confvariables] \
            + self._config.ReservedVariables
        return { f:getattr(self, f) for f in vars if hasattr(self, f) }


class Config(object):
    """Set configuration variables.

    Allow configuration variables to be set via command line
    arguments, environment variables, configuration files, and default
    values, in this order.  The first value found will be taken.
    Command line arguments and configuration files are read using the
    standard Python library modules ``argparse`` and ``ConfigParser``
    respectively, see the documentation of these modules for details
    on how to setup custom arguments or for the format of the
    configuration files.

    The following set of configuration variables that an ICAT client
    typically needs is predefined:

      ``configFile``
        Name of the configuration file to read.

        =========================  ==================================
        command line               ``-c``, ``--configfile``
        environment                ``ICAT_CFG``
        default                    ``/etc/icat/icat.cfg``, 
                                   ``~/.config/icat/icat.cfg``, 
                                   ``~/.icat/icat.cfg``, ``icat.cfg``
        mandatory                  no
        =========================  ==================================

      ``configSection``
        Name of the section in the configuration file to apply.  If
        not set, no values will be read from the configuration file.

        =========================  ==================================
        command line               ``-s``, ``--configsection``
        environment                ``ICAT_CFG_SECTION``
        default                    ``None``
{'fraction_non_alphanumeric': 0.12146596858638743, 'fraction_numerical': 0.0, 'mean_word_length': 2.3988730723606166, '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': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '601557', 'n_tokens_mistral': 2884, 'n_tokens_neox': 2781, 'n_words': 953}