-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConfiguration.py
150 lines (140 loc) · 5.88 KB
/
Configuration.py
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
143
144
145
146
147
148
149
150
'''
Created on 28.07.2022
@author: wk
'''
import re
import os.path
import datetime
from Snippets import Snippets
from SilentLog import SilentLog
class Configuration (SilentLog):
'''Manages translated texts.
'''
rexprMacro = re.compile(r'~\{([a-zA-Z0-9.-]+)\}')
rexprVariable = re.compile(r'^([a-zA-Z0-9.-]+)\s*=\s*(.*)')
def __init__(self, filename: str=None):
'''Constructor.
@param filename: None of the name of the configuration file
'''
SilentLog.__init__(self)
self._filename = filename
self.errors = []
self._variables = {}
if filename is not None:
self.read(filename)
self.silentLogConfiguration(self._variables)
def asBool(self, key, defaultValue: bool=None) -> bool:
'''Returns the value of a configuration variable given by its key as a boolean.
@param key: the key of the variable
@param defaultValue: if the variable does not exist
or the value is not a boolean this value will be returned
@return the value of the variable with the given key or the defaultValue on error
'''
value = self.asString(key) if self.hasKey(key) else None
if value is None:
rc = defaultValue
else:
value = value.lower()
if value in ('true', 't', 'yes', 'y'):
rc = True
elif value in ('false', 'f', 'no', 'n'):
rc = False
else:
self.error(
f'{key} is not a boolean value[true, yes, false, no]: {value}')
rc = defaultValue
return rc
def asDate(self, key, defaultValue: datetime.date=None) -> datetime.date:
'''Returns the value of a configuration variable given by its key as a date.
@param key: the key of the variable
@param defaultValue: if the variable does not exist
or the value is not a date this value will be returned
@return the value of the variable with the given key or the defaultValue on error
'''
rc = defaultValue
value = self.asString(key) if self.hasKey(key) else None
if value is not None:
separator = '.' if value.find('.') > 0 else '-'
parts = value.split(separator)
if len(parts) != 3:
self.error(f'not a date (yyyy-mm-dd or dd.mm.yyyy): {value}')
else:
try:
if len(parts[0]) == 4:
rc = datetime.date(
int(parts[0]), int(parts[1]), int(parts[2]))
elif len(parts[2]) == 4:
rc = datetime.date(
int(parts[2]), int(parts[1]), int(parts[0]))
else:
self.error(
f'wrong date ((yyyy-mm-dd or dd.mm.yyyy): {value}')
if rc is None:
self.error(
f'wrong date ((yyyy-mm-dd or dd.mm.yyyy): {value}')
rc = defaultValue
except ValueError:
self.error(
f'wrong date ((yyyy-mm-dd or dd.mm.yyyy): {value}')
rc = defaultValue
return rc
def asInt(self, key, defaultValue: int=-1) -> int:
'''Returns the value of a configuration variable given by its key as an integer.
@param key: the key of the variable
@param defaultValue: if the variable does not exist
or the value is not an integer this value will be returned
@return the value of the variable with the given key or the defaultValue on error
'''
value = self.asString(key) if self.hasKey(key) else None
if value is None:
rc = defaultValue
else:
try:
rc = int(value)
except ValueError:
rc = defaultValue
return rc
def asString(self, key: str, defaultValue: str=None) -> str:
'''Returns the value of a configuration variable given by its key.
@param key: the key of the variable
@return: if the variable does not exist: defaultValue or (if that does not exist) the key
otherwise: the value of the variable
'''
rc = self._variables[key] if key in self._variables else (
key if defaultValue is None else defaultValue)
return rc
def hasKey(self, key):
'''Tests whether there is a given key.
@param key: the key to test
@return True: the key exists
'''
return key in self._variables
def read(self, filename: str):
'''Reads the configuration from a file.
@param filename: the name of the file
'''
if not os.path.exists(filename):
self.error(f'missing {filename}')
else:
with open(filename, 'r') as fp:
lineNo = 0
count = 0
for line in fp:
lineNo += 1
if line.startswith('#') or line.strip() == '':
continue
matcher = Configuration.rexprVariable.match(line)
if matcher is None:
self.error(
f'{filename}-{lineNo}: illegal input: {line}')
else:
count += 1
name = matcher.group(1)
value = matcher.group(2)
if name in self._variables:
self.error(
f'{filename}-{lineNo}: key is already defined: {name}')
else:
self._variables[name] = Snippets.replace(
value, self._variables, Configuration.rexprMacro)
self.log(f'{filename} contains {count} variable(s)')