Coverage for mymeco/config.py: 100%
46 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-12-11 22:07 +0000
« prev ^ index » next coverage.py v7.4.1, created at 2024-12-11 22:07 +0000
1# coding: utf-8
2"""Handle application configuration file."""
3import os
4import logging
5import typing
6import configparser
8from mymeco import exceptions as exc
11class Configuration():
12 """Handle configuration file."""
14 __log: logging.Logger = logging.getLogger()
15 __filelist: typing.Iterable[str] = [
16 os.path.join(os.environ.get('HOME', '/root'), '.mymeco'),
17 os.path.join(
18 os.environ.get(
19 'XDG_CONFIG_HOME',
20 os.path.join(os.environ.get('HOME', '/root'), '.config')
21 ),
22 'mymeco',
23 'config'
24 ),
25 os.path.join(
26 os.environ.get(
27 'XDG_CONFIG_DIRS',
28 os.path.join(os.sep, 'etc', 'xdg')
29 ),
30 'mymeco',
31 'config'
32 )
33 ]
35 __level_map: typing.Mapping[str, typing.Tuple[int, int]] = {
36 'critical': (0, 3),
37 'critic': (0, 3),
38 'error': (0, 2),
39 'warn': (0, 1),
40 'warning': (0, 1),
41 'info': (0, 0),
42 'debug': (1, 0)
43 }
45 def __init__(self,
46 configfile: typing.Optional[str] = None) -> None:
47 """
48 Read configuration file and store config keys.
50 :param configfile: Set configuration file to use a specific one. If
51 not defined, will try to autodetect a configuration file at the
52 following location:
53 - ``$HOME/.mymeco``
54 - ``$XDG_CONFIG_HOME/mymeco/config``
55 (or ``~/.config/mymeco/config``)
56 - ``$XDG_CONFIG_DIRS/mymeco/config``
57 (or ``/etc/xdg/mymeco/config``)
58 - ``$HOME/.config/mymeco/config``
59 """
60 if configfile is None:
61 # Detect config file
62 configfile = self.__autodetect()
63 elif not os.path.isfile(configfile):
64 configfile = None
66 if configfile is None:
67 self.__log.warning('No configuration file found')
68 raise exc.NoConfigurationFile()
70 self.__configfile = configfile
71 self.__config = configparser.ConfigParser()
72 self.__config.read(self.__configfile)
74 @property
75 def configfile(self) -> str:
76 """
77 Get configuration file found.
79 :return: Full path of found configuration file where data are
80 extracted.
81 """
82 return self.__configfile
84 def log(
85 self
86 ) -> typing.Mapping[str, typing.Union[int, bool]]:
87 """
88 Get logger configuration.
90 Read configuration file and extract right configuration for logger,
91 ready to be passed to ``mymeco.logger.configure`` function.
93 :return: Ready to use `kwargs` for ``mymeco.logger.configure`` method.
94 """
95 if self.__config.has_section('log'):
96 level = str(self.__config['log'].get('level')).lower()
97 try:
98 colored = self.__config['log'].getboolean('colored')
99 except ValueError:
100 colored = True
101 (verb, quiet) = self.__level_map.get(level, (0, 0))
102 else:
103 verb, quiet, colored = (0, 0, True)
104 return {
105 'verbosity_count': verb,
106 'quiet_count': quiet,
107 'colored': colored
108 }
110 def tmdb(
111 self
112 ) -> typing.Mapping[str, str]:
113 """
114 Get TMDb configuration.
116 Read configuration file and extract The Movie Database configuration.
118 :return: Configuration map to access TMDb service. Output contains at
119 least the following keys:
120 * `token`: access token
122 :raises: ``MissingConfiguration`` exception is raised when
123 configuration entry is missing.
124 """
125 if not self.__config.has_section('tmdb'):
126 raise exc.MissingConfiguration('tmdb', None, self.configfile)
128 token: typing.Union[None, str] = self.__config['tmdb'].get(
129 'token', None
130 )
131 if token is None:
132 raise exc.MissingConfiguration('tmdb', 'token', self.configfile)
134 return {
135 'token': token
136 }
138 def __autodetect(self) -> typing.Union[str, None]:
139 for config in self.__filelist:
140 if os.path.isfile(config):
141 return config
142 return None