1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
# coding: utf-8
"""Handle application configuration file."""
import os
import logging
import typing
import configparser
from mymeco import exceptions as exc
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
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
}
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
|