Merge lp:~openerp-commiter/openobject-server/trunk-import-binary-file into lp:openobject-server

Proposed by Nicolas DS
Status: Rejected
Rejected by: Fabien (Open ERP)
Proposed branch: lp:~openerp-commiter/openobject-server/trunk-import-binary-file
Merge into: lp:openobject-server
Diff against target: 132 lines (+28/-2) (has conflicts)
5 files modified
bin/import_xml.rng (+1/-0)
bin/osv/orm.py (+4/-0)
bin/tools/convert.py (+12/-0)
bin/tools/yaml_import.py (+1/-1)
bin/tools/yaml_tag.py (+10/-1)
Text conflict in bin/tools/convert.py
To merge this branch: bzr merge lp:~openerp-commiter/openobject-server/trunk-import-binary-file
Reviewer Review Type Date Requested Status
Fabien (Open ERP) Disapprove
Nicolas DS (community) Approve
Christophe Simonis (OpenERP) Approve
Olivier Dony (Odoo) Pending
Review via email: mp+27799@code.launchpad.net

Description of the change

To import binary data in a binary field for now you can only does this:
- Use XML-RPC, NET-RPC.
- Using direct python code. (Not nice)
- Convert manually all binary file in Base64 and put it in XML, CSV or YAML file.

This merge allows to import binary file directly into binary field with module by using XML, CSV or YAML.

Usage:
======
* Put a binary file in your module path
ie: my_module/my_picture.png and my_module/pict/robot.jpg

In CSV ("my_model.csv):
-----------------------
id, name, image (binary field)
pict1,My pict,@my_picture.png
pict2,Robot pict,@pict/robot.jpg

In XML:
-------
<record model="my_model" id="pict1">
    <field name="name">My pict</field>
    <field name="image" filename="my_picture.png" />
</record>
<record model="my_model" id="pict2">
    <field name="name">Robot pict</field/>
    <field name="image" filename="pict/robot.jpg" />
</record>

In YAML:
-------------
-
  !record {model: my_model, id: pict1}:
    name: My pict
    image: !filename my_picture.png
-
  !record {model: my_model, id: pict2}:
    name: Robot pict
    image: !filename pict/robot.jpg

Test module available at:
http://zyphos.be/openobject/import_binary_test.zip

Forum topic:
http://openobject.com/forum/topic6577.html

To post a comment you must log in.
Revision history for this message
Christophe Simonis (OpenERP) (kangol) wrote :

The "@" is a hack.

Why not just add a new attribute "filename" to the xml ?
and a "!! filename" directive to the yaml parser ?

the csv parser could possibly keep the "@" hack.

review: Disapprove
2387. By Nicolas DS

[FIX] Use filename attribute for XML and !filename for YAML instead of @

Revision history for this message
Nicolas DS (zyphos) wrote :

> The "@" is a hack.
>
> Why not just add a new attribute "filename" to the xml ?
> and a "!! filename" directive to the yaml parser ?
>
> the csv parser could possibly keep the "@" hack.

It's corrected.
See this merge description for the new usage.
Test module has been updated according to those changes.

2388. By Nicolas DS

[FIX] Typos in function name

Revision history for this message
Christophe Simonis (OpenERP) (kangol) wrote :

Seems ok to me

review: Approve
2389. By Nicolas DS

[MERGE] with official trunk

2390. By Nicolas DS

[MERGE] from official trunk

2391. By Nicolas DS

[FIX] Small fix for last merge

Revision history for this message
Nicolas DS (zyphos) wrote :

Ready again to be merge into official trunk.

review: Needs Resubmitting
Revision history for this message
Nicolas DS (zyphos) :
review: Approve
2392. By Nicolas DS

[FIX] Def beginning with "_" is local only in module

Revision history for this message
Fabien (Open ERP) (fp-tinyerp) wrote :

Hello,

The idea is very good.

I don't think you can accept "@..." in import_data which can be called through web-services.
This is a very big security hole. Think about using "@/etc/passwd".

The processing of the @ must be in the XML or YAML processing.

review: Disapprove
Revision history for this message
Fabien (Open ERP) (fp-tinyerp) wrote :

You can resubmit when this is fixed, as it's a good contribution.

Unmerged revisions

2392. By Nicolas DS

[FIX] Def beginning with "_" is local only in module

2391. By Nicolas DS

[FIX] Small fix for last merge

2390. By Nicolas DS

[MERGE] from official trunk

2389. By Nicolas DS

[MERGE] with official trunk

2388. By Nicolas DS

[FIX] Typos in function name

2387. By Nicolas DS

[FIX] Use filename attribute for XML and !filename for YAML instead of @

2386. By Nicolas DS

[IMP] Import @ targeted file in binary field, for CSV, XML and YAML
Usage:
- Put a file (picture, data,...) in your module path. Ie: mymodule/my_picture.png
- In XML, YAML, or CSV put the relative path preceded by a @. Ie: @my_picture.png

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/import_xml.rng'
2--- bin/import_xml.rng 2010-06-09 13:40:13 +0000
3+++ bin/import_xml.rng 2010-09-20 09:13:46 +0000
4@@ -127,6 +127,7 @@
5 <rng:optional><rng:attribute name="search"/></rng:optional>
6 <rng:optional><rng:attribute name="model"/></rng:optional>
7 <rng:optional><rng:attribute name="use"/></rng:optional>
8+ <rng:optional><rng:attribute name="filename"/></rng:optional>
9 <rng:oneOrMore>
10 <rng:choice>
11 <rng:ref name="any"/>
12
13=== modified file 'bin/osv/orm.py'
14--- bin/osv/orm.py 2010-09-20 09:00:56 +0000
15+++ bin/osv/orm.py 2010-09-20 09:13:46 +0000
16@@ -849,6 +849,10 @@
17 res = line[i].lower() not in ('0', 'false', 'off')
18 elif fields_def[field[len(prefix)]]['type'] == 'float':
19 res = line[i] and float(line[i])
20+ elif fields_def[field[len(prefix)]]['type'] == 'binary':
21+ if line[i] and line[i][0] == '@':
22+ # if binary field and first char is '@', import targeted file
23+ res = tools.get_file(current_module, line[i][1:])
24 elif fields_def[field[len(prefix)]]['type'] == 'selection':
25 res = False
26 if isinstance(fields_def[field[len(prefix)]]['selection'],
27
28=== modified file 'bin/tools/convert.py'
29--- bin/tools/convert.py 2010-09-16 11:47:26 +0000
30+++ bin/tools/convert.py 2010-09-20 09:13:46 +0000
31@@ -25,6 +25,7 @@
32 import os.path
33 import pickle
34 import re
35+import base64
36
37 # for eval context:
38 import time
39@@ -68,6 +69,7 @@
40 model = pool.get(model_str)
41 return lambda x: model.browse(cr, uid, x, context=context)
42
43+<<<<<<< TREE
44 def _fix_multiple_roots(node):
45 """
46 Surround the children of the ``node`` element of an XML field with a
47@@ -86,6 +88,13 @@
48 data_node.append(child)
49 node.append(data_node)
50
51+=======
52+def get_file(module, filename):
53+ path = os.path.join(module, filename)
54+ file_data = misc.file_open(path,'rb').read()
55+ return base64.encodestring(file_data)
56+
57+>>>>>>> MERGE-SOURCE
58 def _eval_xml(self, node, pool, cr, uid, idref, context=None):
59 if context is None:
60 context = {}
61@@ -769,6 +778,7 @@
62 f_name = field.get("name",'').encode('utf-8')
63 f_ref = field.get("ref",'').encode('utf-8')
64 f_search = field.get("search",'').encode('utf-8')
65+ f_filename = field.get("filename",'').encode('utf-8')
66 f_model = field.get("model",'').encode('utf-8')
67 if not f_model and model._columns.get(f_name,False):
68 f_model = model._columns[f_name]._obj
69@@ -801,6 +811,8 @@
70 f_val = val[0] + ',' + str(val[1])
71 else:
72 f_val = self.id_get(cr, f_model, f_ref)
73+ elif f_filename:
74+ f_val = get_file(self.module, f_filename)
75 else:
76 f_val = _eval_xml(self,field, self.pool, cr, self.uid, self.idref)
77 if model._columns.has_key(f_name):
78
79=== modified file 'bin/tools/yaml_import.py'
80--- bin/tools/yaml_import.py 2010-09-17 09:41:00 +0000
81+++ bin/tools/yaml_import.py 2010-09-20 09:13:46 +0000
82@@ -713,7 +713,7 @@
83 """
84 Processes a Yaml string. Custom tags are interpreted by 'process_' instance methods.
85 """
86- yaml_tag.add_constructors()
87+ yaml_tag.add_constructors(self.module)
88
89 is_preceded_by_comment = False
90 for node in yaml.load(yaml_string):
91
92=== modified file 'bin/tools/yaml_tag.py'
93--- bin/tools/yaml_tag.py 2010-04-30 14:18:10 +0000
94+++ bin/tools/yaml_tag.py 2010-09-20 09:13:46 +0000
95@@ -1,6 +1,8 @@
96 import yaml
97 import logging
98
99+import convert
100+
101 class YamlTag(object):
102 """
103 Superclass for constructors of custom tags defined in yaml file.
104@@ -143,6 +145,12 @@
105 else:
106 kwargs = loader.construct_mapping(node)
107 return Ref(**kwargs)
108+
109+def get_filename_constructor(module):
110+ def filename_constructor(loader, node):
111+ filename = loader.construct_scalar(node)
112+ return convert.get_file(module,filename)
113+ return filename_constructor
114
115 def ir_set_constructor(loader, node):
116 kwargs = loader.construct_mapping(node)
117@@ -151,7 +159,7 @@
118 # Registers constructors for custom tags.
119 # Constructors are actually defined globally: do not redefined them in another
120 # class/file/package. This means that module recorder need import this file.
121-def add_constructors():
122+def add_constructors(module = ''):
123 yaml.add_constructor(u"!assert", assert_constructor)
124 yaml.add_constructor(u"!record", record_constructor)
125 yaml.add_constructor(u"!python", python_constructor)
126@@ -166,4 +174,5 @@
127 yaml.add_constructor(u"!eval", eval_constructor)
128 yaml.add_multi_constructor(u"!ref", ref_constructor)
129 yaml.add_constructor(u"!ir_set", ir_set_constructor)
130+ yaml.add_constructor(u"!filename", get_filename_constructor(module))
131 add_constructors()
132\ No newline at end of file