Source code for configmodel.SerializerIni

# -*- coding: utf-8 -*-
import configparser
import os

from configmodel.Logger import Log
from configmodel.MixinCachedValues import MixinCachedValues
from configmodel.MixinDelayedWrite import MixinDelayedWrite
from configmodel.SerializerBase import SerializerBase


[docs] class SerializerIni(SerializerBase, MixinCachedValues, MixinDelayedWrite): DEFAULT_SECTION = "Global"
[docs] class ParameterLocation: def __init__(self): self.section = None self.parameter = None @property def full_name(self): return f"[{self.section}] {self.parameter}" def __repr__(self): return self.full_name
def __init__(self, filename): SerializerBase.__init__(self, filename) MixinCachedValues.__init__(self) MixinDelayedWrite.__init__(self, delayed_write_enabled=False) @staticmethod def _get_parameter_location(path): """ Get section and parameter name from path """ location = SerializerIni.ParameterLocation() if len(path) == 1: # place parameter in default section location.section = SerializerIni.DEFAULT_SECTION location.parameter = path[0] else: assert len(path) > 1 # place parameter in section location.section = path[0] location.parameter = ".".join(path[1:]) return location def _commit_delayed_write(self): """ Write cached values to INI file """ Log.debug(f"Writing cached values to INI file: {self.filename}") ini = configparser.ConfigParser() ini.read(self.filename) for full_name, cached_value in self._cached_values.items(): location = self._get_parameter_location(cached_value.path) if not ini.has_section(location.section): ini.add_section(location.section) do_write = False # write value if it is dirty if cached_value.is_dirty: do_write = True # also write value if it is not in INI file if not ini.has_option(location.section, location.parameter): do_write = True # write value if do_write: ini.set(location.section, location.parameter, str(cached_value.value)) with open(self.filename, "w") as config_file: ini.write(config_file) self._set_not_dirty()
[docs] def set_value(self, path, value): if not path: raise ValueError("Parameter path is empty. This is likely a bug in ConfigModel. Please report it.") # set cached value self.set_cached_value(path, value, is_dirty=True) # initiate delayed write self._restart_delayed_timer()
[docs] def get_value(self, path): if not path: raise ValueError("Parameter path is empty. This is likely a bug in ConfigModel. Please report it.") Log.debug(f"Getting value of field '{path}'") # get cached value cached_value = self.get_cached_value(path) return cached_value
[docs] def write_default_values_from_model(self, default_values): """ Write default values to configuration file, if they are not already set """ if not os.path.exists(self.filename): Log.debug(f"Creating new configuration file: {self.filename}") open(self.filename, "w").close() ini = configparser.ConfigParser() ini.read(self.filename) # read all values from INI file to cache cached_values = {} for section in ini.sections(): section_path = [] if section != SerializerIni.DEFAULT_SECTION: section_path = [section] for parameter in ini[section]: parameter_path = section_path + parameter.split(".") value = ini[section][parameter] full_name = self._path_to_str(parameter_path) cached_values[full_name] = self.CachedValue(parameter_path, value, False) # write default values, if not already set in INI file for field in default_values: location = self._get_parameter_location(field.path) if not ini.has_section(location.section): ini.add_section(location.section) if not ini.has_option(location.section, location.parameter): Log.debug(f"Writing default value of field '{field.path}' to '{field.value}', location: {location}") ini.set(location.section, location.parameter, str(field.value)) # add to cached values (if not already there) full_name = self._path_to_str(field.path) if full_name not in cached_values: cached_values[full_name] = self.CachedValue(field.path, field.value, False) # assign cached values self.assign_cached_values(cached_values) # write INI file with open(self.filename, "w") as config_file: ini.write(config_file)