[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [43047] trunk/blender: add the ability to read from XML into RNA for rna_xml module

Campbell Barton ideasman42 at gmail.com
Sun Jan 1 09:09:38 CET 2012


Revision: 43047
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=43047
Author:   campbellbarton
Date:     2012-01-01 08:09:30 +0000 (Sun, 01 Jan 2012)
Log Message:
-----------
add the ability to read from XML into RNA for rna_xml module

Modified Paths:
--------------
    trunk/blender/intern/tools/dump_rna2xml.py
    trunk/blender/release/scripts/modules/rna_xml.py

Modified: trunk/blender/intern/tools/dump_rna2xml.py
===================================================================
--- trunk/blender/intern/tools/dump_rna2xml.py	2012-01-01 04:37:08 UTC (rev 43046)
+++ trunk/blender/intern/tools/dump_rna2xml.py	2012-01-01 08:09:30 UTC (rev 43047)
@@ -28,150 +28,39 @@
 # Example usage
 # blender some.blend --background -noaudio --python intern/tools/dump_rna2xml.py
 
+import os
 import bpy
+import rna_xml
 
-invalid_classes = (bpy.types.Operator,
-               bpy.types.Panel,
-               bpy.types.KeyingSet,
-               bpy.types.Header)
+def main():
+    filename = os.path.splitext(bpy.data.filepath)[0] + ".xml"
 
+    file = open(filename, 'w')
 
-def build_property_typemap():
+    if 0:
+        # blend file
+        rna_xml.rna2xml(file.write,
+                        root_rna=bpy.data,
+                        root_rna_skip={"window_managers"})
+    else:
+        # theme. just another test
+        rna_xml.rna2xml(file.write,
+                        root_rna=bpy.context.user_preferences.themes[0],
+                        method='ATTR')
+        
 
-    property_typemap = {}
+        file.close()
 
-    for attr in dir(bpy.types):
-        cls = getattr(bpy.types, attr)
-        if issubclass(cls, invalid_classes):
-            continue
-
-        properties = cls.bl_rna.properties.keys()
-        properties.remove("rna_type")
-        property_typemap[attr] = properties
-
-    return property_typemap
-
-
-def print_ln(data):
-    print(data, end="")
-
-
-def rna2xml(fw=print_ln, ident_val="  "):
-    from xml.sax.saxutils import quoteattr
-    property_typemap = build_property_typemap()
-
-    def rna2xml_node(ident, value, parent):
-        ident_next = ident + ident_val
-
-        # divide into attrs and nodes.
-        node_attrs = []
-        nodes_items = []
-        nodes_lists = []
-
-        value_type = type(value)
-
-        if issubclass(value_type, invalid_classes):
-            return
-
-        # XXX, fixme, pointcache has eternal nested pointer to its self.
-        if value == parent:
-            return
-
-        value_type_name = value_type.__name__
-        for prop in property_typemap[value_type_name]:
-
-            subvalue = getattr(value, prop)
-            subvalue_type = type(subvalue)
-
-            if subvalue_type == int:
-                node_attrs.append("%s=\"%d\"" % (prop, subvalue))
-            elif subvalue_type == float:
-                node_attrs.append("%s=\"%.4g\"" % (prop, subvalue))
-            elif subvalue_type == bool:
-                node_attrs.append("%s=\"%s\"" % (prop, "TRUE" if subvalue else "FALSE"))
-            elif subvalue_type is str:
-                node_attrs.append("%s=%s" % (prop, quoteattr(subvalue)))
-            elif subvalue_type == set:
-                node_attrs.append("%s=%s" % (prop, quoteattr("{" + ",".join(list(subvalue)) + "}")))
-            elif subvalue is None:
-                node_attrs.append("%s=\"NONE\"" % prop)
-            elif issubclass(subvalue_type, bpy.types.ID):
-                # special case, ID's are always referenced.
-                node_attrs.append("%s=%s" % (prop, quoteattr(subvalue_type.__name__ + ":" + subvalue.name)))
-            else:
-                try:
-                    subvalue_ls = list(subvalue)
-                except:
-                    subvalue_ls = None
-
-                if subvalue_ls is None:
-                    nodes_items.append((prop, subvalue, subvalue_type))
-                else:
-                    # check if the list contains native types
-                    subvalue_rna = value.path_resolve(prop, False)
-                    if type(subvalue_rna).__name__ == "bpy_prop_array":
-                        # TODO, multi-dim!
-                        def str_recursive(s):
-                            if type(s) in (int, float, bool):
-                                return str(s)
-                            else:
-                                return " ".join([str_recursive(si) for si in s])
-
-                        node_attrs.append("%s=\"%s\"" % (prop, " ".join(str_recursive(v) for v in subvalue_rna)))
-                    else:
-                        nodes_lists.append((prop, subvalue_ls, subvalue_type))
-
-        # declare + attributes
-        fw("%s<%s %s>\n" % (ident, value_type_name, " ".join(node_attrs)))
-
-        # unique members
-        for prop, subvalue, subvalue_type in nodes_items:
-            rna2xml_node(ident_next, subvalue, value)
-
-        # list members
-        for prop, subvalue, subvalue_type in nodes_lists:
-            fw("%s<%s>\n" % (ident_next, prop))
-            for subvalue_item in subvalue:
-                if subvalue_item is not None:
-                    rna2xml_node(ident_next + ident_val, subvalue_item, value)
-            fw("%s</%s>\n" % (ident_next, prop))
-
-        fw("%s</%s>\n" % (ident, value_type_name))
-
-    fw("<root>\n")
-    for attr in dir(bpy.data):
-
-        # exceptions
-        if attr.startswith("_"):
-            continue
-        elif attr == "window_managers":
-            continue
-
-        value = getattr(bpy.data, attr)
-        try:
-            ls = value[:]
-        except:
-            ls = None
-
-        if type(ls) == list:
-            fw("%s<%s>\n" % (ident_val, attr))
-            for blend_id in ls:
-                rna2xml_node(ident_val + ident_val, blend_id, None)
-            fw("%s</%s>\n" % (ident_val, attr))
-
-    fw("</root>\n")
-
-
-def main():
-    filename = bpy.data.filepath.rstrip(".blend") + ".xml"
-    file = open(filename, 'w')
-    rna2xml(file.write)
-    file.close()
-
-    # read back.
+    # read back to ensure this is valid!
     from xml.dom.minidom import parse
     xml_nodes = parse(filename)
     print("Written:", filename)
 
+    # test reading back theme
+    if 1:
+        theme = xml_nodes.getElementsByTagName("Theme")[0]
+        rna_xml.xml2rna(theme,
+                        root_rna=bpy.context.user_preferences.themes[0],)
+
 if __name__ == "__main__":
     main()

Modified: trunk/blender/release/scripts/modules/rna_xml.py
===================================================================
--- trunk/blender/release/scripts/modules/rna_xml.py	2012-01-01 04:37:08 UTC (rev 43046)
+++ trunk/blender/release/scripts/modules/rna_xml.py	2012-01-01 08:09:30 UTC (rev 43047)
@@ -20,27 +20,16 @@
 
 # <pep8 compliant>
 
-
 import bpy
 
-# easier to read
-PRETTY_INTEND = True
 
-invalid_classes = (
-    bpy.types.Operator,
-    bpy.types.Panel,
-    bpy.types.KeyingSet,
-    bpy.types.Header,
-    )
+def build_property_typemap(skip_classes):
 
-
-def build_property_typemap():
-
     property_typemap = {}
 
     for attr in dir(bpy.types):
         cls = getattr(bpy.types, attr)
-        if issubclass(cls, invalid_classes):
+        if issubclass(cls, skip_classes):
             continue
 
         properties = cls.bl_rna.properties.keys()
@@ -54,10 +43,32 @@
     print(data, end="")
 
 
-def rna2xml(fw=print_ln, ident_val="  "):
+def rna2xml(fw=print_ln,
+            root_node="",
+            root_rna=None,  # must be set
+            root_rna_skip=set(),
+            ident_val="  ",
+            skip_classes=(bpy.types.Operator,
+                          bpy.types.Panel,
+                          bpy.types.KeyingSet,
+                          bpy.types.Header,
+                          ),
+            pretty_format=True,
+            method='DATA'):
+
     from xml.sax.saxutils import quoteattr
-    property_typemap = build_property_typemap()
+    property_typemap = build_property_typemap(skip_classes)
 
+    def number_to_str(val, val_type):
+        if val_type == int:
+            return "%d" % val
+        elif val_type == float:
+            return "%.6g" % val
+        elif val_type == bool:
+            return "TRUE" if val else "FALSE"
+        else:
+            raise NotImplemented("this type is not a number %s" % val_type)
+
     def rna2xml_node(ident, value, parent):
         ident_next = ident + ident_val
 
@@ -68,7 +79,7 @@
 
         value_type = type(value)
 
-        if issubclass(value_type, invalid_classes):
+        if issubclass(value_type, skip_classes):
             return
 
         # XXX, fixme, pointcache has eternal nested pointer to its self.
@@ -81,12 +92,8 @@
             subvalue = getattr(value, prop)
             subvalue_type = type(subvalue)
 
-            if subvalue_type == int:
-                node_attrs.append("%s=\"%d\"" % (prop, subvalue))
-            elif subvalue_type == float:
-                node_attrs.append("%s=\"%.4g\"" % (prop, subvalue))
-            elif subvalue_type == bool:
-                node_attrs.append("%s=\"%s\"" % (prop, "TRUE" if subvalue else "FALSE"))
+            if subvalue_type in (int, bool, float):
+                node_attrs.append("%s=\"%s\"" % (prop, number_to_str(subvalue, subvalue_type)))
             elif subvalue_type is str:
                 node_attrs.append("%s=%s" % (prop, quoteattr(subvalue)))
             elif subvalue_type == set:
@@ -95,7 +102,7 @@
                 node_attrs.append("%s=\"NONE\"" % prop)
             elif issubclass(subvalue_type, bpy.types.ID):
                 # special case, ID's are always referenced.
-                node_attrs.append("%s=%s" % (prop, quoteattr(subvalue_type.__name__ + ":" + subvalue.name)))
+                node_attrs.append("%s=%s" % (prop, quoteattr(subvalue_type.__name__ + "::" + subvalue.name)))
             else:
                 try:
                     subvalue_ls = list(subvalue)
@@ -110,8 +117,9 @@
                     if type(subvalue_rna).__name__ == "bpy_prop_array":
                         # TODO, multi-dim!
                         def str_recursive(s):
-                            if type(s) in (int, float, bool):
-                                return str(s)
+                            subsubvalue_type = type(s)
+                            if subsubvalue_type in (int, float, bool):
+                                return number_to_str(s, subsubvalue_type)
                             else:
                                 return " ".join([str_recursive(si) for si in s])
 
@@ -120,21 +128,22 @@
                         nodes_lists.append((prop, subvalue_ls, subvalue_type))
 
         # declare + attributes
-        if PRETTY_INTEND:
+        if pretty_format:
             tmp_str = "<%s " % value_type_name
             tmp_ident = "\n" + ident + (" " * len(tmp_str))
-            
+

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-blender-cvs mailing list