''' --------------------------------------------- Class to parse Windoze-style ".INI" files. --------------------------------------------- Instance creates a dictionary object of the form: [section][option] = value Options appearing before any section header are stored in the default section named DefaultSect. Any lines unbound to options are appended to a list in [section][DefaultOpt] ? Lines starting with leading tabs immediately following ? an assignment are assumed to be continuation lines. ? ? Null lines, or lines beginning with ';' or #, ? are appended to a list in [section][Comments] examples: import ini conf = ini.init('/windows/win.ini') str_var = conf[section][key] conf[section][key] = value conf[section][key] = "{'ishtaar':5,'julio':21,'bart':0}" obj_var = eval(conf[section][key]) conf[section][key] = "foobar" 2004/12/11 modified to ignore lines starting with ; or #, ignore orphand lines. ini file is saved upon each call to 'set' by shula 2005/02/02 strings from either side can contain spaces or tabs! strip both sides of the = after read removed ALL stupid remarks and defaults!! be careful. --------------------------------------------- ''' import re, string, UserDict DEBUG=False def dbg(s): if DEBUG: print 'debug:',s # Special keys - leading space for sort to front global_flags = re.I + re.M + re.S class init(UserDict.UserDict): """ Invoke with name of .ini file """ _section = re.compile('^\[(.+)\]', global_flags) _option = re.compile('^([^=]+)=[ \t]*(.*)$', global_flags) def __init__(self, fn): self.filename = fn self.data = {} # Parse the .ini file try: s = open(fn).read() lines = s.splitlines() except: dbg( 'couldnt open '+f) lines = [] #opt = None for line in lines: line = line.strip() if line == '': #opt = None continue if line[0] == ';' or line[0] == '#': continue sect_match = self._section.match(line) if sect_match: sect = sect_match.group(1) if not self.data.has_key(sect): self.data[sect] = {} #opt = None continue opt_match = self._option.match(line) if opt_match: opt, val = opt_match.group(1, 2) opt = opt.strip() val = val.strip() self.data[sect][opt] = val continue def set(self, section, key, value): """ update or create 'key', set to 'value', in 'section'""" # See if name already exists in default section data = self.data for sect in (section): #, DefaultSect): if data.has_key(sect) and data[sect].has_key(key): section = sect break else: if not data.has_key(section): data[section] = {} data[section][key] = value self.write() def write(self): ''' Write the data back to the file. Called automatically on 'set()' ''' return f = open(self.filename, "w") sections = self.data.keys() sections.sort() for section in sections: #if section is not DefaultSect: f.write('\n[%s]\n' % section) data = self.data[section] names = data.keys() names.sort() for name in names: value = data[name] #if name in (Comments, DefaultOpt): #f.write('%s\n' % string.join(value, '\n')) #else: f.write('%s = %s\n' % (name, value)) f.close()