Support for loading configs and configsets.

portnov [2009-02-23 10:35:08]
Support for loading configs and configsets.
Filename
configs/-1222056212.xml
configs/1.xml
configs/configsets/first.xml
configsets.py
configtemplate.py
test.py
diff --git a/configs/-1222056212.xml b/configs/-1222056212.xml
deleted file mode 100644
index 57554c7..0000000
--- a/configs/-1222056212.xml
+++ /dev/null
@@ -1 +0,0 @@
-<object><attribute name='dns'>{{services.dns.ip}}</attribute><attribute name='gateway'>{{services.gateway}}</attribute><attribute name='proxy'>{{services.proxy}}</attribute><attribute name='template'>system</attribute></object>
\ No newline at end of file
diff --git a/configs/1.xml b/configs/1.xml
new file mode 100644
index 0000000..bf31213
--- /dev/null
+++ b/configs/1.xml
@@ -0,0 +1 @@
+<object><attribute name='dns'>{{services.dns}}</attribute><attribute name='gateway'>{{services.gateway}}</attribute><attribute name='id'>1</attribute><attribute name='proxy'>{{services.proxy}}</attribute><attribute name='template'>system</attribute></object>
\ No newline at end of file
diff --git a/configs/configsets/first.xml b/configs/configsets/first.xml
index d403a30..be961ae 100644
--- a/configs/configsets/first.xml
+++ b/configs/configsets/first.xml
@@ -1,3 +1,3 @@
-<? xml version='1.0' ?>
-        <configset name='first'><config for='system'>-1222056212.xml</config>
+<?xml version='1.0'?>
+<configset name='first'><config for='system' id='1'>1.xml</config>
 </configset>
\ No newline at end of file
diff --git a/configsets.py b/configsets.py
index e792e9c..411ec09 100644
--- a/configsets.py
+++ b/configsets.py
@@ -1,6 +1,7 @@
 from os.path import join
 from copy import copy
-# import xmlserialize as xml
+from lxml import etree
+import configtemplate

 class ConfigSet(dict):
     def __init__(self,name):
@@ -12,17 +13,41 @@ class ConfigSet(dict):
         new.update(kwargs)
         return new

+    def __repr__(self):
+        lst = ", ".join(self.keys())
+        return "<ConfigSet %s for %s>" % (self.name,lst)
+
+    def __str__(self):
+        r = repr(self)
+        for k,v in self.iteritems():
+            r += '\n' + k + '\n'
+            r += str(v)
+        return r+'\n</ConfigSet>'
+
     def save(self,path):
         sfn = join(path,'configsets',self.name+'.xml')
-        xmldata = """<? xml version='1.0' ?>
-        <configset name='%s'>""" % self.name
+        xmldata = """<?xml version='1.0'?>
+<configset name='%s'>""" % self.name
         for key in self:
             cfg = self[key]
-            fn = "%s.xml" % hash(cfg)
-            xmldata += "<config for='%s'>%s</config>\n" % (key,fn)
+            fn = "%s.xml" % cfg.id
+            xmldata += "<config for='%s' id='%s'>%s</config>\n" % (key,cfg.id, fn)
             cfg.save(join(path,fn), render=False)
         xmldata += "</configset>"
         f = open(sfn,'w')
         f.write(xmldata)
         f.close()

+def read_configset(dir,filename):
+    cset = ConfigSet('')
+    spath = join(dir,'configsets',filename)
+    print "| Parsing", spath
+    xml = etree.parse(spath).getroot()
+    cset.name = xml.attrib['name']
+    for item in xml:
+        cid = item.attrib['id']
+        fn  = item.text
+        template = item.attrib['for']
+        cfg = configtemplate.read_config(join(dir,fn))
+        cset[template] = cfg
+    return cset
diff --git a/configtemplate.py b/configtemplate.py
index 6093d78..d451693 100644
--- a/configtemplate.py
+++ b/configtemplate.py
@@ -5,6 +5,9 @@ import templates
 import xmlserialize as xml

 bytemplate = {}
+byid = {}
+config_templates = {}
+lastid = 0

 def add_config(template_name, cfg):
     global bytemplate
@@ -14,14 +17,23 @@ def add_config(template_name, cfg):
         bytemplate[template_name] = [cfg]

 def read_template(path):
+    global config_templates
+
     class ConfigTemplate(object):
         def __init__(self,**kwargs):
+            global byid
+            global lastid
+
             for k,v in kwargs.items():
                 if hasattr(self,k):
                     setattr(self,k,v)
                 else:
                     raise AttributeError, "%s config has no attribute %s" % (self.__class__.__name__, k)
             add_config(self.__class__.__name__, self)
+            if not hasattr(self,'id'):
+                lastid += 1
+                self.id = lastid
+            byid[self.id] = self

         def __call__(self,**kwargs):
             cfg = copy(self)
@@ -39,6 +51,21 @@ def read_template(path):
                     raise AttributeError, "%s config has no attribute %s" % (self.__class__.__name__, k)
             return cfg

+        def __str__(self):
+            if hasattr(self,'template'):
+                r = "<Config for %s>" % self.template
+            else:
+                r = "<Config>"
+            for k in dir(self):
+                if k.startswith('_'):
+                    continue
+                v = getattr(self,k)
+                if inspect.ismethod(v):
+                    continue
+                r += "\n  %s = %s" % (k,v)
+            r += "\n</Config>"
+            return r
+
         def render(self):
             return templates.do_render(self)

@@ -60,10 +87,19 @@ def read_template(path):
         else:
             setattr(ConfigTemplate, node.attrib['name'], '')
     ConfigTemplate.__name__ = name
+    config_templates[name] = ConfigTemplate

     return ConfigTemplate

 def read_config(path):
+    global config_templates
     xmldata = open(path).read()
-    cfg = xml.deserialize(xmldata)
+    xmlcfg = xml.deserialize(xmldata)
+    cls = config_templates[xmlcfg.template]
+    cfg = cls()
+    for name in dir(xmlcfg):
+        if name.startswith('_'):
+            continue
+        v = getattr(xmlcfg,name)
+        setattr(cfg,name,v)
     return cfg
diff --git a/test.py b/test.py
index 5dbbc3a..7c59676 100755
--- a/test.py
+++ b/test.py
@@ -101,3 +101,8 @@ print ncfg.render()
 cset = configsets.ConfigSet('first')
 cset['system'] = ncfg
 cset.save('configs')
+
+print
+nset = configsets.read_configset('configs','first.xml')
+print "Read nset:"
+print nset
ViewGit