iro/config.py
author Sandro Knauß <knauss@netzguerilla.net>
Wed, 21 Mar 2012 17:36:05 +0100
branchdevel
changeset 237 eb3501d2cdc9
parent 228 944edbe51145
child 267 ef2df3f23cb1
permissions -rw-r--r--
update setup.py file and moving some scripts to subdirs

from twisted.python import log

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():
    log.msg("Reading configs.")
    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")