- get, set and write_config methods added for manipulation of pisi.conf file from Comar to solve bug #5668.

This commit is contained in:
Faik Uygur
2007-05-22 08:22:31 +00:00
parent 2e501464fc
commit ed21fdc80e
2 changed files with 138 additions and 6 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ __version__ = "1.1_20070305"
__dbversion__ = "1.1_20070305"
__filesdbversion__ = "1.0.5" # yes, this is the real bottleneck
__all__ = [ 'api', 'config', 'packagedb', 'installdb', 'search' ]
__all__ = [ 'api', 'config', 'configfile', 'packagedb', 'installdb', 'search' ]
# FIXME: Exception shadows builtin Exception. This is no good.
class Exception(Exception):
+137 -5
View File
@@ -45,6 +45,8 @@
#qt_dir = /usr/qt/3
import os
import re
import StringIO
import ConfigParser
import gettext
@@ -137,25 +139,155 @@ class ConfigurationSection(object):
class ConfigurationFile(object):
"""Parse and get configuration values from the configuration file"""
def __init__(self, filePath):
parser = ConfigParser.ConfigParser()
self.parser = ConfigParser.ConfigParser()
self.filePath = filePath
parser.read(self.filePath)
self.parser.read(self.filePath)
try:
generalitems = parser.items("general")
generalitems = self.parser.items("general")
except ConfigParser.NoSectionError:
generalitems = []
self.general = ConfigurationSection("general", generalitems)
try:
builditems = parser.items("build")
builditems = self.parser.items("build")
except ConfigParser.NoSectionError:
builditems = []
self.build = ConfigurationSection("build", builditems)
try:
dirsitems = parser.items("directories")
dirsitems = self.parser.items("directories")
except ConfigParser.NoSectionError:
dirsitems = []
self.dirs = ConfigurationSection("directories", dirsitems)
# get, set and write_config methods added for manipulation of pisi.conf file from Comar to solve bug #5668.
# Current ConfigParser does not keep the comments and white spaces, which we do not want for pisi.conf. There
# are patches floating in the python sourceforge to add this feature. The write_config code is from python
# sourceforge tracker id: #1410680, modified a little to make it turn into a function.
def get(self, section, option):
return self.parser.get(section, option)
def set(self, section, option, value):
self.parser.set(section, option, value)
def write_config(self, add_missing=True):
sections = {}
current = StringIO.StringIO()
replacement = [current]
sect = None
opt = None
written = []
optcre = re.compile(
r'(?P<option>[^:=\s][^:=]*)'
r'(?P<vi>[:=])'
r'(?P<padding>\s*)'
r'(?P<value>.*)$'
)
fp = open(self.filePath, "r+")
# Default to " = " to match write(), but use the most recent
# separator found if the file has any options.
padded_vi = " = "
while True:
line = fp.readline()
if not line:
break
# Comment or blank line?
if line.strip() == '' or line[0] in '#;' or \
(line.split(None, 1)[0].lower() == 'rem' and \
line[0] in "rR"):
current.write(line)
continue
# Continuation line?
if line[0].isspace() and sect is not None and opt:
if ';' in line:
# ';' is a comment delimiter only if it follows
# a spacing character
pos = line.find(';')
if line[pos-1].isspace():
comment = line[pos-1:]
# Get rid of the newline, and put in the comment.
current.seek(-1, 1)
current.write(comment + "\n")
continue
# A section header or option header?
else:
# Is it a section header?
mo = self.parser.SECTCRE.match(line)
if mo:
# Remember the most recent section with this name,
# so that any missing options can be added to it.
if sect:
sections[sect] = current
sect = mo.group('header')
current = StringIO.StringIO()
replacement.append(current)
sects = self.parser.sections()
sects.append(ConfigParser.DEFAULTSECT)
if sect in sects:
current.write(line)
# So sections can't start with a continuation line:
opt = None
# An option line?
else:
mo = optcre.match(line)
if mo:
padded_opt, vi, value = mo.group('option', 'vi',
'value')
padded_vi = ''.join(mo.group('vi', 'padding'))
comment = ""
if vi in ('=', ':') and ';' in value:
# ';' is a comment delimiter only if it follows
# a spacing character
pos = value.find(';')
if value[pos-1].isspace():
comment = value[pos-1:]
# Keep track of what we rstrip to preserve formatting
opt = padded_opt.rstrip().lower()
padded_vi = padded_opt[len(opt):] + padded_vi
if self.parser.has_option(sect, opt):
value = self.parser.get(sect, opt)
# Fix continuations.
value = value.replace("\n", "\n\t")
current.write("%s%s%s%s\n" % (opt, padded_vi,
value, comment))
written.append((sect, opt))
if sect:
sections[sect] = current
if add_missing:
# Add any new sections.
sects = self.parser.sections()
if len(self.parser._defaults) > 0:
sects.append(ConfigParser.DEFAULTSECT)
sects.sort()
for sect in sects:
if sect == ConfigParser.DEFAULTSECT:
opts = self.parser._defaults.keys()
else:
# Must use _section here to avoid defaults.
opts = self.parser._sections[sect].keys()
opts.sort()
if sect in sections:
output = sections[sect] or current
else:
output = current
if len(written) > 0:
output.write("\n")
output.write("[%s]\n" % (sect,))
sections[sect] = None
for opt in opts:
if opt != "__name__" and not (sect, opt) in written:
value = self.parser.get(sect, opt)
# Fix continuations.
value = value.replace("\n", "\n\t")
output.write("%s%s%s\n" % (opt, padded_vi, value))
written.append((sect, opt))
# Copy across the new file.
fp.seek(0)
fp.truncate()
for sect in replacement:
if sect is not None:
fp.write(sect.getvalue())