views:

59

answers:

1

Anyone know how'd I'd go about editing ini file values preferably using ConfigParser? (Or even a place to start from would be great!) I've got lots of comments throughout my config file so I'd like to keep them by just editing the values, not taking the values and playing around with multiple files.

Structure of my config file:

[name1]
URL = http://example.com
username = dog
password = password

[name2]
URL = http://catlover.com
username = cat
password = adffa

As you can see, I've got the same options for different section names, so editing just the values for one section is a bit trickier if ConfigParser can't do it.

Thanks in advance.

A: 

Here is an example

import sys
import os.path
from ConfigParser import RawConfigParser as ConfParser
from ConfigParser import Error

p = ConfParser()
# this happend to me save as ASCII
o = open("config.ini")
if o.read().startswith("\xef\xbb\xbf"):
    print "Fatal Error; Please save the file as ASCII not unicode."
    sys.exit()
try:
    results = p.read("config.ini")
except Error, msg:
    print "Error Parsing File"
    print msg
else:
    if results == []:
        print "Could not load config.ini."
        if not os.path.exists("config.ini"):
            print "config.ini does not exist."

        else:
            print "An uknown error occurred."

    else:
        print "Config Details"
        sections = p.sections()
        sections.sort()
        for s in sections:
            print "------------------------"
            print s
            if p.has_option(s, "URL"):
                print "URL: ",
                print p.get(s, "URL")

            else:
                print "URL: No Entry"

            if p.has_option(s, "username"):
                print "User: ",
                print p.get(s, "username")

            else:
                print "User: N/A"

            if p.has_option(s, "password"):
                print "Password: ",
                print p.get(s, "password")

            else:
                print "Password: N/A"

Also I created this class to store my apps variables etc and also make config writing easier it was originally used with twisted but I created a simple replacement logger

import os.path
import sys
#from twisted.python import log
import ConfigParser
from traceback import print_last
class Log(object):

    def msg(t):
        print "Logger: %s " % t

    def err(t = None):
        print "-------------Error-----------"
        print "\n\n"
        if t is None:
            print_last()
# sloppy replacement for twisted's logging functions
log = Log()            
class Settings(object):
    '''Stores settings'''
    config_variables = ['variables_that_should_be_stored_in_config']
    def __init__(self, main_folder = None, log_file = None, music_folder = None ):
        # load the defaults then see if there are updates ones in the config 
        self.load_defaults()
        self.config = ConfigParser.RawConfigParser()
        if len(self.config.read(self.settings_file)) == 1:
            if 'Settings' in self.config.sections():
                try:
                    self.music_folder = self.config.get('Settings', 'music_folder')
                except ConfigParser.NoOptionError:
                    pass
                log.msg('Music Folder: %s' % self.music_folder)
                try:
                    self.mplayer = self.config.get('Settings', 'mplayer')
                except ConfigParser.NoOptionError:
                    pass
                try:
                    self.eula = self.config.getboolean('Settings', 'eula')
                except ConfigParser.NoOptionError:
                    pass
            else:
                log.msg('No Settings Section; Defaults Loaded')
        else:
            log.msg('Settings at default')
    def load_defaults(self):
        log.msg('Loading Defaults')
        self.main_folder = os.path.dirname(os.path.abspath(sys.argv[0]))
        self.settings_file = os.path.join(self.main_folder, 'settings.cfg')
        self.log_file = os.path.join(self.main_folder, 'grooveshark.log')
        self.music_folder = os.path.join(self.main_folder, 'Music')
        self.grooveshark_started = False
        self.eula = False
        self.download_percent = 0.5# default buffer percent is 50 % 
        if sys.platform == 'win32' or sys.platform == 'cygwin':# Windows
            if os.path.exists( os.path.join(self.main_folder, 'mplayer', 'mplayer.exe') ):
                self.mplayer = os.path.join(self.main_folder, 'mplayer', 'mplayer.exe')
            elif os.path.exists( os.path.join(self.main_folder, '/mplayer.exe') ):
                self.mplayer = os.path.join(self.main_folder, '/mplayer.exe') 
            else:
                self.mplayer = 'download'

        elif sys.platform == 'darwin':# Mac
            if os.path.exists( os.path.join(self.main_folder, 'mplayer/mplayer.app') ):
                self.mplayer = os.path.join(self.main_folder, 'mplayer/mplayer.app')
            elif os.path.exists( os.path.join(self.main_folder, '/mplayer.app') ):
                self.mplayer = os.path.join(self.main_folder, '/mplayer.app') 
            else:
                self.mplayer = 'download'
        else:# linux
            # download or navigate to it
            self.mplayer = 'download'

        # Create Music Folder if it does not exist
        if not os.path.exists(self.music_folder):
            os.makedirs(self.music_folder)
        # Create log file if it does not exist
        if not os.path.exists(self.log_file):
            l = open(self.log_file, 'wb')
            l.close()

        log.msg('Application Folder: %s' % self.main_folder)
        log.msg('Log File: %s' % self.log_file)
        log.msg('Music Folder: %s' % self.music_folder)

    def __setattr__(self, variable, value):
        log.msg('Setting %s to %s' % (variable, value))
        object.__setattr__(self, variable, value)
        if variable in self.config_variables:
            try:
                self.config.set('Settings', variable, value)
            except:
                # Means config wasn't created then, could be we were trying to set self.config (in which case self.config wasn't set yet because we were trying to set it)
                log.err()
            else:
                # UPDATE settings file
                log.msg('Saving Settings to %s' % (self.settings_file))
                try:
                    self.config.write( open(self.settings_file, 'wb') )
                except:
                    log.err()
Zimm3r
From I can tell from your code, it won't really work for me. I've already gotten a lot of code working with the config file (reading and writing). But my issue is that I need to change a value for ie. the `URL` in the `[name2]` section. And I need it so that the section doesn't move anywhere. I'm trying to figure out how to do: `def editAcct(section, option, oldValue, newValue)` and have it change the chosen option in the section.
vlad003
Ya you use the set method instead of the get method (same syntax plus one more argument for the value) See: http://docs.python.org/library/configparser.html
Zimm3r
So I've taken another look at this problem and I realized that the `set` method doesn't work because I need to keep all the comments in there untouched. I ended up implementing my own way which finds the section name in the file (by line number) and the next section; then it finds the line with the value to change between the 2 section names; changes that; and rewrites the whole thing to the file. It's able to keep the comments which I need. Thanks for the answer anyways!
vlad003