#!/usr/bin/env python #------------------------------------------------------------------------------- # FILE: myconfig.py # PURPOSE: Configuration file Abstraction # # AUTHOR: Jason G Yates # DATE: 22-May-2018 # # MODIFICATIONS: # # USAGE: This is the base class of used to abstract gauges and graphs, etc # LogError or FatalError should be used to log errors or fatal errors. # #------------------------------------------------------------------------------- import threading try: from ConfigParser import RawConfigParser except ImportError as e: from configparser import RawConfigParser from genmonlib.mycommon import MyCommon from genmonlib.program_defaults import ProgramDefaults class MyConfig (MyCommon): #---------------------MyConfig::__init__------------------------------------ def __init__(self, filename = None, section = None, simulation = False, log = None): super(MyConfig, self).__init__() self.log = log self.FileName = filename self.Section = section self.Simulation = simulation self.CriticalLock = threading.Lock() # Critical Lock (writing conf file) self.InitComplete = False try: self.config = RawConfigParser() self.config.read(self.FileName) if self.Section == None: SectionList = self.GetSections() if len(SectionList): self.Section = SectionList[0] except Exception as e1: self.LogErrorLine("Error in MyConfig:init: " + str(e1)) return self.InitComplete = True #---------------------MyConfig::HasOption----------------------------------- def HasOption(self, Entry): return self.config.has_option(self.Section, Entry) #---------------------MyConfig::GetList------------------------------------- def GetList(self): return self.config.items(self.Section) #---------------------MyConfig::GetSections--------------------------------- def GetSections(self): return self.config.sections() #---------------------MyConfig::SetSection---------------------------------- def SetSection(self, section): if self.Simulation: return True if not (isinstance(section, str) or isinstance(section, unicode)) or not len(section): self.LogError("Error in MyConfig:ReadValue: invalid section: " + str(section)) return False self.Section = section return True #---------------------MyConfig::ReadValue----------------------------------- def ReadValue(self, Entry, return_type = str, default = None, section = None, NoLog = False): try: if section != None: self.SetSection(section) if self.config.has_option(self.Section, Entry): if return_type == str: return self.config.get(self.Section, Entry) elif return_type == bool: return self.config.getboolean(self.Section, Entry) elif return_type == float: return self.config.getfloat(self.Section, Entry) elif return_type == int: return self.config.getint(self.Section, Entry) else: self.LogErrorLine("Error in MyConfig:ReadValue: invalid type:" + str(return_type)) return default else: return default except Exception as e1: if not NoLog: self.LogErrorLine("Error in MyConfig:ReadValue: " + Entry + ": " + str(e1)) return default #---------------------MyConfig::WriteSection-------------------------------- def WriteSection(self, SectionName): if self.Simulation: return True SectionList = self.GetSections() if SectionName in SectionList: self.LogError("Error in WriteSection: Section already exist.") return True try: with self.CriticalLock: with open(self.FileName, "a") as ConfigFile: ConfigFile.write("[" + SectionName + "]") ConfigFile.flush() ConfigFile.close() # update the read data that is cached self.config.read(self.FileName) return True except Exception as e1: self.LogErrorLine("Error in WriteSection: " + str(e1)) return False #---------------------MyConfig::WriteValue---------------------------------- def WriteValue(self, Entry, Value, remove = False, section = None): if self.Simulation: return if section != None: self.SetSection(section) SectionFound = False try: with self.CriticalLock: Found = False ConfigFile = open(self.FileName,'r') FileString = ConfigFile.read() ConfigFile.close() ConfigFile = open(self.FileName,'w') for line in FileString.splitlines(): if not line.isspace(): # blank lines newLine = line.strip() # strip leading spaces if len(newLine): if not newLine[0] == "#": # not a comment if not SectionFound and not self.LineIsSection(newLine): ConfigFile.write(line+"\n") continue if self.LineIsSection(newLine) and self.Section.lower() != self.GetSectionName(newLine).lower(): if SectionFound and not Found and not remove: # we reached the end of the section ConfigFile.write(Entry + " = " + Value + "\n") Found = True SectionFound = False ConfigFile.write(line+"\n") continue if self.LineIsSection(newLine) and self.Section.lower() == self.GetSectionName(newLine).lower(): SectionFound = True ConfigFile.write(line+"\n") continue if not SectionFound: ConfigFile.write(line+"\n") continue items = newLine.split('=') # split items in line by spaces if len(items) >= 2: items[0] = items[0].strip() if items[0] == Entry: if not remove: ConfigFile.write(Entry + " = " + Value + "\n") Found = True continue ConfigFile.write(line+"\n") # if this is a new entry, then write it to the file, unless we are removing it # this check is if there is not section below the one we are working in, # it will be added to the end of the file if not Found and not remove: ConfigFile.write(Entry + " = " + Value + "\n") ConfigFile.flush() ConfigFile.close() # update the read data that is cached self.config.read(self.FileName) return True except Exception as e1: self.LogError("Error in WriteValue: " + str(e1)) return False #---------------------MyConfig::GetSectionName------------------------------ def GetSectionName(self, Line): if self.Simulation: return "" Line = Line.strip() if Line.startswith("[") and Line.endswith("]") and len(Line) >=3 : Line = Line.replace("[", "") Line = Line.replace("]", "") return Line return "" #---------------------MyConfig::LineIsSection------------------------------- def LineIsSection(self, Line): if self.Simulation: return False Line = Line.strip() if Line.startswith("[") and Line.endswith("]") and len(Line) >=3 : return True return False