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