[IMP] field regularity
authorXavier Morel <xmo@openerp.com>
Fri, 27 Sep 2013 12:13:25 +0000 (14:13 +0200)
committerXavier Morel <xmo@openerp.com>
Fri, 27 Sep 2013 12:13:25 +0000 (14:13 +0200)
Make @file a more generic data source, add base64 type for b64 encoding

bzr revid: xmo@openerp.com-20130927121325-mbjm4612qkaa0z0x

doc/03_module_dev_01.rst
openerp/import_xml.rng
openerp/tools/convert.py

index adc32c4..f35dab5 100644 (file)
@@ -206,8 +206,8 @@ Extra attributes can either preprocess the body or replace its use entirely:
 ``@type`` (optional)
 
     One of ``char``, ``int``, ``float``, ``list``, ``tuple``, ``xml`` or
-    ``html`` or ``file``. Converts the ``field``'s body to the specified type
-    (or validates the body's content)
+    ``html``, ``file`` or ``base64``. Converts the ``field``'s body to the
+    specified type (or validates the body's content)
 
     * ``xml`` will join multiple XML nodes under a single ``<data>`` root
     * in ``xml`` and ``html``, external ids can be referenced using
@@ -217,6 +217,13 @@ Extra attributes can either preprocess the body or replace its use entirely:
     * ``file`` expects a module-local path and will save the path prefixed with
       the current module's name, separated by a ``,`` (comma). For use with
       :py:func:`~openerp.modules.module.get_module_resource`.
+    * ``base64`` expects binary data, encodes it to base64 and sets it. Mostly
+      useful with ``@file``
+
+``@file``
+
+    Can be used with types ``char`` and ``base64``, sources the field's content
+    from the specified file instead of the field's text body.
 
 ``@model``
 
index e694e6d..8b9b588 100644 (file)
                 <rng:group>
                     <rng:attribute name="type">
                         <rng:choice>
+                            <rng:value>base64</rng:value>
                             <rng:value>char</rng:value>
                             <rng:value>file</rng:value>
                         </rng:choice>
                     </rng:attribute>
-                    <rng:text/>
+                    <rng:choice>
+                        <rng:group>
+                            <rng:attribute name="file"/>
+                            <rng:empty/>
+                        </rng:group>
+                        <rng:text/>
+                    </rng:choice>
                 </rng:group>
                 <rng:group>
                     <rng:attribute name="type"><rng:value>int</rng:value></rng:attribute>
                     </rng:oneOrMore>
                 </rng:group>
                 <rng:group>
-                    <rng:attribute name="file"/>
-                    <rng:empty/>
-                </rng:group>
-                <rng:group>
                     <rng:attribute name="ref"/>
                     <rng:empty/>
                 </rng:group>
                     <rng:optional><rng:attribute name="use"/></rng:optional>
                     <rng:empty/>
                 </rng:group>
-                <rng:group>
-                    <rng:text/>
-                </rng:group>
+                <rng:text/>
             </rng:choice>
         </rng:element>
     </rng:define>
index 0b65cfc..29c52d4 100644 (file)
@@ -175,34 +175,38 @@ def _eval_xml(self, node, pool, cr, uid, idref, context=None):
         if t == 'html':
             return _process("".join([etree.tostring(n, encoding='utf-8')
                                    for n in node]), idref)
+
+        data = node.text
         if node.get('file'):
-            import openerp.tools
-            import base64
-            fp = openerp.tools.file_open(node.get('file'))
-            result = base64.b64encode(fp.read())
-            return result
+            with openerp.tools.file_open(node.get('file'), 'rb') as f:
+                data = f.read()
 
         if t == 'file':
             from ..modules import module
-            path = node.text.strip()
+            path = data.strip()
             if not module.get_module_resource(self.module, path):
                 raise IOError("No such file or directory: '%s' in %s" % (
                     path, self.module))
             return '%s,%s' % (self.module, path)
-        if t in ('char', 'int', 'float'):
-            d = node.text
-            if t == 'int':
-                d = d.strip()
-                if d == 'None':
-                    return None
-                else:
-                    return int(d.strip())
-            elif t == 'float':
-                return float(d.strip())
-            return d
-        elif t in ('list','tuple'):
+
+        if t == 'char':
+            return data
+
+        if t == 'base64':
+            return data.encode('base64')
+
+        if t == 'int':
+            d = data.strip()
+            if d == 'None':
+                return None
+            return int(d)
+
+        if t == 'float':
+            return float(data.strip())
+
+        if t in ('list','tuple'):
             res=[]
-            for n in node.findall('./value'):
+            for n in node.iterchildren(tag='value'):
                 res.append(_eval_xml(self,n,pool,cr,uid,idref))
             if t=='tuple':
                 return tuple(res)