2022-09-20 09:34:28 +00:00
|
|
|
import configparser
|
|
|
|
import structlog
|
2023-11-06 18:04:35 +00:00
|
|
|
import json
|
2022-09-20 09:34:28 +00:00
|
|
|
|
|
|
|
class CONFIG:
|
|
|
|
"""
|
|
|
|
CONFIG class for handling with config files
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
2022-12-10 12:34:26 +00:00
|
|
|
def __init__(self, configfile: str):
|
2022-09-20 09:34:28 +00:00
|
|
|
# set up logger
|
|
|
|
self.log = structlog.get_logger("CONFIG")
|
|
|
|
|
|
|
|
# init configparser
|
|
|
|
self.config = configparser.ConfigParser(inline_comment_prefixes="#", allow_no_value=True)
|
2022-12-10 12:34:26 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
self.config_name = configfile
|
|
|
|
|
|
|
|
except Exception:
|
|
|
|
self.config_name = "config.ini"
|
2022-09-20 09:34:28 +00:00
|
|
|
|
|
|
|
self.log.info("[CFG] logfile init", file=self.config_name)
|
|
|
|
|
|
|
|
# check if log file exists
|
|
|
|
self.config_exists()
|
|
|
|
|
|
|
|
def config_exists(self):
|
|
|
|
"""
|
|
|
|
check if config file exists
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
return bool(self.config.read(self.config_name, None))
|
|
|
|
except Exception as configerror:
|
|
|
|
self.log.error("[CFG] logfile init error", e=configerror)
|
|
|
|
return False
|
|
|
|
|
|
|
|
def write_config(self, section: str, key: str, value):
|
|
|
|
"""
|
|
|
|
write values to config
|
|
|
|
"""
|
|
|
|
|
2023-11-06 10:30:37 +00:00
|
|
|
# Validates config data
|
|
|
|
def validate(self, data):
|
|
|
|
for section in data:
|
|
|
|
for setting in data[section]:
|
|
|
|
if section == 'NETWORK':
|
|
|
|
if setting == 'modemport' and int(data[section][setting]) == 0:
|
|
|
|
raise Exception("'modemport' should be an integer")
|
|
|
|
if section == 'STATION':
|
|
|
|
if setting == 'mycall' and len(data[section][setting]) <= 0:
|
|
|
|
raise Exception("'%s' can't be empty" % setting)
|
|
|
|
if setting == 'mygrid' and len(data[section][setting]) <= 0:
|
|
|
|
raise Exception("'%s' can't be empty" % setting)
|
|
|
|
if setting == 'ssid_list' and not isinstance(data[section][setting], list):
|
|
|
|
raise Exception("'%s' needs to be a list" % setting)
|
|
|
|
# TODO finish this for all config settings!
|
|
|
|
|
2023-11-06 18:04:35 +00:00
|
|
|
# Handle special setting data type conversion
|
|
|
|
# is_writing means data from a dict being writen to the config file
|
|
|
|
# if False, it means the opposite direction
|
|
|
|
def handle_setting(self, section, setting, value, is_writing = False):
|
|
|
|
if (section == 'STATION' and setting == 'ssid_list'):
|
|
|
|
if (is_writing):
|
|
|
|
return json.dumps(value)
|
|
|
|
else:
|
|
|
|
return json.loads(value)
|
|
|
|
else:
|
|
|
|
return value
|
|
|
|
|
2023-11-06 10:30:37 +00:00
|
|
|
# Sets and writes config data from a dict containing data settings
|
|
|
|
def write(self, data):
|
|
|
|
|
|
|
|
# Validate config data before writing
|
|
|
|
self.validate(data)
|
|
|
|
|
|
|
|
for section in data:
|
|
|
|
# init section if it doesn't exist yet
|
|
|
|
if not section.upper() in self.config.keys():
|
|
|
|
self.config[section] = {}
|
|
|
|
|
|
|
|
for setting in data[section]:
|
2023-11-06 19:52:33 +00:00
|
|
|
new_value = self.handle_setting(
|
2023-11-06 18:04:35 +00:00
|
|
|
section, setting, data[section][setting], True)
|
2023-11-06 19:52:33 +00:00
|
|
|
self.config[section][setting] = str(new_value)
|
2023-11-06 10:30:37 +00:00
|
|
|
|
|
|
|
# Write config data to file
|
|
|
|
try:
|
|
|
|
with open(self.config_name, 'w') as configfile:
|
|
|
|
self.config.write(configfile)
|
2023-11-06 18:04:35 +00:00
|
|
|
return self.read()
|
2023-11-06 10:30:37 +00:00
|
|
|
except Exception as conferror:
|
|
|
|
self.log.error("[CFG] reading logfile", e=conferror)
|
|
|
|
return False
|
|
|
|
|
2023-11-06 14:36:11 +00:00
|
|
|
def read(self):
|
2022-09-20 09:34:28 +00:00
|
|
|
"""
|
|
|
|
read config file
|
|
|
|
"""
|
2023-11-06 14:36:11 +00:00
|
|
|
if not self.config_exists():
|
|
|
|
return False
|
2023-11-06 18:04:35 +00:00
|
|
|
|
|
|
|
# at first just copy the config as read from file
|
|
|
|
result = {s:dict(self.config.items(s)) for s in self.config.sections()}
|
|
|
|
|
|
|
|
# handle the special settings (like 'ssid_list')
|
|
|
|
for section in result:
|
|
|
|
for setting in result[section]:
|
|
|
|
result[section][setting] = self.handle_setting(
|
|
|
|
section, setting, result[section][setting], False)
|
2022-09-20 09:34:28 +00:00
|
|
|
|
2023-11-06 18:04:35 +00:00
|
|
|
return result
|
2022-09-20 09:34:28 +00:00
|
|
|
|
2023-02-18 13:18:39 +00:00
|
|
|
def get(self, area, key, default):
|
|
|
|
"""
|
|
|
|
read from config and add if not exists
|
|
|
|
|
|
|
|
"""
|
2023-02-18 13:51:26 +00:00
|
|
|
|
2023-02-18 18:57:04 +00:00
|
|
|
for _ in range(2):
|
2023-02-18 14:01:26 +00:00
|
|
|
try:
|
2023-02-18 18:57:04 +00:00
|
|
|
parameter = (
|
|
|
|
self.config[area][key] in ["True", "true", True]
|
|
|
|
if default in ["True", "true", True, "False", "false", False]
|
|
|
|
else self.config[area][key]
|
|
|
|
)
|
2023-02-18 14:01:26 +00:00
|
|
|
except KeyError:
|
|
|
|
self.config[area][key] = str(default)
|
2023-02-18 13:51:26 +00:00
|
|
|
|
|
|
|
self.log.info("[CFG] reading...", parameter=parameter, key=key)
|
|
|
|
return parameter
|