#####################################################################
#####################################################################
# fluxspace.config - Fluxspace configuration management module
#####################################################################
#####################################################################

import os.path
import xml.dom.minidom

# Where to find fluxspace configuration files
defaultConfigPath = [os.path.expanduser('~/.fluxspace'),
                     os.path.expanduser('~/.fluxbox')]
defaultConfigFileName = 'fluxspace.xml'
tracer = None

class ConfigException(Exception):
    def __init__(self, message):
        self.message = message

class ConfigBadRoot(ConfigException):
    pass

class ConfigNoneFound(ConfigException):
    pass

class ConfigBadElement(ConfigException):
    pass

class ConfigFormatError(ConfigException):
    def __init__(self, message, xmlException):
        fullMessage = '%s\n\nXML Error: %s' % (message, str(xmlException))
        ConfigException.__init__(self, fullMessage)

def SetTracer(tracer_):
    global tracer
    tracer = tracer_

######################################################################
class Config:
######################################################################
    def __init__(self):
        global defaultConfigPath
        self.configPath = defaultConfigPath
        self.Reset()

    def Reset(self):
        self.configDOM     = None
        self.root          = None
        self.moduleNames   = []
        self.moduleConfigs = {}

    def Close(self):
        if self.configDOM is not None:
            self.configDOM.unlink()
            self.configDOM = None

    def ModuleConfig(self, name):
        if not self.moduleConfigs.has_key(name):
            return None
        return self.moduleConfigs[name]

    def Load(self, fileName = defaultConfigFileName):
        for configPathSegment in self.configPath:
            path = os.path.join(configPathSegment, fileName)
            if os.path.isfile(path):
                if tracer is not None:
                    tracer.Trace('Reading configuration "%s"...' % path)
                try:
                    self.configDOM = xml.dom.minidom.parse(path)
                except xml.parsers.expat.ExpatError, xmlError:
                    raise ConfigFormatError('Configuration file format error', xmlError )
                break

        if self.configDOM is None:
            raise ConfigNoneFound('No configuration loaded')

        self.root = self.configDOM.getElementsByTagName('fluxspace')
        if len(self.root) != 1:
            raise ConfigBadRoot('Bad or missing fluxspace root element')

        for module in self.root[0].childNodes:
            if not module.nodeType == module.ELEMENT_NODE:
                continue
            if module.getAttribute('enable') != 'yes':
                continue
            moduleName = module.tagName
            if moduleName not in self.moduleNames:
                self.moduleNames.append(moduleName)
            if not self.moduleConfigs.has_key(moduleName):
                self.moduleConfigs[moduleName] = module
            else:
                raise ConfigBadElement('more than one "%s" module' % moduleName, module)


syntax highlighted by Code2HTML, v. 0.9.1