Merge lp:~serpentcs/server-env-tools/base_module_record into lp:~server-env-tools-core-editors/server-env-tools/7.0

Proposed by Serpent Consulting Services
Status: Needs review
Proposed branch: lp:~serpentcs/server-env-tools/base_module_record
Merge into: lp:~server-env-tools-core-editors/server-env-tools/7.0
Diff against target: 1437 lines (+1372/-0)
11 files modified
base_module_record/__init__.py (+25/-0)
base_module_record/__openerp__.py (+59/-0)
base_module_record/base_module_record.py (+505/-0)
base_module_record/security/ir.model.access.csv (+2/-0)
base_module_record/wizard/__init__.py (+26/-0)
base_module_record/wizard/base_module_record_data.py (+133/-0)
base_module_record/wizard/base_module_record_data_view.xml (+72/-0)
base_module_record/wizard/base_module_record_object_view.xml (+156/-0)
base_module_record/wizard/base_module_record_objects.py (+173/-0)
base_module_record/wizard/base_module_save.py (+170/-0)
base_module_record/wizard/base_module_save_view.xml (+51/-0)
To merge this branch: bzr merge lp:~serpentcs/server-env-tools/base_module_record
Reviewer Review Type Date Requested Status
Alexandre Fayolle - camptocamp code review, no tests Needs Fixing
Yannick Vaucher @ Camptocamp Abstain
Raphaël Valyi - http://www.akretion.com Abstain
Stefan Rijnhart (Opener) Needs Information
Pedro Manuel Baeza Disapprove
Joël Grand-Guillaume @ camptocamp code review, no tests Disapprove
Review via email: mp+196613@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c) wrote :

Hi,

Thanks for the work. I'm wondering why OpenERP SA dropped this module. Seems like, at least on my experience, it was producing a very randomized result and never really succeed to use it...

So, for my own opinion, I'm not in favor of taking it here under the community umbrella. But if other people want to, then say it and I may change my mind.

In the meanwhile I disapprove that MP.

Regards,

Joël

review: Disapprove (code review, no tests)
Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

The problem with this module is IMHO that you need a very controlled environment to get results from it, and doesn't fulfill all the requirements that a "module creator" must have, so I also vote for having out from OCA repositories. If not, we can receive a lot of bugs reports for this or that thing from unexperienced users that believe that this module resolves all their problems.

Regards.

review: Disapprove
Revision history for this message
Serpent Consulting Services (serpent-consulting-services) wrote :

Sounds alright if community feels so.

Let this be out of server-env-tools, yet available for end users to use if they wish.

Thank you guys, appreciate your efforts and time on this.

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Interesting. I would not have judged so hard on this module. Then again, I only ever used it to export data that was at that time easier for me to configure in the interface than in XML, such as email templates. I don't use it anymore, but I would not mind keeping it in a community repository where it has the chance to improve.

So I'm voting needs information, but to ask from other reviewers if anyone else thinks this one can be saved.

review: Needs Information
Revision history for this message
Serpent Consulting Services (serpent-consulting-services) wrote :

The Core and simple purpose of the module is to save your job of writing the simple yml n xml files.
OpenERP does not have a UI editor as of now, so this module does the job!

Revision history for this message
Sylvain LE GAL (GRAP) (sylvain-legal) wrote :

Hi,

I used this module some times in V7, like Stephen to export datas (demo or not) and only for that this module is very usefull. For exemple to write this file, that populate french departments, (http://bazaar.launchpad.net/~sylvain-legal/openerp-grap-shared/7.0/view/head:/l10n_fr_res_department/data/res_country_department_fr_data.yml), I earned an hour of work.

My PoV is : "better something than nothing", and even if this module receive a lot of bug reports, it doesn't really matter because it's a tools only for admin user.

My 2 cents.

review: Approve (module used, no code review)
Revision history for this message
Raphaël Valyi - http://www.akretion.com (rvalyi) wrote :

Hello,

I let the other decide. Basically my PoV is that this is a shitty module that will remain a shitty module because it produces output that you should reprocess quite a lot manually. Now if some find it useful, why not.

review: Abstain
Revision history for this message
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote :

Never used that module

review: Abstain
Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :

Never used it, code looks shaggy, and there are not tests.

Are there known issues?

In it's current state, this module is not on par with the standards of OCA and it needs care and love.

If someone has use for this module and is volunteering to maintain it, I'm willing to perform a detailed review of the code and help that person to improve the module.

review: Needs Fixing (code review, no tests)

Unmerged revisions

54. By Serpent Consulting Services

Base_module_record v7 compatible
;

53. By Serpent Consulting Services

Merged with Parent

52. By Vacha Trivedi(SerpentCS)

[IMP] base_module_record : Improvments for v7 compatiblebase_module_record as av7 compatible module

51. By Serpent Consulting Services

[ADD] Added base_module_record as av7 compatible module

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'base_module_record'
=== added file 'base_module_record/__init__.py'
--- base_module_record/__init__.py 1970-01-01 00:00:00 +0000
+++ base_module_record/__init__.py 2013-11-25 18:42:07 +0000
@@ -0,0 +1,25 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from . import base_module_record
23from . import wizard
24# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
25
026
=== added file 'base_module_record/__openerp__.py'
--- base_module_record/__openerp__.py 1970-01-01 00:00:00 +0000
+++ base_module_record/__openerp__.py 2013-11-25 18:42:07 +0000
@@ -0,0 +1,59 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22
23{
24 'name': 'Record and Create Modules',
25 'version': '1.0',
26 'category': 'Tools',
27 'description': """
28This module allows you to create a new module without any development.
29======================================================================
30
31It records all operations on objects during the recording session and
32produce a .ZIP module. So you can create your own module directly from
33the OpenERP client.
34
35This version works for creating and updating existing records. It recomputes
36dependencies and links for all types of widgets (many2one, many2many, ...).
37It also support workflows and demo/update data.
38
39This should help you to easily create reusable and publishable modules
40for custom configurations and demo/testing data.
41
42How to use it:
43Run Administration/Customization/Module Creation/Export Customizations As a Module wizard.
44Select datetime criteria of recording and objects to be recorded and Record module.
45 """,
46 'author': 'OpenERP SA, Serpent Consulting Services Pvt. Ltd.',
47 'website': 'http://www.openerp.com, http://www.serpentcs.com',
48 'depends': ['base'],
49 'data': [
50 'security/ir.model.access.csv',
51 'wizard/base_module_record_object_view.xml',
52 'wizard/base_module_record_data_view.xml',
53 ],
54 'demo': [],
55 'installable': True,
56 'auto_install':False,
57 'images': ['images/base_module_record1.jpeg','images/base_module_record2.jpeg','images/base_module_record3.jpeg',]
58}
59# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
060
=== added file 'base_module_record/base_module_record.py'
--- base_module_record/base_module_record.py 1970-01-01 00:00:00 +0000
+++ base_module_record/base_module_record.py 2013-11-25 18:42:07 +0000
@@ -0,0 +1,505 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from xml.dom import minidom
23from openerp.osv import fields,osv
24from openerp import pooler
25import string
26from openerp import tools
27
28
29class xElement(minidom.Element):
30 """dom.Element with compact print
31 The Element in minidom has a problem: if printed, adds whitespace
32 around the text nodes. The standard will not ignore that whitespace.
33 This class simply prints the contained nodes in their compact form, w/o
34 added spaces.
35 """
36 def writexml(self, writer, indent="", addindent="", newl=""):
37 writer.write(indent)
38 minidom.Element.writexml(self, writer, indent='', addindent='', newl='')
39 writer.write(newl)
40
41def doc_createXElement(xdoc, tagName):
42 e = xElement(tagName)
43 e.ownerDocument = xdoc
44 return e
45
46import yaml
47from openerp.tools import yaml_tag # This import is not unused! Do not remove!
48# Please do not override yaml_tag here: modify it in server bin/tools/yaml_tag.py
49
50class base_module_record(osv.Model):
51 _name = "ir.module.record"
52 _columns = {
53
54 }
55 def __init__(self, *args, **kwargs):
56 self.recording = 0
57 self.recording_data = []
58 self.depends = {}
59 super(base_module_record, self).__init__(*args, **kwargs)
60
61 # To Be Improved
62 def _create_id(self, cr, uid, model, data):
63 i = 0
64 while True:
65 try:
66 name = filter(lambda x: x in string.letters, (data.get('name','') or '').lower())
67 except:
68 name=''
69# name=data.get('name','') or ''.lower()
70 val = model.replace('.','_')+'_'+ name + str(i)
71 i+=1
72 if val not in self.ids.values():
73 break
74 return val
75
76 def _get_id(self, cr, uid, model, id):
77 if type(id)==type(()):
78 id=id[0]
79 if (model,id) in self.ids:
80 res_id = self.ids[(model,id)]
81 return res_id, False
82 dt = self.pool.get('ir.model.data')
83 dtids = dt.search(cr, uid, [('model','=',model), ('res_id','=',id)])
84 if not dtids:
85 return False, None
86 obj = dt.browse(cr, uid, dtids[0])
87 self.depends[obj.module] = True
88 return obj.module+'.'+obj.name, obj.noupdate
89
90 def _create_record(self, cr, uid, doc, model, data, record_id, noupdate=False):
91 data_pool = self.pool.get('ir.model.data')
92 model_pool = self.pool.get(model)
93
94 record = doc.createElement('record')
95 record.setAttribute("id", record_id)
96 record.setAttribute("model", model)
97 record_list = [record]
98
99 lids = data_pool.search(cr, uid, [('model','=',model)])
100 res = data_pool.read(cr, uid, lids[:1], ['module'])
101 if res:
102 self.depends[res[0]['module']]=True
103 fields = model_pool.fields_get(cr, uid)
104 for key,val in data.items():
105 if not (val or (fields[key]['type']=='boolean')):
106 continue
107 if (fields[key]['type'] in ('integer','float') or
108 fields[key]['type'] == 'selection' and isinstance(val, int)):
109 field = doc.createElement('field')
110 field.setAttribute("name", key)
111 field.setAttribute("eval", val and str(val) or 'False' )
112 record.appendChild(field)
113 elif fields[key]['type'] in ('boolean',):
114 field = doc.createElement('field')
115 field.setAttribute("name", key)
116 field.setAttribute("eval", val and '1' or '0' )
117 record.appendChild(field)
118 elif fields[key]['type'] in ('many2one',):
119 field = doc.createElement('field')
120 field.setAttribute("name", key)
121 if type(val) in (type(''),type(u'')):
122 id = val
123 else:
124 id,update = self._get_id(cr, uid, fields[key]['relation'], val)
125 noupdate = noupdate or update
126 if not id:
127 relation_pool = self.pool.get(fields[key]['relation'])
128
129 field.setAttribute("model", fields[key]['relation'])
130 fld_nm = relation_pool._rec_name
131 name = relation_pool.read(cr, uid, val,[fld_nm])[fld_nm] or False
132 field.setAttribute("search", str([(str(fld_nm) ,'=', name)]))
133 else:
134 field.setAttribute("ref", id)
135 record.appendChild(field)
136 elif fields[key]['type'] in ('one2many',):
137 for valitem in (val or []):
138 if valitem[0] in (0,1):
139 if key in model_pool._columns:
140 model_pool._columns[key]._fields_id
141 else:
142 model_pool._inherit_fields[key][2]._fields_id
143 if valitem[0] == 0:
144 newid = self._create_id(cr, uid, fields[key]['relation'], valitem[2])
145 valitem[1]=newid
146 else:
147 newid,update = self._get_id(cr, uid, fields[key]['relation'], valitem[1])
148 if not newid:
149 newid = self._create_id(cr, uid, fields[key]['relation'], valitem[2])
150 valitem[1]=newid
151 self.ids[(fields[key]['relation'], valitem[1])] = newid
152
153 childrecord, update = self._create_record(cr, uid, doc, fields[key]['relation'],valitem[2], newid)
154 noupdate = noupdate or update
155 record_list += childrecord
156 else:
157 pass
158 elif fields[key]['type'] in ('many2many',):
159 res = []
160 for valitem in (val or []):
161 if valitem[0]==6:
162 for id2 in valitem[2]:
163 id,update = self._get_id(cr, uid, fields[key]['relation'], id2)
164 self.ids[(fields[key]['relation'],id2)] = id
165 noupdate = noupdate or update
166 res.append(id)
167 field = doc.createElement('field')
168 field.setAttribute("name", key)
169 field.setAttribute("eval", "[(6,0,["+','.join(map(lambda x: "ref('%s')" % (x,), res))+'])]')
170 record.appendChild(field)
171 else:
172 field = doc_createXElement(doc, 'field')
173 field.setAttribute("name", key)
174 field.appendChild(doc.createTextNode(val))
175 record.appendChild(field)
176
177 return record_list, noupdate
178
179 def _create_yaml_record(self, cr, uid, model, data, record_id):
180 record={'model': model, 'id': str(record_id)}
181
182 model_pool = self.pool.get(model)
183 data_pool = self.pool.get('ir.model.data')
184 lids = data_pool.search(cr, uid, [('model','=',model)])
185
186 res = data_pool.read(cr, uid, lids[:1], ['module'])
187 attrs={}
188 if res:
189 self.depends[res[0]['module']]=True
190 fields = model_pool.fields_get(cr, uid)
191 defaults={}
192 try:
193 defaults[model] = model_pool.default_get(cr, uid, data)
194 except:
195 defaults[model]={}
196 for key,val in data.items():
197 if ((key in defaults[model]) and (val == defaults[model][key])) and not(fields[key].get('required',False)):
198 continue
199 if fields[key]['type'] in ('integer','float'):
200 if not val:
201 val=0.0
202 attrs[key] = val
203 elif not (val or (fields[key]['type']=='function')):
204 continue
205 elif fields[key]['type'] in ('boolean',):
206 if not val:
207 continue
208 attrs[key] = val
209 elif fields[key]['type'] in ('many2one',):
210 if type(val) in (type(''), type(u'')):
211 id = val
212 else:
213 id, update = self._get_id(cr, uid, fields[key]['relation'], val)
214 attrs[key] = str(id)
215 elif fields[key]['type'] in ('one2many',):
216 items=[[]]
217 for valitem in (val or []):
218 if valitem[0] in (0,1):
219 if key in model_pool._columns:
220 fname = model_pool._columns[key]._fields_id
221 else:
222 fname = model_pool._inherit_fields[key][2]._fields_id
223 del valitem[2][fname] #delete parent_field from child's fields list
224
225 childrecord = self._create_yaml_record(cr, uid, fields[key]['relation'],valitem[2], None)
226 items[0].append(childrecord['attrs'])
227 attrs[key] = items
228 elif fields[key]['type'] in ('many2many',):
229 if (key in defaults[model]) and (val[0][2] == defaults[model][key]):
230 continue
231 res = []
232 for valitem in (val or []):
233 if valitem[0]==6:
234 for id2 in valitem[2]:
235 id,update = self._get_id(cr, uid, fields[key]['relation'], id2)
236 self.ids[(fields[key]['relation'],id2)] = id
237 res.append(str(id))
238 m2m=[res]
239 if m2m[0]:
240 attrs[key] = m2m
241 else:
242 try:
243 attrs[key]=str(val)
244 except:
245 attrs[key]=tools.ustr(val)
246 attrs[key]=attrs[key].replace('"','\'')
247 record['attrs'] = attrs
248 return record
249
250 def get_copy_data(self, cr, uid, model, id, result):
251 res = []
252 obj=self.pool.get(model)
253 data=obj.read(cr, uid,[id])
254 if type(data)==type([]):
255 del data[0]['id']
256 data=data[0]
257 else:
258 del data['id']
259
260 mod_fields = obj.fields_get(cr, uid)
261 for f in filter(lambda a: isinstance(obj._columns[a], fields.function)\
262 and (not obj._columns[a].store),obj._columns):
263 del data[f]
264
265 for key,val in data.items():
266 if result.has_key(key):
267 continue
268 if mod_fields[key]['type'] == 'many2one':
269 if type(data[key])==type(True) or type(data[key])==type(1):
270 result[key]=data[key]
271 elif not data[key]:
272 result[key] = False
273 else:
274 result[key]=data[key][0]
275
276 elif mod_fields[key]['type'] in ('one2many',):
277# continue # due to this start stop recording will not record one2many field
278 rel = mod_fields[key]['relation']
279 if rel == 'mail.message':
280 continue
281 if len(data[key]):
282 res1=[]
283 for rel_id in data[key]:
284 res=[0,0]
285 res.append(self.get_copy_data(cr, uid,rel,rel_id,{}))
286 res1.append(res)
287 result[key]=res1
288 else:
289 result[key]=data[key]
290
291 elif mod_fields[key]['type'] == 'many2many':
292 result[key]=[(6,0,data[key])]
293
294 else:
295 result[key]=data[key]
296 for k,v in obj._inherits.items():
297 del result[v]
298 return result
299
300 def _create_function(self, cr, uid, doc, model, name, record_id):
301 record = doc.createElement('function')
302 record.setAttribute("name", name)
303 record.setAttribute("model", model)
304 record_list = [record]
305
306 value = doc.createElement('value')
307 value.setAttribute('eval', '[ref(\'%s\')]' % (record_id, ))
308 value.setAttribute('model', model)
309
310 record.appendChild(value)
311 return record_list, False
312
313 def _generate_object_xml(self, cr, uid, rec, recv, doc, result=None):
314 record_list = []
315 noupdate = False
316 if rec[3]=='write':
317 for id in rec[4]:
318 id,update = self._get_id(cr, uid, rec[2], id)
319 noupdate = noupdate or update
320 if not id:
321 continue
322 record,update = self._create_record(cr, uid, doc, rec[2], rec[5], id)
323 noupdate = noupdate or update
324 record_list += record
325
326 elif rec[4] in ('menu_create',):
327 for id in rec[5]:
328 id,update = self._get_id(cr, uid, rec[3], id)
329 noupdate = noupdate or update
330 if not id:
331 continue
332 record,update = self._create_function(cr, uid, doc, rec[3], rec[4], id)
333 noupdate = noupdate or update
334 record_list += record
335
336 elif rec[3]=='create':
337 id = self._create_id(cr, uid, rec[2],rec[4])
338 record,noupdate = self._create_record(cr, uid, doc, rec[2], rec[4], id)
339 self.ids[(rec[2], result)] = id
340 record_list += record
341
342 elif rec[3]=='copy':
343 data=self.get_copy_data(cr,uid,rec[2],rec[4],rec[5])
344 copy_rec=(rec[0],rec[1],rec[2],rec[3],rec[4],data,rec[5])
345 rec=copy_rec
346 rec_data=[(self.recording_data[0][0],rec,self.recording_data[0][2],self.recording_data[0][3])]
347 self.recording_data=rec_data
348 id = self._create_id(cr, uid, rec[2],rec[5])
349 record,noupdate = self._create_record(cr, uid, doc, rec[2], rec[5], id)
350 self.ids[(rec[2], result)] = id
351 record_list += record
352
353 return record_list,noupdate
354
355 def _generate_object_yaml(self, cr, uid, rec, result=None):
356 if self.mode=="create":
357 yml_id = self._create_id(cr, uid, rec[2],rec[4])
358 self.ids[(rec[2], result)] = yml_id
359 record = self._create_yaml_record(cr, uid, rec[2], rec[4], yml_id)
360 return record
361 if self.mode=="workflow":
362 id,update = self._get_id(cr, uid, rec[2], rec[4])
363 data = {}
364 data['model'] = rec[2]
365 data['action'] = rec[3]
366 data['ref'] = id
367 return data
368 if self.mode=="write":
369 id,update = self._get_id(cr, uid, rec[2],rec[4][0])
370 record = self._create_yaml_record(cr, uid, rec[2], rec[5], id)
371 return record
372 data=self.get_copy_data(cr,uid,rec[2],rec[4],rec[5])
373 copy_rec=(rec[0],rec[1],rec[2],rec[3],rec[4],data,rec[5])
374 rec=copy_rec
375 rec_data=[(self.recording_data[0][0],rec,self.recording_data[0][2],self.recording_data[0][3])]
376 self.recording_data=rec_data
377 id = self._create_id(cr, uid, rec[2],rec[5])
378 record = self._create_yaml_record(cr, uid, str(rec[2]), rec[5], id)
379 self.ids[(rec[2], result)] = id
380 return record
381
382 def _generate_function_yaml(self, cr, uid, args):
383 db, uid, model, action, ids, context = args
384 temp_context = context.copy()
385 active_id = temp_context['active_id']
386 active_model = temp_context['active_model']
387 active_id, update = self._get_id(cr, uid, active_model, active_id)
388 if not active_id:
389 active_id = 1
390 rec_id, noupdate = self._get_id(cr, uid, model, ids[0])
391 temp_context['active_id'] = "ref('%s')"%unicode(active_id)
392 temp_context['active_ids'][0] = "ref('%s')"%str(active_id)
393 function={}
394 function['model'] = model
395 function['action'] = action
396 attrs = "self.%s(cr, uid, [ref('%s')], {" %(action, rec_id, )
397 for k, v in temp_context.iteritems():
398 if isinstance(v, str):
399 f= "'"+k+"': "+"'%s'"%v + ", "
400 else:
401 v=str(v).replace('"', '')
402 f= "'"+k+"': "+"%s"%v + ", "
403 attrs = attrs + f
404 attrs=str(attrs)+'})'
405 function['attrs'] = attrs
406 return function
407
408 def _generate_assert_xml(self, rec, doc):
409 pass
410
411 def generate_xml(self, cr, uid):
412 # Create the minidom document
413 if len(self.recording_data):
414 self.ids = {}
415 doc = minidom.Document()
416 terp = doc.createElement("openerp")
417 doc.appendChild(terp)
418 for rec in self.recording_data:
419 if rec[0]=='workflow':
420 rec_id,noupdate = self._get_id(cr, uid, rec[1][2], rec[1][4])
421 if not rec_id:
422 continue
423 data = doc.createElement("data")
424 terp.appendChild(data)
425 wkf = doc.createElement('workflow')
426 data.appendChild(wkf)
427 wkf.setAttribute("model", rec[1][2])
428 wkf.setAttribute("action", rec[1][3])
429 if noupdate:
430 data.setAttribute("noupdate", "1")
431 wkf.setAttribute("ref", rec_id)
432 if rec[0]=='query':
433 res_list,noupdate = self._generate_object_xml(cr, uid, rec[1], rec[2], doc, rec[3])
434 data = doc.createElement("data")
435 if noupdate:
436 data.setAttribute("noupdate", "1")
437 if res_list:
438 terp.appendChild(data)
439 for res in res_list:
440 data.appendChild(res)
441 elif rec[0]=='assert':
442 pass
443 return doc.toprettyxml(indent="\t").encode('utf-8')
444
445 def generate_yaml(self, cr, uid):
446 self.ids = {}
447 if len(self.recording_data):
448 yaml_file='''\n'''
449
450 for rec in self.recording_data:
451 if rec[1][3] == 'create':
452 self.mode="create"
453 elif rec[1][3] == 'write':
454 self.mode="write"
455 elif rec[1][3] == 'copy':
456 self.mode="copy"
457 elif rec[0] == 'workflow':
458 self.mode="workflow"
459 elif rec[0] == 'osv_memory_action':
460 self.mode='osv_memory_action'
461 else:
462 continue
463 if self.mode == "workflow":
464 record = self._generate_object_yaml(cr, uid, rec[1],rec[0])
465 yaml_file += "!comment Performing a workflow action %s on module %s"%(record['action'], record['model']) + '''\n'''
466 object = yaml.load(unicode('''\n !workflow %s \n'''%record,'iso-8859-1'))
467 yaml_file += str(object) + '''\n\n'''
468 elif self.mode == 'osv_memory_action':
469 osv_action = self._generate_function_yaml(cr, uid, rec[1])
470 yaml_file += "!comment Performing an osv_memory action %s on module %s"%(osv_action['action'], osv_action['model']) + '''\n'''
471 osv_action = yaml.load(unicode('''\n !python %s \n'''%osv_action,'iso-8859-1'))
472 yaml_file += str(osv_action) + '''\n'''
473 attrs = yaml.dump(osv_action.attrs, default_flow_style=False)
474 attrs = attrs.replace("''", '"')
475 attrs = attrs.replace("'", '')
476 yaml_file += attrs + '''\n\n'''
477 else:
478 record = self._generate_object_yaml(cr, uid, rec[1], rec[3])
479 if self.mode == "create" or self.mode == "copy":
480 yaml_file += "!comment Creating a %s record"%(record['model']) + '''\n'''
481 else:
482 yaml_file += "!comment Modifying a %s record"%(record['model']) + '''\n'''
483 object = yaml.load(unicode('''\n !record %s \n'''%record,'iso-8859-1'))
484 yaml_file += str(object) + '''\n'''
485 attrs = yaml.dump(object.attrs, default_flow_style=False)
486 yaml_file += attrs + '''\n\n'''
487
488 yaml_result=''''''
489 for line in yaml_file.split('\n'):
490 line=line.replace("''","'")
491 if (line.find('!record') == 0) or (line.find('!workflow') == 0) or (line.find('!python') == 0):
492 line = "- \n" + " " + line
493 elif line.find('!comment') == 0:
494 line=line.replace('!comment','- \n ')
495 elif line.find('- -') != -1:
496 line=line.replace('- -',' -')
497 line = " " + line
498 else:
499 line = " " + line
500 yaml_result += line + '''\n'''
501 return yaml_result
502
503base_module_record()
504# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
505
0506
=== added directory 'base_module_record/images'
=== added file 'base_module_record/images/base_module_record1.jpeg'
1Binary files base_module_record/images/base_module_record1.jpeg 1970-01-01 00:00:00 +0000 and base_module_record/images/base_module_record1.jpeg 2013-11-25 18:42:07 +0000 differ507Binary files base_module_record/images/base_module_record1.jpeg 1970-01-01 00:00:00 +0000 and base_module_record/images/base_module_record1.jpeg 2013-11-25 18:42:07 +0000 differ
=== added file 'base_module_record/images/base_module_record2.jpeg'
2Binary files base_module_record/images/base_module_record2.jpeg 1970-01-01 00:00:00 +0000 and base_module_record/images/base_module_record2.jpeg 2013-11-25 18:42:07 +0000 differ508Binary files base_module_record/images/base_module_record2.jpeg 1970-01-01 00:00:00 +0000 and base_module_record/images/base_module_record2.jpeg 2013-11-25 18:42:07 +0000 differ
=== added file 'base_module_record/images/base_module_record3.jpeg'
3Binary files base_module_record/images/base_module_record3.jpeg 1970-01-01 00:00:00 +0000 and base_module_record/images/base_module_record3.jpeg 2013-11-25 18:42:07 +0000 differ509Binary files base_module_record/images/base_module_record3.jpeg 1970-01-01 00:00:00 +0000 and base_module_record/images/base_module_record3.jpeg 2013-11-25 18:42:07 +0000 differ
=== added directory 'base_module_record/security'
=== added file 'base_module_record/security/ir.model.access.csv'
--- base_module_record/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
+++ base_module_record/security/ir.model.access.csv 2013-11-25 18:42:07 +0000
@@ -0,0 +1,2 @@
1id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2access_ir_module_record,ir.module.record,model_ir_module_record,base.group_system,1,1,1,1
03
=== added directory 'base_module_record/wizard'
=== added file 'base_module_record/wizard/__init__.py'
--- base_module_record/wizard/__init__.py 1970-01-01 00:00:00 +0000
+++ base_module_record/wizard/__init__.py 2013-11-25 18:42:07 +0000
@@ -0,0 +1,26 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from . import base_module_save
23from . import base_module_record_objects
24from . import base_module_record_data
25# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
26
027
=== added file 'base_module_record/wizard/base_module_record_data.py'
--- base_module_record/wizard/base_module_record_data.py 1970-01-01 00:00:00 +0000
+++ base_module_record/wizard/base_module_record_data.py 2013-11-25 18:42:07 +0000
@@ -0,0 +1,133 @@
1# -*- encoding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from openerp.osv import orm, fields, osv
23from openerp import tools
24from openerp.tools.translate import _
25
26import time
27
28class base_module_data(orm.TransientModel):
29 _name = 'base.module.data'
30 _description = "Base Module Data"
31
32 _columns = {
33 'check_date': fields.datetime('Record from Date', required=True),
34 'objects': fields.many2many('ir.model', 'base_module_record_model_rel', 'objects', 'model_id', 'Objects'),
35 'filter_cond': fields.selection([('created', 'Created'), ('modified', 'Modified'), ('created_modified', 'Created & Modified')], 'Records only', required=True),
36 'info_yaml': fields.boolean('YAML'),
37 }
38
39 def _get_default_objects(self, cr, uid, context=None):
40 names = ('ir.ui.view', 'ir.ui.menu', 'ir.model', 'ir.model.fields', 'ir.model.access',
41 'res.partner', 'res.partner.category', 'workflow',
42 'workflow.activity', 'workflow.transition', 'ir.actions.server', 'ir.server.object.lines')
43 return self.pool.get('ir.model').search(cr, uid, [('model', 'in', names)])
44
45 _defaults = {
46 'check_date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
47 'objects': _get_default_objects,
48 'filter_cond': 'created',
49 }
50
51 def _create_xml(self, cr, uid, data, context=None):
52 mod = self.pool.get('ir.module.record')
53 res_xml = mod.generate_xml(cr, uid)
54 return {'res_text': res_xml }
55
56 def _create_yaml(self, cr, uid, data, context=None):
57 mod = self.pool.get('ir.module.record')
58 res_xml = mod.generate_yaml(cr, uid)
59 return { 'res_text': res_xml }
60
61 def record_objects(self, cr, uid, ids, context=None):
62 data = self.read(cr, uid, ids, [], context=context)[0]
63 check_date = data['check_date']
64 filter = data['filter_cond']
65 user = (self.pool.get('res.users').browse(cr, uid, uid)).login
66 mod = self.pool.get('ir.module.record')
67 mod_obj = self.pool.get('ir.model')
68 mod.recording_data = []
69 for id in data['objects']:
70 obj_name=(mod_obj.browse(cr, uid, id)).model
71 obj_pool=self.pool.get(obj_name)
72 if filter =='created':
73 search_condition =[('create_date','>',check_date)]
74 elif filter =='modified':
75 search_condition =[('write_date','>',check_date)]
76 elif filter =='created_modified':
77 search_condition =['|',('create_date','>',check_date),('write_date','>',check_date)]
78 if '_log_access' in dir(obj_pool):
79 if not (obj_pool._log_access):
80 search_condition=[]
81 if '_auto' in dir(obj_pool):
82 if not obj_pool._auto:
83 continue
84 search_ids=obj_pool.search(cr,uid,search_condition)
85 for s_id in search_ids:
86 args=(cr.dbname,uid,obj_name,'copy', s_id,{}, context)
87 mod.recording_data.append(('query', args, {}, s_id))
88
89 mod_obj = self.pool.get('ir.model.data')
90 if len(mod.recording_data):
91 if data['info_yaml']:
92 res=self._create_yaml(cr, uid, data, context)
93 else:
94 res=self._create_xml(cr, uid, data, context)
95 model_data_ids = mod_obj.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'module_create_xml_view')], context=context)
96 resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
97 return {
98 'name': _('Data Recording'),
99 'context': {'default_res_text': tools.ustr(res['res_text'])},
100 'view_type': 'form',
101 'view_mode': 'form',
102 'res_model': 'base.module.record.data',
103 'views': [(resource_id, 'form')],
104 'type': 'ir.actions.act_window',
105 'target': 'new',
106 }
107
108 model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'module_recording_message_view')], context=context)
109 resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
110 return {
111 'name': _('Module Recording'),
112 'context': context,
113 'view_type': 'form',
114 'view_mode': 'form',
115 'res_model': 'base.module.record.objects',
116 'views': [(resource_id, 'form')],
117 'type': 'ir.actions.act_window',
118 'target': 'new',
119 }
120
121base_module_data()
122
123class base_module_record_data(orm.TransientModel):
124 _name = 'base.module.record.data'
125 _description = "Base Module Record Data"
126
127 _columns = {
128 'res_text': fields.text('Result'),
129 }
130
131base_module_record_data()
132
133#vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0134
=== added file 'base_module_record/wizard/base_module_record_data_view.xml'
--- base_module_record/wizard/base_module_record_data_view.xml 1970-01-01 00:00:00 +0000
+++ base_module_record/wizard/base_module_record_data_view.xml 2013-11-25 18:42:07 +0000
@@ -0,0 +1,72 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record id="base_module_record_data_view" model="ir.ui.view">
6 <field name="name">base_module_record_data</field>
7 <field name="model">base.module.data</field>
8 <field name="arch" type="xml">
9 <form string="Data Recording" version="7.0">
10 <sheet>
11 <group>
12 <field name="check_date"/>
13 <newline/>
14 <field name="filter_cond"/>
15 <separator string="Choose objects to record" colspan="4"/>
16 <field name="objects" colspan="4" nolabel="1"/>
17 </group>
18 <group><field name="info_yaml"/></group>
19 <footer>
20 <button icon="gtk-cancel" string="Cancel" special="cancel"/>
21 <button name="record_objects" icon="gtk-ok" string="Record" type="object"/>
22 </footer>
23 </sheet>
24 </form>
25 </field>
26 </record>
27
28 <record model="ir.actions.act_window" id="action_base_module_record_data">
29 <field name="name">Export Customizations as Data</field>
30 <field name="res_model">base.module.data</field>
31 <field name="view_type">form</field>
32 <field name="view_mode">form</field>
33 <field name="target">new</field>
34 <field name="view_id" ref="base_module_record_data_view"/>
35 </record>
36
37
38 <menuitem
39 parent="menu_wizard_base_mod_rec"
40 name="Export Customizations As Data file"
41 action="action_base_module_record_data"
42 id="menu_wizard_base_module_record_data"/>
43
44 <act_window
45 id="act_base_module_record_data"
46 name="Export Customizations As Data File"
47 res_model="base.module.data"
48 src_model="ir.module.module"
49 view_mode="form"
50 target="new"
51 multi="True"
52 key2="client_action_multi"/>
53
54 <record id="module_create_xml_view" model="ir.ui.view">
55 <field name="name">module.create.xml.form</field>
56 <field name="model">base.module.record.data</field>
57 <field name="arch" type="xml">
58 <form string="Data Recording" version="7.0">
59 <sheet>
60 <group>
61 <separator string="Result, paste this to your module's xml" colspan="4"/>
62 <field name="res_text" nolabel="1" colspan="4"/>
63 </group>
64 <footer>
65 <button icon="gtk-close" string="Close" special="cancel"/>
66 </footer>
67 </sheet>
68 </form>
69 </field>
70 </record>
71 </data>
72</openerp>
073
=== added file 'base_module_record/wizard/base_module_record_object_view.xml'
--- base_module_record/wizard/base_module_record_object_view.xml 1970-01-01 00:00:00 +0000
+++ base_module_record/wizard/base_module_record_object_view.xml 2013-11-25 18:42:07 +0000
@@ -0,0 +1,156 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record id="base_module_record_objects_view" model="ir.ui.view">
6 <field name="name">base_module_record_objects</field>
7 <field name="model">base.module.record</field>
8 <field name="arch" type="xml">
9 <form string="Objects Recording" version="7.0">
10 <sheet>
11 <group>
12 <field name="check_date"/>
13 <newline/>
14 <field name="filter_cond"/>
15 <separator string="Choose objects to record" colspan="4"/>
16 <field name="objects" colspan="4" nolabel="1"/>
17 </group>
18 <group><field name="info_yaml"/></group>
19 <separator colspan="4"/>
20 <footer>
21 <button icon="gtk-cancel" string="Cancel" special="cancel"/>
22 <button name="record_objects" icon="gtk-ok" string="Record" type="object"/>
23 </footer>
24 </sheet>
25 </form>
26 </field>
27 </record>
28
29 <record model="ir.actions.act_window" id="action_base_module_record_objects">
30 <field name="name">Export Customizations as a Module</field>
31 <field name="res_model">base.module.record</field>
32 <field name="view_type">form</field>
33 <field name="view_mode">form</field>
34 <field name="target">new</field>
35 <field name="view_id" ref="base_module_record_objects_view"/>
36 </record>
37
38 <menuitem
39 parent="base.menu_custom"
40 name="Module Creation"
41 id="menu_wizard_base_mod_rec"/>
42<!-- groups="base.group_extended"/> -->
43
44 <menuitem
45 parent="menu_wizard_base_mod_rec"
46 name="Export Customizations As a Module"
47 action="action_base_module_record_objects"
48 id="menu_wizard_base_module_record_objects"/>
49
50 <act_window
51 id="act_base_module_record_objects"
52 name="Export Customizations As a Module"
53 res_model="base.module.record"
54 src_model="ir.module.module"
55 view_mode="form"
56 target="new"
57 multi="True"
58 key2="client_action_multi"/>
59
60 <record id="module_create_form_view" model="ir.ui.view">
61 <field name="name">module.create.form</field>
62 <field name="model">base.module.record.objects</field>
63 <field name="arch" type="xml">
64 <form string="Module Recording" version="7.0">
65 <sheet>
66 <group>
67 <separator string="Module successfully created !" colspan="4"/>
68 <field name="module_filename"/>
69 <newline/>
70 <field name="module_file"/>
71 </group>
72 <separator string="Information" colspan="4"/>
73 <label string="If you think your module could interest other people, we'd like you to publish it on http://www.openerp.com, in the 'Modules' section. You can do it through the website or using features of the 'base_module_publish' module." colspan="4" align="0.0"/>
74 <label string="Thanks in advance for your contribution." colspan="4" align="0.0"/>
75 <separator colspan="4"/>
76 <footer>
77 <button icon="gtk-close" string="Close" special="cancel"/>
78 </footer>
79 </sheet>
80 </form>
81 </field>
82 </record>
83
84 <record model="ir.actions.act_window" id="action_module_created">
85 <field name="name">Module Recording</field>
86 <field name="res_model">base.module.record.objects</field>
87 <field name="view_type">form</field>
88 <field name="view_mode">form</field>
89 <field name="target">new</field>
90 <field name="view_id" ref="module_create_form_view"/>
91 </record>
92
93 <record id="info_start_form_view" model="ir.ui.view">
94 <field name="name">info.start.form.view</field>
95 <field name="model">base.module.record.objects</field>
96 <field name="arch" type="xml">
97 <form string="Module Recording" version="7.0">
98 <sheet>
99 <group>
100 <separator string="Module Information" colspan="4"/>
101 <field name="name"/>
102 <field name="directory_name"/>
103 <field name="version"/>
104 <field name="author"/>
105 <field name="website"/>
106 <field name="category"/>
107 <field name="data_kind"/>
108 <newline/>
109 <field name="description"/>
110 <separator colspan="4"/>
111 <footer>
112 <button icon="gtk-cancel" string="Cancel" special="cancel"/>
113 <button string="Continue" name="inter_call" type="object" icon="gtk-ok"/>
114 </footer>
115 </group>
116 </sheet>
117 </form>
118 </field>
119 </record>
120
121 <record id="module_recording_message_view" model="ir.ui.view">
122 <field name="name">module_recording_message</field>
123 <field name="model">base.module.record.objects</field>
124 <field name="arch" type="xml">
125 <form string="Module Recording" version="7.0">
126 <sheet>
127 <label string="Thanks For using Module Recorder" colspan="4" align="0.0"/>
128 <separator string="" colspan="4"/>
129 <footer>
130 <button icon="gtk-ok" string="OK" special="cancel"/>
131 </footer>
132 </sheet>
133 </form>
134 </field>
135 </record>
136
137 <record id="yml_save_form_view" model="ir.ui.view">
138 <field name="name">yml.save.form</field>
139 <field name="model">base.module.record.objects</field>
140 <field name="arch" type="xml">
141 <form string="Module Recording" version="7.0">
142 <sheet>
143 <separator string="YAML file successfully created !" colspan="4"/>
144 <newline/>
145 <field name="yaml_file" filename="module_filename"/>
146 <separator colspan="4"/>
147 <footer>
148 <button icon="gtk-close" string="Close" special="cancel"/>
149 </footer>
150 </sheet>
151 </form>
152 </field>
153 </record>
154
155 </data>
156</openerp>
0157
=== added file 'base_module_record/wizard/base_module_record_objects.py'
--- base_module_record/wizard/base_module_record_objects.py 1970-01-01 00:00:00 +0000
+++ base_module_record/wizard/base_module_record_objects.py 2013-11-25 18:42:07 +0000
@@ -0,0 +1,173 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from openerp.osv import orm, fields, osv
23from openerp import tools
24from openerp.tools.translate import _
25from . import base_module_save
26
27import time
28
29class base_module_record(orm.TransientModel):
30 _name = 'base.module.record'
31 _description = "Base Module Record"
32
33 _columns = {
34 'check_date': fields.datetime('Record from Date', required=True),
35 'objects': fields.many2many('ir.model', 'base_module_record_object_rel', 'objects', 'model_id', 'Objects'),
36 'filter_cond': fields.selection([('created', 'Created'), ('modified', 'Modified'), ('created_modified', 'Created & Modified')], 'Records only', required=True),
37 'info_yaml': fields.boolean('YAML'),
38 }
39
40 def _get_default_objects(self, cr, uid, context=None):
41 names = ('ir.ui.view', 'ir.ui.menu', 'ir.model', 'ir.model.fields', 'ir.model.access',
42 'res.partner', 'res.partner.address', 'res.partner.category', 'workflow',
43 'workflow.activity', 'workflow.transition', 'ir.actions.server', 'ir.server.object.lines')
44 return self.pool.get('ir.model').search(cr, uid, [('model', 'in', names)])
45
46 _defaults = {
47 'check_date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
48 'objects': _get_default_objects,
49 'filter_cond': 'created',
50 }
51
52 def record_objects(self, cr, uid, ids, context=None):
53 data = self.read(cr, uid, ids, [], context=context)[0]
54 check_date=data['check_date']
55 filter=data['filter_cond']
56 user=(self.pool.get('res.users').browse(cr,uid,uid)).login
57 mod = self.pool.get('ir.module.record')
58 mod_obj = self.pool.get('ir.model')
59 mod.recording_data = []
60 for id in data['objects']:
61 obj_name=(mod_obj.browse(cr,uid,id)).model
62 obj_pool=self.pool.get(obj_name)
63 if filter =='created':
64 search_condition =[('create_date', '>', check_date)]
65 elif filter =='modified':
66 search_condition =[('write_date', '>', check_date)]
67 elif filter =='created_modified':
68 search_condition =['|',('create_date', '>', check_date), ('write_date', '>', check_date)]
69 if '_log_access' in dir(obj_pool):
70 if not (obj_pool._log_access):
71 search_condition=[]
72 if '_auto' in dir(obj_pool):
73 if not obj_pool._auto:
74 continue
75 search_ids = obj_pool.search(cr,uid,search_condition)
76 for s_id in search_ids:
77 args=(cr.dbname, uid,obj_name, 'copy', s_id,{},context)
78 mod.recording_data.append(('query', args, {}, s_id))
79
80 mod_obj = self.pool.get('ir.model.data')
81 if len(mod.recording_data):
82 if data['info_yaml']:
83 mod = self.pool.get('ir.module.record')
84 res=base_module_save._create_yaml(self, cr, uid, data, context)
85 model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'yml_save_form_view')], context=context)
86 resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
87 return {
88 'name': _('Message'),
89 'context': {'default_yaml_file': tools.ustr(res['yaml_file'])},
90 'view_type': 'form',
91 'view_mode': 'form',
92 'res_model': 'base.module.record.objects',
93 'views': [(resource_id, 'form')],
94 'type': 'ir.actions.act_window',
95 'target': 'new',
96 }
97 else:
98 model_data_ids = mod_obj.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'info_start_form_view')], context=context)
99 resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
100 return {
101 'name': _('Message'),
102 'context': context,
103 'view_type': 'form',
104 'view_mode': 'form',
105 'res_model': 'base.module.record.objects',
106 'views': [(resource_id, 'form')],
107 'type': 'ir.actions.act_window',
108 'target': 'new',
109 }
110
111 model_data_ids = mod_obj.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'module_recording_message_view')], context=context)
112 resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
113 return {
114 'name': _('Message'),
115 'context': context,
116 'view_type': 'form',
117 'view_mode': 'form',
118 'res_model': 'base.module.record.objects',
119 'views': [(resource_id, 'form')],
120 'type': 'ir.actions.act_window',
121 'target': 'new',
122 }
123
124base_module_record()
125
126class base_module_record_objects(orm.TransientModel):
127 _name = 'base.module.record.objects'
128 _description = "Base Module Record Objects"
129
130 def inter_call(self,cr,uid,data,context=None):
131 res=base_module_save._create_module(self, cr, uid, data, context)
132 mod_obj = self.pool.get('ir.model.data')
133 model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'module_create_form_view')], context=context)
134 resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
135 context.update(res)
136
137 return {
138 'name': _('Message'),
139 'context': {
140 'default_module_filename': tools.ustr(res['module_filename']),
141 'default_module_file': tools.ustr(res['module_file']),
142 },
143 'view_type': 'form',
144 'view_mode': 'form',
145 'res_model': 'base.module.record.objects',
146 'views': [(resource_id, 'form')],
147 'type': 'ir.actions.act_window',
148 'target': 'new',
149 }
150
151 _columns = {
152 'name': fields.char('Module Name', size=64, required=True),
153 'directory_name': fields.char('Directory Name', size=32, required=True),
154 'version': fields.char('Version', size=16, required=True),
155 'author': fields.char('Author', size=64, required=True),
156 'category': fields.char('Category', size=64, required=True),
157 'website': fields.char('Documentation URL', size=64, required=True),
158 'description': fields.text('Full Description', required=True),
159 'data_kind': fields.selection([('demo', 'Demo Data'), ('update', 'Normal Data')], 'Type of Data', required=True),
160 'module_file': fields.binary('Module .zip File', filename="module_filename"),
161 'module_filename': fields.char('Filename', size=64),
162 'yaml_file': fields.binary('Module .zip File'),
163 }
164 _defaults = {
165 'author': 'OpenERP SA',
166 'category': 'Vertical Modules/Parametrization',
167 'website': 'http://www.openerp.com',
168 'data_kind': 'update',
169 }
170
171base_module_record_objects()
172
173# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0174
=== added file 'base_module_record/wizard/base_module_save.py'
--- base_module_record/wizard/base_module_save.py 1970-01-01 00:00:00 +0000
+++ base_module_record/wizard/base_module_save.py 2013-11-25 18:42:07 +0000
@@ -0,0 +1,170 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22import zipfile
23import StringIO
24import base64
25
26from openerp import tools
27from openerp.tools.translate import _
28from openerp.osv import orm, fields, osv
29
30
31def _create_yaml(self, cr, uid, data, context=None):
32 mod = self.pool.get('ir.module.record')
33 try:
34 res_xml = mod.generate_yaml(cr, uid)
35 except Exception, e:
36 raise osv.except_osv(_('Error'),_(str(e)))
37 return {
38 'yaml_file': base64.encodestring(res_xml),
39}
40
41def _create_module(self, cr, uid, ids, context=None):
42 mod = self.pool.get('ir.module.record')
43 res_xml = mod.generate_xml(cr, uid)
44 data = self.read(cr, uid, ids, [], context=context)[0]
45 s = StringIO.StringIO()
46 zip = zipfile.ZipFile(s, 'w')
47 dname = data['directory_name']
48 data['update_name'] = ''
49 data['demo_name'] = ''
50 if ['data_kind'] =='demo':
51 data['demo_name'] = '"%(directory_name)s_data.xml"' % data
52 else:
53 data['update_name'] = '"%(directory_name)s_data.xml"' % data
54 data['depends'] = ','.join(map(lambda x: '"'+x+'"', mod.depends.keys()))
55 _terp = """{
56 "name" : "%(name)s",
57 "version" : "%(version)s",
58 "author" : "%(author)s",
59 "website" : "%(website)s",
60 "category" : "%(category)s",
61 "description": \"\"\"%(description)s\"\"\",
62 "depends" : [%(depends)s],
63 "init_xml" : [ ],
64 "demo_xml" : [ %(demo_name)s],
65 "update_xml" : [%(update_name)s],
66 "installable": True
67} """ % data
68 filewrite = {
69 '__init__.py':'#\n# Generated by the OpenERP module recorder !\n#\n',
70 '__openerp__.py':_terp,
71 dname+'_data.xml': res_xml
72 }
73 for name,datastr in filewrite.items():
74 info = zipfile.ZipInfo(dname+'/'+name)
75 info.compress_type = zipfile.ZIP_DEFLATED
76 info.external_attr = 2175008768
77 if not datastr:
78 datastr = ''
79 zip.writestr(info, datastr)
80 zip.close()
81 return {
82 'module_file': base64.encodestring(s.getvalue()),
83 'module_filename': data['directory_name']+'-'+data['version']+'.zip'
84 }
85
86class base_module_save(orm.TransientModel):
87 _name = 'base.module.save'
88 _description = "Base Module Save"
89
90 def default_get(self, cr, uid, fields, context=None):
91 mod = self.pool.get('ir.module.record')
92 result = {}
93 info = "Details of "+str(len(mod.recording_data))+" Operation(s):\n\n"
94 res = super(base_module_save, self).default_get(cr, uid, fields, context=context)
95 for line in mod.recording_data:
96 result.setdefault(line[0],{})
97 result[line[0]].setdefault(line[1][3], {})
98 result[line[0]][line[1][3]].setdefault(line[1][3], 0)
99 result[line[0]][line[1][3]][line[1][3]]+=1
100 for key1,val1 in result.items():
101 info+=key1+"\n"
102 for key2,val2 in val1.items():
103 info+="\t"+key2+"\n"
104 for key3,val3 in val2.items():
105 info+="\t\t"+key3+" : "+str(val3)+"\n"
106 if 'info_text' in fields:
107 res.update({'info_text': info})
108 if 'info_status' in fields:
109 info_status = mod.recording and 'record' or 'no'
110 res.update({'info_status': info_status})
111 return res
112
113 _columns = {
114 'info_text': fields.text('Information', readonly=True),
115 'info_status': fields.selection([('no', 'Not Recording'),('record', 'Recording')], 'Status', readonly=True),
116 'info_yaml': fields.boolean('YAML'),
117 }
118
119 def record_save(self, cr, uid, ids, context=None):
120 data = self.read(cr, uid, ids, [], context=context)[0]
121 mod = self.pool.get('ir.module.record')
122 mod_obj = self.pool.get('ir.model.data')
123 if len(mod.recording_data):
124 if data['info_yaml']:
125 mod = self.pool.get('ir.module.record')
126 res=_create_yaml(self, cr, uid, data, context)
127 model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'yml_save_form_view')], context=context)
128 resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
129 return {
130 'name': _('Message'),
131 'context': {
132 'default_yaml_file': tools.ustr(res['yaml_file']),
133 },
134 'view_type': 'form',
135 'view_mode': 'form',
136 'res_model': 'base.module.record.objects',
137 'views': [(resource_id, 'form')],
138 'type': 'ir.actions.act_window',
139 'target': 'new',
140 }
141 else:
142 model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'info_start_form_view')], context=context)
143 resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
144 return {
145 'name': _('Message'),
146 'context': context,
147 'view_type': 'form',
148 'view_mode': 'form',
149 'res_model': 'base.module.record.objects',
150 'views': [(resource_id, 'form')],
151 'type': 'ir.actions.act_window',
152 'target': 'new',
153 }
154 model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'module_recording_message_view')], context=context)
155 resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
156
157 return {
158 'name': _('Message'),
159 'context': context,
160 'view_type': 'form',
161 'view_mode': 'form',
162 'res_model': 'base.module.record.objects',
163 'views': [(resource_id, 'form')],
164 'type': 'ir.actions.act_window',
165 'target': 'new',
166 }
167
168base_module_save()
169
170# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
0\ No newline at end of file171\ No newline at end of file
1172
=== added file 'base_module_record/wizard/base_module_save_view.xml'
--- base_module_record/wizard/base_module_save_view.xml 1970-01-01 00:00:00 +0000
+++ base_module_record/wizard/base_module_save_view.xml 2013-11-25 18:42:07 +0000
@@ -0,0 +1,51 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record id="base_module_save_view" model="ir.ui.view">
6 <field name="name">base_module_save</field>
7 <field name="model">base.module.save</field>
8 <field name="arch" type="xml">
9 <form string="Module Recording" version="7.0">
10 <sheet>
11 <separator string="Recording Information" colspan="4"/>
12 <field name="info_status"/>
13 <field name="info_text" colspan="4" nolabel="1"/>
14 <field name="info_yaml" colspan="4"/>
15 <separator colspan="4"/>
16 <group colspan="4" col="2">
17 <button icon="gtk-cancel" string="Cancel" special="cancel"/>
18 <button name="record_save" icon="gtk-ok" string="Continue" type="object"/>
19 </group>
20 </sheet>
21 </form>
22 </field>
23 </record>
24
25 <record model="ir.actions.act_window" id="action_base_module_save">
26 <field name="name">Publish as module</field>
27 <field name="res_model">base.module.save</field>
28 <field name="view_type">form</field>
29 <field name="view_mode">form</field>
30 <field name="target">new</field>
31 <field name="view_id" ref="base_module_save_view"/>
32 </record>
33
34 <menuitem
35 parent="menu_wizard_base_mod_rec"
36 name="Publish as Module"
37 action="action_base_module_save"
38 id="menu_wizard_base_module_save"/>
39
40 <act_window
41 id="act_base_module_save"
42 name="Publish as Module"
43 res_model="base.module.save"
44 src_model="ir.module.module"
45 view_mode="form"
46 target="new"
47 multi="True"
48 key2="client_action_multi"/>
49
50 </data>
51</openerp>