# coding: utf-8
"""Handle application configuration file."""
import os
import logging
import typing
import configparser
from mymeco import exceptions as exc
[docs]
class Configuration():
"""Handle configuration file."""
__log: logging.Logger = logging.getLogger()
__filelist: typing.Iterable[str] = [
os.path.join(os.environ.get('HOME', '/root'), '.mymeco'),
os.path.join(
os.environ.get(
'XDG_CONFIG_HOME',
os.path.join(os.environ.get('HOME', '/root'), '.config')
),
'mymeco',
'config'
),
os.path.join(
os.environ.get(
'XDG_CONFIG_DIRS',
os.path.join(os.sep, 'etc', 'xdg')
),
'mymeco',
'config'
)
]
__level_map: typing.Mapping[str, typing.Tuple[int, int]] = {
'critical': (0, 3),
'critic': (0, 3),
'error': (0, 2),
'warn': (0, 1),
'warning': (0, 1),
'info': (0, 0),
'debug': (1, 0)
}
def __init__(self,
configfile: typing.Optional[str] = None) -> None:
"""
Read configuration file and store config keys.
:param configfile: Set configuration file to use a specific one. If
not defined, will try to autodetect a configuration file at the
following location:
- ``$HOME/.mymeco``
- ``$XDG_CONFIG_HOME/mymeco/config``
(or ``~/.config/mymeco/config``)
- ``$XDG_CONFIG_DIRS/mymeco/config``
(or ``/etc/xdg/mymeco/config``)
- ``$HOME/.config/mymeco/config``
"""
if configfile is None:
# Detect config file
configfile = self.__autodetect()
elif not os.path.isfile(configfile):
configfile = None
if configfile is None:
self.__log.warning('No configuration file found')
raise exc.NoConfigurationFile()
self.__configfile = configfile
self.__config = configparser.ConfigParser()
self.__config.read(self.__configfile)
@property
def configfile(self) -> str:
"""
Get configuration file found.
:return: Full path of found configuration file where data are
extracted.
"""
return self.__configfile
[docs]
def log(
self
) -> typing.Mapping[str, typing.Union[int, bool]]:
"""
Get logger configuration.
Read configuration file and extract right configuration for logger,
ready to be passed to ``mymeco.logger.configure`` function.
:return: Ready to use `kwargs` for ``mymeco.logger.configure`` method.
"""
if self.__config.has_section('log'):
level = str(self.__config['log'].get('level')).lower()
try:
colored = self.__config['log'].getboolean('colored')
except ValueError:
colored = True
(verb, quiet) = self.__level_map.get(level, (0, 0))
else:
verb, quiet, colored = (0, 0, True)
return {
'verbosity_count': verb,
'quiet_count': quiet,
'colored': colored
}
[docs]
def tmdb(
self
) -> typing.Mapping[str, str]:
"""
Get TMDb configuration.
Read configuration file and extract The Movie Database configuration.
:return: Configuration map to access TMDb service. Output contains at
least the following keys:
* `token`: access token
:raises: ``MissingConfiguration`` exception is raised when
configuration entry is missing.
"""
if not self.__config.has_section('tmdb'):
raise exc.MissingConfiguration('tmdb', None, self.configfile)
token: typing.Union[None, str] = self.__config['tmdb'].get(
'token', None
)
if token is None:
raise exc.MissingConfiguration('tmdb', 'token', self.configfile)
return {
'token': token
}
def __autodetect(self) -> typing.Union[str, None]:
for config in self.__filelist:
if os.path.isfile(config):
return config
return None