iro.config: using OrderedDict instead of Dict + List for Options. devel
authorSandro Knauß <knauss@netzguerilla.net>
Fri, 30 Mar 2012 15:55:44 +0200
branchdevel
changeset 269 0d134b173cb1
parent 268 d0fcb1cde990
child 270 665c3ea02d35
iro.config: using OrderedDict instead of Dict + List for Options.
iro/config.py
iro/offer/provider.py
iro/offer/smstrade.py
iro/offer/smtp.py
iro/tests/config.py
--- a/iro/config.py	Fri Mar 30 11:49:13 2012 +0200
+++ b/iro/config.py	Fri Mar 30 15:55:44 2012 +0200
@@ -3,6 +3,7 @@
 from ConfigParser import ConfigParser
 import signal
 from functools import partial
+from collections import OrderedDict
 
 from validate import vInteger
 from error import NeededOption 
@@ -60,29 +61,26 @@
     
     If one option is valid, the attribute is created with the value of the validate function.
     """
-    def __init__(self, name):
+    def __init__(self, name, options=None):
         """
         :param string name: section name.
+        :param `collections.OrderedDict` options: Orderd Dict of the configuration options (see :attr:`options`) 
         """
         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),
-        }
-        """Options dict for Options used in configuration file (see :class:`iro.config.Option`). Ordering of configuration fields are done by :attr:`order`. 
+        
+        self.options = options
+        """Options :class:`collections.OrderedDict` for Options used in configuration file (see :class:`iro.config.Option`). Ordering of configuration fields are done by :attr:`order`. 
         
         Sample::
         
-               {"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)
-               }
+            OrderedDict([
+                ("dburl",Option(lambda x,y:x,long="Connection URL to database",must=True)),
+                ("port",Option(partial(vInteger,minv=0),long="Port under that twisted is running",must=True)),
+            ])
         
         A child class typically use update to add more options.
         """
-
-        self.order = ["dburl","port"]
-        """ A list for ordering the options dict (:attr:`options`). """
-
+        
         self._init = True
         """indecates, if the config is loaded with config values."""
 
@@ -140,7 +138,7 @@
         :return: a list of lines
         """
         ret=[]
-        for o in self.order:
+        for o in self.options:
             opt=self.options[o]
             if opt.long:
                 ret.append("# "+opt.long)
@@ -163,7 +161,7 @@
     if main._init:
         main.load(configParser.items("main"))
     else:
-        m = Config("main")
+        m = Config("main", main_options)
         m.load(configParser.items("main"))
         if not main.same(m):
             raise Exception("Main options can't be reloaded, please restart your Application.")
@@ -186,5 +184,12 @@
 confFiles=["iro.conf", "~/iro.conf","/etc/iro/iro.conf"]
 """Configfile list """
 
-main = Config("main")
+main_options = OrderedDict([
+    ("dburl",Option(lambda x,y:x,long="Connection URL to database",must=True)),
+    ("port",Option(partial(vInteger,minv=0),long="Port under that twisted is running",must=True)),
+    ])
+
+"options for main section"
+
+main = Config("main", main_options)
 """Main config options"""
--- a/iro/offer/provider.py	Fri Mar 30 11:49:13 2012 +0200
+++ b/iro/offer/provider.py	Fri Mar 30 15:55:44 2012 +0200
@@ -1,4 +1,5 @@
 from functools import partial
+from collections import OrderedDict
 
 from ..error import NoRoute, NoTyp, ValidateException, NoProvider
 from ..config import Option, Config
@@ -9,34 +10,23 @@
     testmode = False
     """- **True** -- no message to external provider should be send.
     - **False** (default) -- message are send to external provider."""
-    def __init__(self, name, typs={}):
+    def __init__(self, name, typs={}, options=[]):
         """Constructor for Provider class.
         
         :param string name: Name of the Provider.
         :param dict typs: A Dictonary with typs and routes.
+        :param items options: [("name",Option(...)),...]
 
         >>> p = Provider("myProvider",{"sms":["route1","route2"]})
         """
 
-        Config.__init__(self, name)
+        Config.__init__(self, name, OrderedDict([
+                    ("typ",Option(vProvider, long="One available provider typ.", must=True, default=name))
+                    ]+options)
+                )
         self.typs=typs
         self.testmode = False
 
-        self.options = {
-                "typ":Option(vProvider, long="One available provider typ.", must=True, default=name)
-                }
-        """Options dict for Options used in configuration file (see :class:`iro.config.Option`). Ordering of configuration fields are done by :attr:`order`. 
-        
-        Sample::
-        
-               {"typ":Option(vProvider, long="One available provider typ.", must=True, default="default")}
-        
-        A child class typically use update to add more options (see code of :class:`iro.offer.smtp.SMTP`).
-        """
-
-        self.order = ["typ"]
-        """ A list for ordering the options dict (:attr:`options`). """
-
     def send(self, typ, route, recipient, message):
         """Main send function, that is called, for every single message.
 
--- a/iro/offer/smstrade.py	Fri Mar 30 11:49:13 2012 +0200
+++ b/iro/offer/smstrade.py	Fri Mar 30 15:55:44 2012 +0200
@@ -90,11 +90,8 @@
 
     def __init__(self, name):       
         self.url = "https://gateway.smstrade.de"
-        Provider.__init__(self, name, {"sms":["basic","economy","gold","direct"]})
-        self.options.update({
-            "key":Option(lambda x,y:x,long="smstrade Gateway Key https://login.smstrade.de/index.php?gateway", must=True)
-            })
-        self.order.append("key")
+        options =[("key", Option(lambda x,y:x,long="smstrade Gateway Key https://login.smstrade.de/index.php?gateway", must=True)),]
+        Provider.__init__(self, name, {"sms":["basic","economy","gold","direct"]},options)
 
     def send(self, route, recipient, sms):
         """send on SMS to recipients via route
--- a/iro/offer/smtp.py	Fri Mar 30 11:49:13 2012 +0200
+++ b/iro/offer/smtp.py	Fri Mar 30 15:55:44 2012 +0200
@@ -28,17 +28,16 @@
 
     """
     def __init__(self, name):
-        Provider.__init__(self,name,{"mail":[None]})
-        self.options.update({
-            "send_from":Option(vEmail,long="Emailaddress from which mail will be sended.",must=True),
-            "host":Option(lambda x,y:x, long="Hostname of MTA", must=True),
-            "port":Option(partial(vInteger,minv=0),long="Port of the MTA", default=25),
-            "user":Option(lambda x,y:x, long="username to login into MTA.",default=""),
-            "password":Option(lambda x,y:x, long="password to login into MTA.",default=""),
-            "SSL":Option(vBool,long="use SSL for connection to MTA", default=False),
-            "TLS":Option(vBool,long="use TLS for connection to MTA", default=False),
-            })
-        self.order.extend(["host","port","user","password","SSL","TLS","send_from"])
+        options = [
+                ("host", Option(lambda x,y: x, long="Hostname of MTA", must=True)),
+                ("port", Option(partial(vInteger,minv=0),long="Port of the MTA", default=25)),
+                ("user", Option(lambda x,y: x, long="username to login into MTA.",default="")),
+                ("password", Option(lambda x,y: x, long="password to login into MTA.",default="")),
+                ("SSL", Option(vBool,long="use SSL for connection to MTA", default=False)),
+                ("TLS", Option(vBool,long="use TLS for connection to MTA", default=False)),
+                ("send_from", Option(vEmail,long="Emailaddress from which mail will be sended.",must=True)),
+                ]
+        Provider.__init__(self,name,{"mail":[None]},options)
 
     def send(self, recipient, mail):   
         """sends a mail to recipient
--- a/iro/tests/config.py	Fri Mar 30 11:49:13 2012 +0200
+++ b/iro/tests/config.py	Fri Mar 30 15:55:44 2012 +0200
@@ -3,12 +3,15 @@
 import signal
 import io
 import ConfigParser
-from  iro import config, error 
+from collections import OrderedDict
+from functools import partial
+
+from iro import config, error, validate 
 from iro.offer.provider import Provider, providers
 
 class TestModuleConfig(unittest.TestCase):
     '''test config class'''
-    
+ 
     def setUp(self):
         self._reloadList=config.configParser.reloadList
         config.configParser.reloadList=[]
@@ -76,6 +79,8 @@
 
 class TestRead(unittest.TestCase):
 
+
+
     def tearDown(self):
         for s in config.configParser.sections():
             config.configParser.remove_section(s)
@@ -137,8 +142,8 @@
         v=Mock()
         class TestProvider(Provider):
             def __init__(self,name):
-                Provider.__init__(self,name)
-                self.options.update({"test":config.Option(v)})
+                o = [("test",config.Option(v))]
+                Provider.__init__(self, name, options=o)
         providers["test"]=TestProvider
         try:
             sample_config = """[p]
@@ -158,11 +163,19 @@
 
 
 class TestConfig(unittest.TestCase):
+
+    def config(self,name):
+        return config.Config(name, OrderedDict([
+                ("dburl",config.Option(lambda x,y:x,long="Connection URL to database",must=True)),
+                ("port",config.Option(partial(validate.vInteger,minv=0),long="Port under that twisted is running",must=True)),
+                ])
+            )
+
     def testSame(self):
-        c1 = config.Config("1")
+        c1 = self.config("1")
         c1.port = 1
         c1.dburl = "dburl1"
-        c2 = config.Config("2")
+        c2 = self.config("2")
         c2.port = 1
         c2.dburl = "dburl1"
         self.assertTrue(c1.same(c2))
@@ -177,15 +190,15 @@
         self.assertFalse(c1.same(c2))
 
     def testSampleConf(self):
-        c1 = config.Config("1")
+        c1 = self.config("1")
         self.assertEqual(c1.sampleConf(),["[1]",
             "# Connection URL to database",
             "dburl = ","",
             "# Port under that twisted is running",
             "port = ",""])
 
-    def testsampleConfDefault(self):
-        c1 = config.Config("1")
+    def testSampleConfDefault(self):
+        c1 = self.config("1")
         c1.options["port"].default = 12345
         c1.options["port"].must = False
         c1.options["dburl"].default = True