--- 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")
--- a/iro/model/offer.py Thu Feb 23 16:59:49 2012 +0100
+++ b/iro/model/offer.py Sat Feb 25 16:12:07 2012 +0100
@@ -1,7 +1,7 @@
from .dbdefer import dbdefer
import schema
-from ..config import config
+from ..config import configParser
from ..offer import getProvider, Offer
@dbdefer
@@ -22,8 +22,8 @@
def loadOffers(session):
offers.clear()
providers.clear()
- for provider in ( s for s in config.sections() if not s in ["main",]):
- p=getProvider(provider,config.get(provider,"typ"),config.items(provider))
+ for provider in ( s for s in configParser.sections() if not s in ["main",]):
+ p=getProvider(provider,configParser.get(provider,"typ"),configParser.items(provider))
for t in p.typs:
for r in p.typs[t]:
n = schema.Offer.get(session, provider, r, t).name
@@ -33,5 +33,5 @@
offers={}
providers={}
-config.registerReload(loadOffers)
+configParser.registerReload(loadOffers)
--- a/iro/offer/provider.py Thu Feb 23 16:59:49 2012 +0100
+++ b/iro/offer/provider.py Sat Feb 25 16:12:07 2012 +0100
@@ -1,35 +1,18 @@
from functools import partial
-from ..error import NoRoute, NoTyp, ValidateException, NoProvider, NeededOption
-from ..config import Option
+from ..error import NoRoute, NoTyp, ValidateException, NoProvider
+from ..config import Option, Config
-class Provider():
- def __init__(self, name, config, typs={}):
- self.name = name
- self.config = config
+class Provider(Config):
+ def __init__(self, name, typs={}):
+ Config.__init__(self, name)
self.typs=typs
self.testmode = False
-
+
self.options = {
"typ":Option(vProvider, long="One available provider typ.", must=True)
}
- def loadConfig(self):
- c=dict(self.config)
- for o in self.options:
- try:
- value = self.options[o].validate(c[o],o)
- setattr(self, o, value)
- except (KeyError):
- if self.options[o].must:
- raise NeededOption(self.name, o)
- elif self.options[o].default is not None:
- setattr(self,o,self.options[o].default)
-
- for (n, v) in self.config:
- if n == "typ":
- self.typ = v
-
def send(self, typ, route, recipient, message):
pass
@@ -43,7 +26,9 @@
def getProvider(name, typ, config):
try:
- return providers[typ](name,config)
+ p = providers[typ](name)
+ p.load(config)
+ return p
except KeyError:
raise NoProvider(typ)
--- a/iro/offer/smstrade.py Thu Feb 23 16:59:49 2012 +0100
+++ b/iro/offer/smstrade.py Sat Feb 25 16:12:07 2012 +0100
@@ -79,13 +79,12 @@
"count":('boolean',False),
"cost":('boolean',False),
}
- def __init__(self, name, config):
+ def __init__(self, name):
self.url = "https://gateway.smstrade.de"
- Provider.__init__(self,name,config,{"sms":["basic","economy","gold","direct"]})
+ 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.loadConfig()
def send(self, route, sms, recipient):
"""send SMS with $sms to $recipients"""
--- a/iro/offer/smtp.py Thu Feb 23 16:59:49 2012 +0100
+++ b/iro/offer/smtp.py Sat Feb 25 16:12:07 2012 +0100
@@ -21,8 +21,8 @@
from .provider import Provider, providers
class SMTP(Provider):
- def __init__(self, name, config):
- Provider.__init__(self,name,config,{"mail":[None]})
+ 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),
@@ -32,7 +32,6 @@
"TLS":Option(vBool,long="use TLS for connection to MTA", default=False),
"SSL":Option(vBool,long="use SSL for connection to MTA", default=False),
})
- self.loadConfig()
def send(self,mail,recipient):
if not self.testmode:
--- a/tests/config.py Thu Feb 23 16:59:49 2012 +0100
+++ b/tests/config.py Sat Feb 25 16:12:07 2012 +0100
@@ -3,25 +3,29 @@
import signal
import io
import ConfigParser
-from iro import config
+from iro import config, error
from iro.offer.provider import Provider, providers
class TestConfig(unittest.TestCase):
'''test config class'''
def setUp(self):
- self._reloadList=config.config.reloadList
- config.config.reloadList=[]
+ self._reloadList=config.configParser.reloadList
+ config.configParser.reloadList=[]
def tearDown(self):
- config.config.reloadList = self._reloadList
+ config.configParser.reloadList = self._reloadList
- @patch('iro.config.config')
- def testReadConfig(self,pConfig):
+ @patch('iro.config.main')
+ @patch('iro.config.configParser')
+ def testReadConfig(self,pConfig,pMain):
+ pMain.read = False
config.readConfig()
- self.assertEqual([i[0] for i in pConfig.method_calls],["read","reload"])
+ self.assertEqual([i[0] for i in pConfig.method_calls],["read","reload","items"])
pConfig.read.assert_called_once_with(config.confFiles)
+ pConfig.items.assert_called_once_with("main")
pConfig.reload.assert_called_once_with()
+ self.assertEqual(pMain.load.called,1)
@patch('signal.signal')
@patch('iro.config.readConfig')
@@ -35,93 +39,97 @@
def testRegisterReload(self):
def x():
pass
- config.config.registerReload(x)
- self.assertEqual(config.config.reloadList,[x])
+ config.configParser.registerReload(x)
+ self.assertEqual(config.configParser.reloadList,[x])
def testReload(self):
x = Mock()
- config.config.reloadList = [x]
- config.config.reload_()
+ config.configParser.reloadList = [x]
+ config.configParser.reload_()
x.assert_called_once_with()
class TestRead(unittest.TestCase):
def tearDown(self):
- for s in config.config.sections():
- config.config.remove_section(s)
+ for s in config.configParser.sections():
+ config.configParser.remove_section(s)
@patch('iro.config.ConfigParser.read')
def testMain(self,pRead):
sample_config = """[main]
hostname = localhost
port = 8000
+dburl = sdfdsafgsfdg
"""
- config.config.readfp(io.BytesIO(sample_config))
- config.config.read([])
- pRead.assert_called_once_with(config.config,[])
+ config.configParser.readfp(io.BytesIO(sample_config))
+ config.configParser.read([])
+ pRead.assert_called_once_with(config.configParser,[])
@patch('iro.config.ConfigParser.read')
def testMainBadPort(self,pRead):
sample_config = """[main]
hostname = localhost
port = -8000
+dburl = sadfaserasg
"""
- config.config.readfp(io.BytesIO(sample_config))
- self.assertRaises(config.ValidateException, config.config.read, [])
+ config.configParser.readfp(io.BytesIO(sample_config))
+ self.assertRaises(error.ValidateException, config.configParser.read, [])
@patch('iro.config.ConfigParser.read')
def testMainNoMust(self,pRead):
sample_config = """[main]
port = 8000
+dburl = asdfgdsrg
"""
- config.config.readfp(io.BytesIO(sample_config))
- self.assertRaises(ConfigParser.NoOptionError, config.config.read, [])
+ config.configParser.readfp(io.BytesIO(sample_config))
+ self.assertRaises(config.NeededOption, config.configParser.read, [])
@patch('iro.config.ConfigParser.read')
def testMust(self,pRead):
v=Mock()
- config.main["test"] = config.Option(v)
+ config.main.options["test"] = config.Option(v)
try:
sample_config = """[main]
hostname = localhost
+dburl = sdfawersdf
port = 8000
"""
- config.config.readfp(io.BytesIO(sample_config))
- config.config.read([])
+ config.configParser.readfp(io.BytesIO(sample_config))
+ config.configParser.read([])
self.assertEqual(v.called,0)
sample_config = """[main]
hostname = localhost
+dburl = adfgsdftsfg
port = 8000
test = foohu
"""
- config.config.readfp(io.BytesIO(sample_config))
- config.config.read([])
+ config.configParser.readfp(io.BytesIO(sample_config))
+ config.configParser.read([])
v.assert_called_once_with("foohu","test")
finally:
- del(config.main["test"])
+ del(config.main.options["test"])
@patch('iro.config.ConfigParser.read')
def testProviders(self, pRead):
v=Mock()
class TestProvider(Provider):
- def __init__(self,name,c):
- Provider.__init__(self,name,c)
+ def __init__(self,name):
+ Provider.__init__(self,name)
self.options.update({"test":config.Option(v)})
- self.loadConfig()
providers["test"]=TestProvider
try:
sample_config = """[p]
"""
- config.config.readfp(io.BytesIO(sample_config))
- self.assertRaises(ConfigParser.NoOptionError, config.config.read, [])
+ config.configParser.readfp(io.BytesIO(sample_config))
+ self.assertRaises(ConfigParser.NoOptionError, config.configParser.read, [])
self.assertEqual(v.called,0)
sample_config = """[p]
typ= test
test= foo
"""
- config.config.readfp(io.BytesIO(sample_config))
- config.config.read([])
+ config.configParser.readfp(io.BytesIO(sample_config))
+ config.configParser.read([])
v.assert_called_once_with("foo","test")
finally:
del(providers["test"])
--- a/tests/job.py Thu Feb 23 16:59:49 2012 +0100
+++ b/tests/job.py Sat Feb 25 16:12:07 2012 +0100
@@ -126,7 +126,7 @@
self.user = u
self.offer = o
- self.provider=Provider("bla", [], {"sms":["a","b","c"]})
+ self.provider=Provider("bla", {"sms":["a","b","c"]})
self.job = exJobs.create(u, [Telnumber('123456789')], SMS('test'), [])
def tearDown(self):
--- a/tests/offer.py Thu Feb 23 16:59:49 2012 +0100
+++ b/tests/offer.py Sat Feb 25 16:12:07 2012 +0100
@@ -4,7 +4,7 @@
import io
from iro.model import offer
-from iro.config import config
+from iro.config import configParser
from iro.offer import Offer, providers as OfferProviders, Provider
from iro.model.schema import User, Offer as DBOffer, Userright
from iro.controller.pool import dbPool
@@ -18,8 +18,8 @@
dbPool.start(reactor)
def tearDown(self):
- for s in config.sections():
- config.remove_section(s)
+ for s in configParser.sections():
+ configParser.remove_section(s)
dbPool.pool.stop()
offer.offers.clear()
@@ -34,7 +34,7 @@
def testReloadList(self):
'''test if loadOffers will be fired by reloading Config'''
- self.assertTrue(offer.loadOffers in config.reloadList)
+ self.assertTrue(offer.loadOffers in configParser.reloadList)
@inlineCallbacks
def testExtendProviderUnknown(self):
@@ -72,7 +72,7 @@
o=DBOffer(name="oh", provider="bla", route="a", typ="sms")
u.rights.append(Userright(o))
- offer.providers={"bla":Provider("bla", [], {"sms":["a","b","c"]})}
+ offer.providers={"bla":Provider("bla", {"sms":["a","b","c"]})}
for l in [['bla'],['oh'],['oh','bla'],['bla','oh']]:
ret = yield offer.extendProvider(u, "sms", l)
@@ -89,7 +89,7 @@
o=DBOffer(name="a", provider="bla", route="b", typ="sms")
u.rights.append(Userright(o))
- offer.providers={"bla":Provider("bla", [], {"sms":["a","b","c"]})}
+ offer.providers={"bla":Provider("bla", {"sms":["a","b","c"]})}
ret = yield offer.extendProvider(u, "sms", ["bla"])
self.assertEqual(ret, ["oh","a"])
@@ -104,9 +104,8 @@
def testLoadOffers(self):
class TestProvider(Provider):
- def __init__(self,name,config):
- Provider.__init__(self,name,config,{"sms":["a",]})
- self.loadConfig()
+ def __init__(self,name):
+ Provider.__init__(self,name,{"sms":["a",]})
with self.session() as session:
session.add(DBOffer(name="oh", provider="p", route="a", typ="sms"))
@@ -114,7 +113,7 @@
sample_config = """[p]
typ = test
"""
- config.readfp(io.BytesIO(sample_config))
+ configParser.readfp(io.BytesIO(sample_config))
OfferProviders["test"]=TestProvider
yield offer.loadOffers()
self.assertEqual(offer.offers.keys(),["oh"])
@@ -130,7 +129,7 @@
sample_config = """[p]
typ = unknown
"""
- config.readfp(io.BytesIO(sample_config))
+ configParser.readfp(io.BytesIO(sample_config))
d = offer.loadOffers()
self.assertFailure(d, NoProvider)
return d
--- a/tests/smstrade.py Thu Feb 23 16:59:49 2012 +0100
+++ b/tests/smstrade.py Sat Feb 25 16:12:07 2012 +0100
@@ -13,14 +13,16 @@
class TestSMStradeProvider(unittest.TestCase):
def getProvider(self, c=None):
- ret={"key":"XXXXXX",
+ _c={"key":"XXXXXXXX",
"typ":"smstrade",
}
if c:
- ret.update(c)
+ _c.update(c)
- return Smstrade("test",ret.items())
+ ret = Smstrade("test")
+ ret.load(_c.items())
+ return ret
@patch("urllib.urlopen")
def testSendSMS(self,mock_urlopen):
@@ -28,7 +30,7 @@
f.readlines.return_value = ["100","12345678","0.055","1"]
mock_urlopen.return_value = f
- params = ["key=XXXXXX","to=00491701234567", "message=Hello+World", "route=gold", "message_id=1", "cost=1","count=1",'charset=utf-8']
+ params = ["key=XXXXXXXX","to=00491701234567", "message=Hello+World", "route=gold", "message_id=1", "cost=1","count=1",'charset=utf-8']
params.sort()
p=self.getProvider()
@@ -49,11 +51,10 @@
testStatusCode.todo = "to implement"
def testNeededOption(self):
- c={"key":"XXXXXXXX","typ":"smstrade"}
- s=Smstrade("test",c.items())
+ s= self.getProvider()
self.assertEqual(s.key, "XXXXXXXX")
- self.assertRaises(NeededOption,Smstrade,"test",[])
+ self.assertRaises(NeededOption, s.load,[])
def testSendFunc(self):
s = self.getProvider()
--- a/tests/smtp.py Thu Feb 23 16:59:49 2012 +0100
+++ b/tests/smtp.py Sat Feb 25 16:12:07 2012 +0100
@@ -24,16 +24,18 @@
self.smtp_server.close()
def getSMTP(self, c=None):
- ret={"send_from":"send@t.de",
+ _c={"send_from":"send@t.de",
"host":HOST,
"port":PORT,
"typ":"smtp",
}
if c:
- ret.update(c)
+ _c.update(c)
- return SMTP("test",ret.items())
+ ret = SMTP("test")
+ ret.load(_c.items())
+ return ret
def testSendMail(self):
p=self.getSMTP()
@@ -120,7 +122,7 @@
"password":"p",
"typ":"smtp",
}
- s=SMTP("test",c.items())
+ s = self.getSMTP(c)
self.assertEqual(s.send_from, "send@t.de")
self.assertEqual(s.host, HOST)
self.assertEqual(s.port, PORT)
@@ -130,12 +132,12 @@
self.assertEqual(s.TLS,False)
c.update({"TLS":True, "SSL":True})
- s=SMTP("test", c.items())
+ s = self.getSMTP(c)
self.assertEqual(s.SSL,True)
self.assertEqual(s.TLS,True)
del c["host"]
- self.assertRaises(NeededOption,SMTP,"test",c.items())
+ self.assertRaises(NeededOption, s.load, c)
def testSendFunc(self):
s = self.getSMTP()
--- a/tests/task.py Thu Feb 23 16:59:49 2012 +0100
+++ b/tests/task.py Sat Feb 25 16:12:07 2012 +0100
@@ -54,7 +54,7 @@
o=DBOffer(name="test", provider="bla", route="basic", typ="sms")
u.rights.append(Userright(o))
- p=Provider(name="p", config={}, typs={"sms":["test",]})
+ p=Provider(name="p", typs={"sms":["test",]})
def send(typ,route,recipient,message):
return Status(provider=p, route=route)
p.send=send