iro/config.py
author Sandro Knauß <knauss@netzguerilla.net>
Mon, 27 Feb 2012 22:26:10 +0100
branchdevel
changeset 194 0dad11389eec
parent 188 4d6130d91e56
child 220 602720314930
permissions -rw-r--r--
Refactoring tests.validate now use twisted.trial.unittests This allows to test the validate decorator.

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
        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))

    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._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 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 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")