Technical discussions | Discussions techniques
Subscription date : 28 October 2009
Messages : 415
|
Hi,
Well i wrote a script called HomeMadeConfigParser which is doing a better job than what the ConfigParser does. It's not complete yet, since i made it to fit my needs. Perhaps it can be improved for others to use since it is taylor-made for CD.
You get data with or without comments and set data with those comments, so that doesn't mess up the interface.
Usage is quite simple:
>>> import HomeMadeConfigParser
>>> parser=HomeMadeConfigParser.Parser()
>>> parser.read('./applet.conf')
>>> parser.iterate(section, with_comments=True, previous_lines=1)
>>> parser.get(section, key, type='str')
>>> parser.set(section, key, value, [comment1, comment2])
etc.
Hope it's useful. Code here, below.
Will post that on LP.
class Parser(object):
def __init__(self):
self.path = ''
self.conf = []
object.__init__(self)
def read(self, path_to_conf_file):
""" Reads configuration file into a list """
self.conf = []
self.path = path_to_conf_file
try:
self.conffile = open(self.path, 'r')
mold = self.conffile.readlines()
self.conffile.close()
for line in mold:
line = line.rstrip()
if len(line) > 0:
self.conf.append(line)
else:
continue
except:
print "HomeMadeConfigParser Error: an error occurred while handling", self.path
raise
def findSection(self, section):
""" Looks for a section and returns its index """
if len(self.conf) > 0:
section = '['+section+']'
i = iter(self.conf)
item = ''
index = -1
while item != section:
try:
item = i.next()
index += 1
except:
raise NoSectionError(section)
return index
else:
raise NoSectionError
def iterate(self, section, with_comment=False, previous_lines=1):
""" Returns a list of options in [key, value] lists
for the given section.
with_comment (bool) -- set to False by default. Returns
comments if set to True.
previous_lines (int) -- set to 1 by default. Represents index
of lines to return where 0 is the section
name. To return previous lines set value
to -n.
"""
if isinstance(section, str) \
and isinstance(with_comment, bool) \
and isinstance(previous_lines, int) \
and previous_lines < 2:
pass
else:
raise ArgError((section, with_comment, previous_lines))
option_list = []
index = self.findSection(section)
pre_index = 0
while previous_lines < 1:
pre_index = index + previous_lines
if pre_index > -1:
option_list.append(self.conf[pre_index])
else:
pass
previous_lines += 1
option = ' '
while option[0] != '[':
index += 1
try:
option = self.conf[index]
if with_comment == False and option[0] == '#':
continue
elif with_comment == True and option[0] == '#':
option_list.append(option)
else:
pair = option.split('=')
option_list.append(pair)
except:
return option_list
return option_list
def options(self, section):
""" Returns a list of options for a given section. """
pairs = self.iterate(section)
options = []
for pair in pairs:
options.append(pair[0])
return options
def sections(self):
""" Returns a list of sections. """
sections = []
for line in self.conf:
if line[0] == '[':
sections.append(line.strip('[').strip(']'))
else:
continue
return sections
def get(self, section, key, output_type='str'):
""" Returns the value of option based on given section and key. """
options = self.iterate(section)
i = iter(options)
item = ''
while item != key:
try:
pair = i.next()
item = pair[0]
except:
raise NoKeyError(key)
if len(pair[-1]) > 0:
if output_type == 'int':
try:
value = int(pair[-1])
except:
raise BadTypeError(output_type, pair[-1])
elif output_type == 'float':
try:
value = float(pair[-1])
except:
raise BadTypeError(output_type, pair[-1])
elif output_type == 'bool':
if str.lower(pair[-1]) in 'true' or str.lower(pair[-1]) in 'false':
value = str.lower(pair[-1]) in 'true'
else:
raise BadTypeError(output_type, pair[-1])
else:
value = str(pair[-1])
else:
value = pair[-1]
return value
def set(self, section, key, value='', comment=[]):
""" Sets new key-value pair to end of section,
optionally preceded by a comment. If no value is
specified, the key alone is added. If key exists
its value is replaced, otherwise it is appended
at the end of the section. Comment should be a list
each item of which is a comment line preceding the key.
"""
if isinstance(comment, list):
pass
else:
raise BadTypeError('list', comment)
if len(self.conf) > 0:
pass
else:
raise NoListError()
line = key+'='+value
index = self.findSection(section)
while True:
try:
index += 1
option = self.conf[index]
if option[0] == '[':
mode = 'i'
break
elif '=' in option:
pair = option.split('=')
if pair[0] == key:
mode = 'r'
break
else:
continue
else:
continue
except:
mode = 'a'
break
if len(comment) == 0:
if mode == 'i':
if self.conf[index-1][0:2] == '#[':
index = index-1
self.conf.insert(index, line)
elif mode == 'r':
self.conf[index] = line
else:
self.conf.append(line)
else:
if mode == 'i':
for item in comment:
self.conf.insert(index, item)
index += 1
self.conf.insert(index, line)
elif mode == 'r':
self.conf[index] = line
comment.reverse()
for item in comment:
self.conf.insert(index, item)
else:
for item in comment:
self.conf.append(item)
self.conf.append(line)
def write(self, path_to_file='', with_comments=True):
""" Writes the content of the configuration to a file.
It writes the file with comments by default, if any.
If no path is provided, it will use the path from read().
"""
if len(path_to_file) > 0:
self.path = path_to_file
elif len(self.path) > 2:
if len(self.conf) > 0:
try:
conffile = open(self.path, 'w')
for line in self.conf:
if with_comments == True and line[0] == '#':
conffile.write(line+'\n')
elif with_comments == False and line [0] == '#':
pass
elif not isinstance(with_comments, bool):
print self.ArgError
conffile.close()
print self.WriteError
return None
else:
conffile.write(line+'\n'+'\n')
conffile.close()
except:
print "HomeMadeConfigParser Error: an error occurred while handling", self.path
raise
else:
raise NoListError
else:
raise NoPathError
class NoSectionError(Exception):
def __init__(self, section):
self.value = "HomeMadeConfigParser found no section called "+section+"."
def __str__(self):
return repr(self.value)
class NoKeyError(Exception):
def __init__(self, key):
self.value = "HomeMadeConfigParser found no key called "+key+"."
def __str__(self):
return repr(self.key)
class NoListError(Exception):
def __init__(self):
self.value = "HomeMadeConfigParser found no configuration data to parse. " \
"Run Parser.read() to fetch data."
def __str__(self):
return repr(self.value)
class NoPathError(Exception):
def __init__(self):
self.value = "HomeMadeConfigParser needs a valid path to file to write data to."
def __str__(self):
return repr(self.value)
class ArgError(Exception):
def __init__(self, args):
self.value = "HomeMadeConfigParser received bad argument(s) in method: ", args
def __str__(self):
return repr(self.value)
class BadTypeError(Exception):
def __init__(self, expected, received):
self.value = "HomeMadeConfigParser: The value type did not match the expected type. " \
" Expected type was '"+expected+"', but received '"+str(received)+"'."
def __str__(self):
return repr(self.value)
|
matttbe, Sunday 15 May 2011 à 23:23
|
|
Subscription date : 24 January 2009
Messages : 12573
|
Thanks for sharing! |
Subscription date : 28 October 2009
Messages : 415
|
Ok, i ran across some new trouble:
for some reason CD keeps reloading the user conf file (/current_theme/plugins/...) from the conf file in the source (/third-party/...) each time CD starts up.
I thought CD should do so only if the source conf file's version was higher than the user conf file?
So now in my applet, mail account details are written to the user conf file (and i can see the changes happening in that file) but when i restart CD, the conf file is wiped clean and replaced with the source conf file. So mail accounts and user preferences are lost. I am writing to file through my own HomeMadeConfigParser script -- i don't know if that makes any difference.
Any idea what's happening?
B. |
Subscription date : 30 November 2007
Messages : 17118
|
the dock shouldn't rewrite the conf file, maybe the versions mismatch (the version on the top of the file, and the version of the applet in the auto-load.conf.
what gives the debug output of cairo-dock ?
anyway, to prevent custom keys from disappearing if ever the conf file is updated, put a 0 after the widget key
(for instance:)
but another possibility would be to store such info in another file, and let the user configure the accounts from a dialog window (or a simple gtk window). |
matttbe, Sunday 29 March 2015 à 14:22
|
|
Subscription date : 24 January 2009
Messages : 12573
|
(spams have been removed) |
Technical discussions | Discussions techniques
|