iro/config.py
branchdevel
changeset 186 b381eaa774ab
parent 184 6b0ff82dff81
child 187 352527f2b6ca
--- a/iro/config.py	Thu Feb 23 16:59:49 2012 +0100
+++ b/iro/config.py	Sat Feb 25 16:12:07 2012 +0100
@@ -1,11 +1,11 @@
-from ConfigParser import ConfigParser, NoOptionError
+from ConfigParser import ConfigParser
 import signal
 from functools import partial
 
 from validate import vInteger
-from error import ValidateException
+from error import NeededOption 
 
-class Config(ConfigParser):
+class MyConfigParser(ConfigParser):
     def __init__(self):
         ConfigParser.__init__(self)
         self.reloadList=[]
@@ -15,16 +15,9 @@
         ConfigParser.read(self, files)
         for s in self.sections():
             if s == "main":
-                opts=main
-                for o in opts:
-                    try:
-                        opts[o].validate(self.get(s,o),o)
-                    except (ValidateException, NoOptionError):
-                        if opts[o].must:
-                            raise
+                main.validate(self.items(s))
             else:
                 getProvider("tmp", self.get(s,'typ'), self.items(s))
-           
 
     def reload_(self):
         for f in self.reloadList:
@@ -41,9 +34,54 @@
         self.must = must
         self.default = default
 
+class Config():
+    def __init__(self, name):
+        self.name = name
+        self.options={
+            "hostname":Option(lambda x,y:x,long="Hostname under that twisted is running",must=True),
+            "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.read=False
+
+
+    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.read = True
+                    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():
-    config.read(confFiles)
-    config.reload()
+    configParser.read(confFiles)
+    configParser.reload()
+    if not main.read:
+        main.load(configParser.items("main"))
+    else:
+        m = Config("main").load(configParser.items("main"))
+        if not main.same(m):
+            raise Exception("Main options can't be reloaded, you have to restart.")
 
 def registerSignal():
     '''register readConfig to SIGUSR2'''
@@ -52,8 +90,7 @@
 
     signal.signal(signal.SIGUSR2,rC)
 
-config=Config()
+configParser = MyConfigParser()
 confFiles=["iro.conf", "~/iro.conf","/etc/iro/iro.conf"]
-main={"hostname":Option(lambda x,y:x,long="Hostname under that twisted is running",must=True),
-        "port":Option(partial(vInteger,minv=0),long="Port under that twisted is running",must=True),
-        }
+
+main = Config("main")