- get, set and write_config methods added for manipulation of pisi.conf file from Comar to solve bug #5668.
This commit is contained in:
+1
-1
@@ -17,7 +17,7 @@ __version__ = "1.1_20070305"
|
|||||||
__dbversion__ = "1.1_20070305"
|
__dbversion__ = "1.1_20070305"
|
||||||
__filesdbversion__ = "1.0.5" # yes, this is the real bottleneck
|
__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.
|
# FIXME: Exception shadows builtin Exception. This is no good.
|
||||||
class Exception(Exception):
|
class Exception(Exception):
|
||||||
|
|||||||
+137
-5
@@ -45,6 +45,8 @@
|
|||||||
#qt_dir = /usr/qt/3
|
#qt_dir = /usr/qt/3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
import StringIO
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
@@ -137,25 +139,155 @@ class ConfigurationSection(object):
|
|||||||
class ConfigurationFile(object):
|
class ConfigurationFile(object):
|
||||||
"""Parse and get configuration values from the configuration file"""
|
"""Parse and get configuration values from the configuration file"""
|
||||||
def __init__(self, filePath):
|
def __init__(self, filePath):
|
||||||
parser = ConfigParser.ConfigParser()
|
self.parser = ConfigParser.ConfigParser()
|
||||||
self.filePath = filePath
|
self.filePath = filePath
|
||||||
|
|
||||||
parser.read(self.filePath)
|
self.parser.read(self.filePath)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
generalitems = parser.items("general")
|
generalitems = self.parser.items("general")
|
||||||
except ConfigParser.NoSectionError:
|
except ConfigParser.NoSectionError:
|
||||||
generalitems = []
|
generalitems = []
|
||||||
self.general = ConfigurationSection("general", generalitems)
|
self.general = ConfigurationSection("general", generalitems)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
builditems = parser.items("build")
|
builditems = self.parser.items("build")
|
||||||
except ConfigParser.NoSectionError:
|
except ConfigParser.NoSectionError:
|
||||||
builditems = []
|
builditems = []
|
||||||
self.build = ConfigurationSection("build", builditems)
|
self.build = ConfigurationSection("build", builditems)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dirsitems = parser.items("directories")
|
dirsitems = self.parser.items("directories")
|
||||||
except ConfigParser.NoSectionError:
|
except ConfigParser.NoSectionError:
|
||||||
dirsitems = []
|
dirsitems = []
|
||||||
self.dirs = ConfigurationSection("directories", 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())
|
||||||
|
|||||||
Reference in New Issue
Block a user