iro/config.py
author Sandro Knauß <knauss@netzguerilla.net>
Mon, 05 Mar 2012 23:51:56 +0100
branchdevel
changeset 217 d755b2e0cc0b
parent 188 4d6130d91e56
child 220 602720314930
permissions -rw-r--r--
task now saves own status

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