iro/config.py
branchdevel
changeset 267 ef2df3f23cb1
parent 228 944edbe51145
child 269 0d134b173cb1
equal deleted inserted replaced
266:a0adcb788fec 267:ef2df3f23cb1
     6 
     6 
     7 from validate import vInteger
     7 from validate import vInteger
     8 from error import NeededOption 
     8 from error import NeededOption 
     9 
     9 
    10 class MyConfigParser(ConfigParser):
    10 class MyConfigParser(ConfigParser):
       
    11     """Configparser that also validate configfile.
       
    12 
       
    13     It is possile to restiger function, that are called, when config file is reloaded
       
    14     """
    11     def __init__(self):
    15     def __init__(self):
    12         ConfigParser.__init__(self)
    16         ConfigParser.__init__(self)
    13         self.reloadList=[]
    17         self.reloadList=[]
    14 
    18 
    15     def read(self,files):
    19     def read(self,files):
       
    20         """reads an validate configuration file"""
    16         from offer import getProvider
    21         from offer import getProvider
    17         r = ConfigParser.read(self, files)
    22         r = ConfigParser.read(self, files)
    18         for s in self.sections():
    23         for s in self.sections():
    19             if s == "main":
    24             if s == "main":
    20                 main.validate(self.items(s))
    25                 main.validate(self.items(s))
    21             else:
    26             else:
    22                 getProvider("tmp", self.get(s,'typ'), self.items(s))
    27                 getProvider("tmp", self.get(s,'typ'), self.items(s))
    23         return r
    28         return r
    24 
    29 
    25     def reload_(self):
    30     def reload_(self):
       
    31         """run all registered function."""
    26         for f in self.reloadList:
    32         for f in self.reloadList:
    27             f()
    33             f()
    28 
    34 
    29     def registerReload(self, func):
    35     def registerReload(self, func):
       
    36         """adds **func** to reloadList.
       
    37         
       
    38         func ist called with no arguments.
       
    39         """
    30         self.reloadList.append(func)
    40         self.reloadList.append(func)
    31 
    41 
    32 class Option():
    42 class Option():
       
    43     """One Option in the configuration file"""
    33     def __init__(self, validate, long="", help="", must=False, default=None):
    44     def __init__(self, validate, long="", help="", must=False, default=None):
       
    45         """
       
    46         :param func validate: a validate function, it has to return the value, if valid and raise an error if not.
       
    47         :param string long: long description
       
    48         :param string help: the help text
       
    49         :param boolean must: Is this option nessasary
       
    50         :param default: default value
       
    51         """
    34         self.validate = validate
    52         self.validate = validate
    35         self.long=long
    53         self.long=long
    36         self.help = help
    54         self.help = help
    37         self.must = must
    55         self.must = must
    38         self.default = default
    56         self.default = default
    39 
    57 
    40 class Config:
    58 class Config:
       
    59     """Base class for all classes, that uses option from configfile.
       
    60     
       
    61     If one option is valid, the attribute is created with the value of the validate function.
       
    62     """
    41     def __init__(self, name):
    63     def __init__(self, name):
       
    64         """
       
    65         :param string name: section name.
       
    66         """
    42         self.name = name
    67         self.name = name
    43         self.options={
    68         self.options={
    44             "port":Option(partial(vInteger,minv=0),long="Port under that twisted is running",must=True),
    69             "port":Option(partial(vInteger,minv=0),long="Port under that twisted is running",must=True),
    45             "dburl":Option(lambda x,y:x,long="Connection URL to database",must=True),
    70             "dburl":Option(lambda x,y:x,long="Connection URL to database",must=True),
    46         }
    71         }
       
    72         """Options dict for Options used in configuration file (see :class:`iro.config.Option`). Ordering of configuration fields are done by :attr:`order`. 
       
    73         
       
    74         Sample::
       
    75         
       
    76                {"port":Option(partial(vInteger,minv=0),long="Port under that twisted is running",must=True),
       
    77                 "dburl":Option(lambda x,y:x,long="Connection URL to database",must=True)
       
    78                }
       
    79         
       
    80         A child class typically use update to add more options.
       
    81         """
       
    82 
    47         self.order = ["dburl","port"]
    83         self.order = ["dburl","port"]
       
    84         """ A list for ordering the options dict (:attr:`options`). """
       
    85 
    48         self._init = True
    86         self._init = True
       
    87         """indecates, if the config is loaded with config values."""
    49 
    88 
    50 
    89 
    51     def _read(self, cfg, write=False):
    90     def _read(self, cfg, write=False):
       
    91         """Test or set configuration options.
       
    92         
       
    93         :param dict cfg: The Configuration dict. Normally you use ``configParser.items("section")``.
       
    94         :param boolean write: test or set the option to actual object.
       
    95 
       
    96         :raises: :exc:`iro.error.NeededOption`
       
    97         """
    52         c = dict(cfg)
    98         c = dict(cfg)
    53 
    99 
    54         for o in self.options:
   100         for o in self.options:
    55             option = self.options[o]
   101             option = self.options[o]
    56             try:
   102             try:
    63                     raise NeededOption(self.name, o)
   109                     raise NeededOption(self.name, o)
    64                 elif write and option.default is not None:
   110                 elif write and option.default is not None:
    65                     setattr(self, o, option.default)
   111                     setattr(self, o, option.default)
    66 
   112 
    67     def validate(self, cfg):
   113     def validate(self, cfg):
       
   114         """Validate configuration.
       
   115 
       
   116         :param dict cfg: The Configuration dict. Normally you use ``configParser.items("section")``.
       
   117         """
    68         self._read(cfg, False)
   118         self._read(cfg, False)
    69 
   119 
    70     def load(self, cfg):
   120     def load(self, cfg):
       
   121         """Loads configuration into object.
       
   122 
       
   123         :param dict cfg: The Configuration dict. Normally you use ``configParser.items("section")``.
       
   124         """
    71         self._read(cfg, True)
   125         self._read(cfg, True)
    72 
   126 
    73     def same(self, other):
   127     def same(self, other):
       
   128         """returns ``True``, if the options of other object are the same"""
    74         for o in self.options:
   129         for o in self.options:
    75             if getattr(self,o) != getattr(other,o):
   130             if getattr(self,o) != getattr(other,o):
    76                 return False
   131                 return False
    77         else:
   132         else:
    78             return True
   133             return True
    79 
   134 
    80     def sampleConf(self):
   135     def sampleConf(self):
       
   136         """returns a sample Configuration section.
       
   137 
       
   138         This function also adds the long help text to the sample section.
       
   139 
       
   140         :return: a list of lines
       
   141         """
    81         ret=[]
   142         ret=[]
    82         for o in self.order:
   143         for o in self.order:
    83             opt=self.options[o]
   144             opt=self.options[o]
    84             if opt.long:
   145             if opt.long:
    85                 ret.append("# "+opt.long)
   146                 ret.append("# "+opt.long)
    93             ret.append("")
   154             ret.append("")
    94 
   155 
    95         return ["[%s]"%self.name,]+ret
   156         return ["[%s]"%self.name,]+ret
    96 
   157 
    97 def readConfig():
   158 def readConfig():
       
   159     """Read the configuration and update all registered object (see :meth:`MyConfigParser.reload_`)."""
    98     log.msg("Reading configs.")
   160     log.msg("Reading configs.")
    99     configParser.read(confFiles)
   161     configParser.read(confFiles)
   100     configParser.reload_()
   162     configParser.reload_()
   101     if main._init:
   163     if main._init:
   102         main.load(configParser.items("main"))
   164         main.load(configParser.items("main"))
   105         m.load(configParser.items("main"))
   167         m.load(configParser.items("main"))
   106         if not main.same(m):
   168         if not main.same(m):
   107             raise Exception("Main options can't be reloaded, please restart your Application.")
   169             raise Exception("Main options can't be reloaded, please restart your Application.")
   108 
   170 
   109 def init():
   171 def init():
       
   172     """Load the main options."""
   110     configParser.read(confFiles)
   173     configParser.read(confFiles)
   111     main.load(configParser.items("main"))
   174     main.load(configParser.items("main"))
   112 
   175 
   113 def registerSignal():
   176 def registerSignal():
   114     '''register readConfig to SIGUSR2'''
   177     '''register readConfig to SIGUSR2'''
   116         readConfig()
   179         readConfig()
   117 
   180 
   118     signal.signal(signal.SIGUSR2,rC)
   181     signal.signal(signal.SIGUSR2,rC)
   119 
   182 
   120 configParser = MyConfigParser()
   183 configParser = MyConfigParser()
       
   184 """configParser to get configuration."""
       
   185 
   121 confFiles=["iro.conf", "~/iro.conf","/etc/iro/iro.conf"]
   186 confFiles=["iro.conf", "~/iro.conf","/etc/iro/iro.conf"]
       
   187 """Configfile list """
   122 
   188 
   123 main = Config("main")
   189 main = Config("main")
       
   190 """Main config options"""