iro/config.py
author Sandro Knauß <knauss@netzguerilla.net>
Sun, 11 Mar 2012 16:37:49 +0100
branchdevel
changeset 224 072de50834f9
parent 220 602720314930
child 228 944edbe51145
permissions -rw-r--r--
adding init function that only loads main options

from ConfigParser import ConfigParser
import signal
from functools import partial

from validate import vInteger
from error import NeededOption 

class MyConfigParser(ConfigParser):
    def __init__(self):
        ConfigParser.__init__(self)
        self.reloadList=[]

    def read(self,files):
        from offer import getProvider
        r = ConfigParser.read(self, files)
        for s in self.sections():
            if s == "main":
                main.validate(self.items(s))
            else:
                getProvider("tmp", self.get(s,'typ'), self.items(s))
        return r

    def reload_(self):
        for f in self.reloadList:
            f()

    def registerReload(self, func):
        self.reloadList.append(func)

class Option():
    def __init__(self, validate, long="", help="", must=False, default=None):
        self.validate = validate
        self.long=long
        self.help = help
        self.must = must
        self.default = default

class Config:
    def __init__(self, name):
        self.name = name
        self.options={
            "port":Option(partial(vInteger,minv=0),long="Port under that twisted is running",must=True),
            "dburl":Option(lambda x,y:x,long="Connection URL to database",must=True),
        }
        self.order = ["dburl","port"]
        self._init = True


    def _read(self, cfg, write=False):
        c = dict(cfg)

        for o in self.options:
            option = self.options[o]
            try:
                value = option.validate(c[o],o)
                if write:
                    self._init = False
                    setattr(self,o,value)
            except KeyError:
                if option.must:
                    raise NeededOption(self.name, o)
                elif write and option.default is not None:
                    setattr(self, o, option.default)

    def validate(self, cfg):
        self._read(cfg, False)

    def load(self, cfg):
        self._read(cfg, True)

    def same(self, other):
        for o in self.options:
            if getattr(self,o) != getattr(other,o):
                return False
        else:
            return True

    def sampleConf(self):
        ret=[]
        for o in self.order:
            opt=self.options[o]
            if opt.long:
                ret.append("# "+opt.long)
            if opt.must:
                s= "%s = "%o
                if opt.default is not None:
                    s += str(opt.default)
                ret.append(s)
            else:
                ret.append("# %s = %s"%(o,opt.default))
            ret.append("")

        return ["[%s]"%self.name,]+ret

def readConfig():
    configParser.read(confFiles)
    configParser.reload_()
    if main._init:
        main.load(configParser.items("main"))
    else:
        m = Config("main")
        m.load(configParser.items("main"))
        if not main.same(m):
            raise Exception("Main options can't be reloaded, please restart your Application.")

def init():
    configParser.read(confFiles)
    main.load(configParser.items("main"))

def registerSignal():
    '''register readConfig to SIGUSR2'''
    def rC(signal, frame):
        readConfig()

    signal.signal(signal.SIGUSR2,rC)

configParser = MyConfigParser()
confFiles=["iro.conf", "~/iro.conf","/etc/iro/iro.conf"]

main = Config("main")