openerp-community-reviewer team mailing list archive
-
openerp-community-reviewer team
-
Mailing list archive
-
Message #01660
[Merge] lp:~serpentcs/server-env-tools/base_module_record into lp:server-env-tools
Serpent Consulting Services has proposed merging lp:~serpentcs/server-env-tools/base_module_record into lp:server-env-tools.
Requested reviews:
Server Environment And Tools Core Editors (server-env-tools-core-editors)
For more details, see:
https://code.launchpad.net/~serpentcs/server-env-tools/base_module_record/+merge/196613
--
https://code.launchpad.net/~serpentcs/server-env-tools/base_module_record/+merge/196613
Your team Server Environment And Tools Core Editors is requested to review the proposed merge of lp:~serpentcs/server-env-tools/base_module_record into lp:server-env-tools.
=== 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 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from . import base_module_record
+from . import wizard
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
=== 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 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+
+{
+ 'name': 'Record and Create Modules',
+ 'version': '1.0',
+ 'category': 'Tools',
+ 'description': """
+This module allows you to create a new module without any development.
+======================================================================
+
+It records all operations on objects during the recording session and
+produce a .ZIP module. So you can create your own module directly from
+the OpenERP client.
+
+This version works for creating and updating existing records. It recomputes
+dependencies and links for all types of widgets (many2one, many2many, ...).
+It also support workflows and demo/update data.
+
+This should help you to easily create reusable and publishable modules
+for custom configurations and demo/testing data.
+
+How to use it:
+Run Administration/Customization/Module Creation/Export Customizations As a Module wizard.
+Select datetime criteria of recording and objects to be recorded and Record module.
+ """,
+ 'author': 'OpenERP SA, Serpent Consulting Services Pvt. Ltd.',
+ 'website': 'http://www.openerp.com, http://www.serpentcs.com',
+ 'depends': ['base'],
+ 'data': [
+ 'security/ir.model.access.csv',
+ 'wizard/base_module_record_object_view.xml',
+ 'wizard/base_module_record_data_view.xml',
+ ],
+ 'demo': [],
+ 'installable': True,
+ 'auto_install':False,
+ 'images': ['images/base_module_record1.jpeg','images/base_module_record2.jpeg','images/base_module_record3.jpeg',]
+}
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== 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 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from xml.dom import minidom
+from openerp.osv import fields,osv
+from openerp import pooler
+import string
+from openerp import tools
+
+
+class xElement(minidom.Element):
+ """dom.Element with compact print
+ The Element in minidom has a problem: if printed, adds whitespace
+ around the text nodes. The standard will not ignore that whitespace.
+ This class simply prints the contained nodes in their compact form, w/o
+ added spaces.
+ """
+ def writexml(self, writer, indent="", addindent="", newl=""):
+ writer.write(indent)
+ minidom.Element.writexml(self, writer, indent='', addindent='', newl='')
+ writer.write(newl)
+
+def doc_createXElement(xdoc, tagName):
+ e = xElement(tagName)
+ e.ownerDocument = xdoc
+ return e
+
+import yaml
+from openerp.tools import yaml_tag # This import is not unused! Do not remove!
+# Please do not override yaml_tag here: modify it in server bin/tools/yaml_tag.py
+
+class base_module_record(osv.Model):
+ _name = "ir.module.record"
+ _columns = {
+
+ }
+ def __init__(self, *args, **kwargs):
+ self.recording = 0
+ self.recording_data = []
+ self.depends = {}
+ super(base_module_record, self).__init__(*args, **kwargs)
+
+ # To Be Improved
+ def _create_id(self, cr, uid, model, data):
+ i = 0
+ while True:
+ try:
+ name = filter(lambda x: x in string.letters, (data.get('name','') or '').lower())
+ except:
+ name=''
+# name=data.get('name','') or ''.lower()
+ val = model.replace('.','_')+'_'+ name + str(i)
+ i+=1
+ if val not in self.ids.values():
+ break
+ return val
+
+ def _get_id(self, cr, uid, model, id):
+ if type(id)==type(()):
+ id=id[0]
+ if (model,id) in self.ids:
+ res_id = self.ids[(model,id)]
+ return res_id, False
+ dt = self.pool.get('ir.model.data')
+ dtids = dt.search(cr, uid, [('model','=',model), ('res_id','=',id)])
+ if not dtids:
+ return False, None
+ obj = dt.browse(cr, uid, dtids[0])
+ self.depends[obj.module] = True
+ return obj.module+'.'+obj.name, obj.noupdate
+
+ def _create_record(self, cr, uid, doc, model, data, record_id, noupdate=False):
+ data_pool = self.pool.get('ir.model.data')
+ model_pool = self.pool.get(model)
+
+ record = doc.createElement('record')
+ record.setAttribute("id", record_id)
+ record.setAttribute("model", model)
+ record_list = [record]
+
+ lids = data_pool.search(cr, uid, [('model','=',model)])
+ res = data_pool.read(cr, uid, lids[:1], ['module'])
+ if res:
+ self.depends[res[0]['module']]=True
+ fields = model_pool.fields_get(cr, uid)
+ for key,val in data.items():
+ if not (val or (fields[key]['type']=='boolean')):
+ continue
+ if (fields[key]['type'] in ('integer','float') or
+ fields[key]['type'] == 'selection' and isinstance(val, int)):
+ field = doc.createElement('field')
+ field.setAttribute("name", key)
+ field.setAttribute("eval", val and str(val) or 'False' )
+ record.appendChild(field)
+ elif fields[key]['type'] in ('boolean',):
+ field = doc.createElement('field')
+ field.setAttribute("name", key)
+ field.setAttribute("eval", val and '1' or '0' )
+ record.appendChild(field)
+ elif fields[key]['type'] in ('many2one',):
+ field = doc.createElement('field')
+ field.setAttribute("name", key)
+ if type(val) in (type(''),type(u'')):
+ id = val
+ else:
+ id,update = self._get_id(cr, uid, fields[key]['relation'], val)
+ noupdate = noupdate or update
+ if not id:
+ relation_pool = self.pool.get(fields[key]['relation'])
+
+ field.setAttribute("model", fields[key]['relation'])
+ fld_nm = relation_pool._rec_name
+ name = relation_pool.read(cr, uid, val,[fld_nm])[fld_nm] or False
+ field.setAttribute("search", str([(str(fld_nm) ,'=', name)]))
+ else:
+ field.setAttribute("ref", id)
+ record.appendChild(field)
+ elif fields[key]['type'] in ('one2many',):
+ for valitem in (val or []):
+ if valitem[0] in (0,1):
+ if key in model_pool._columns:
+ model_pool._columns[key]._fields_id
+ else:
+ model_pool._inherit_fields[key][2]._fields_id
+ if valitem[0] == 0:
+ newid = self._create_id(cr, uid, fields[key]['relation'], valitem[2])
+ valitem[1]=newid
+ else:
+ newid,update = self._get_id(cr, uid, fields[key]['relation'], valitem[1])
+ if not newid:
+ newid = self._create_id(cr, uid, fields[key]['relation'], valitem[2])
+ valitem[1]=newid
+ self.ids[(fields[key]['relation'], valitem[1])] = newid
+
+ childrecord, update = self._create_record(cr, uid, doc, fields[key]['relation'],valitem[2], newid)
+ noupdate = noupdate or update
+ record_list += childrecord
+ else:
+ pass
+ elif fields[key]['type'] in ('many2many',):
+ res = []
+ for valitem in (val or []):
+ if valitem[0]==6:
+ for id2 in valitem[2]:
+ id,update = self._get_id(cr, uid, fields[key]['relation'], id2)
+ self.ids[(fields[key]['relation'],id2)] = id
+ noupdate = noupdate or update
+ res.append(id)
+ field = doc.createElement('field')
+ field.setAttribute("name", key)
+ field.setAttribute("eval", "[(6,0,["+','.join(map(lambda x: "ref('%s')" % (x,), res))+'])]')
+ record.appendChild(field)
+ else:
+ field = doc_createXElement(doc, 'field')
+ field.setAttribute("name", key)
+ field.appendChild(doc.createTextNode(val))
+ record.appendChild(field)
+
+ return record_list, noupdate
+
+ def _create_yaml_record(self, cr, uid, model, data, record_id):
+ record={'model': model, 'id': str(record_id)}
+
+ model_pool = self.pool.get(model)
+ data_pool = self.pool.get('ir.model.data')
+ lids = data_pool.search(cr, uid, [('model','=',model)])
+
+ res = data_pool.read(cr, uid, lids[:1], ['module'])
+ attrs={}
+ if res:
+ self.depends[res[0]['module']]=True
+ fields = model_pool.fields_get(cr, uid)
+ defaults={}
+ try:
+ defaults[model] = model_pool.default_get(cr, uid, data)
+ except:
+ defaults[model]={}
+ for key,val in data.items():
+ if ((key in defaults[model]) and (val == defaults[model][key])) and not(fields[key].get('required',False)):
+ continue
+ if fields[key]['type'] in ('integer','float'):
+ if not val:
+ val=0.0
+ attrs[key] = val
+ elif not (val or (fields[key]['type']=='function')):
+ continue
+ elif fields[key]['type'] in ('boolean',):
+ if not val:
+ continue
+ attrs[key] = val
+ elif fields[key]['type'] in ('many2one',):
+ if type(val) in (type(''), type(u'')):
+ id = val
+ else:
+ id, update = self._get_id(cr, uid, fields[key]['relation'], val)
+ attrs[key] = str(id)
+ elif fields[key]['type'] in ('one2many',):
+ items=[[]]
+ for valitem in (val or []):
+ if valitem[0] in (0,1):
+ if key in model_pool._columns:
+ fname = model_pool._columns[key]._fields_id
+ else:
+ fname = model_pool._inherit_fields[key][2]._fields_id
+ del valitem[2][fname] #delete parent_field from child's fields list
+
+ childrecord = self._create_yaml_record(cr, uid, fields[key]['relation'],valitem[2], None)
+ items[0].append(childrecord['attrs'])
+ attrs[key] = items
+ elif fields[key]['type'] in ('many2many',):
+ if (key in defaults[model]) and (val[0][2] == defaults[model][key]):
+ continue
+ res = []
+ for valitem in (val or []):
+ if valitem[0]==6:
+ for id2 in valitem[2]:
+ id,update = self._get_id(cr, uid, fields[key]['relation'], id2)
+ self.ids[(fields[key]['relation'],id2)] = id
+ res.append(str(id))
+ m2m=[res]
+ if m2m[0]:
+ attrs[key] = m2m
+ else:
+ try:
+ attrs[key]=str(val)
+ except:
+ attrs[key]=tools.ustr(val)
+ attrs[key]=attrs[key].replace('"','\'')
+ record['attrs'] = attrs
+ return record
+
+ def get_copy_data(self, cr, uid, model, id, result):
+ res = []
+ obj=self.pool.get(model)
+ data=obj.read(cr, uid,[id])
+ if type(data)==type([]):
+ del data[0]['id']
+ data=data[0]
+ else:
+ del data['id']
+
+ mod_fields = obj.fields_get(cr, uid)
+ for f in filter(lambda a: isinstance(obj._columns[a], fields.function)\
+ and (not obj._columns[a].store),obj._columns):
+ del data[f]
+
+ for key,val in data.items():
+ if result.has_key(key):
+ continue
+ if mod_fields[key]['type'] == 'many2one':
+ if type(data[key])==type(True) or type(data[key])==type(1):
+ result[key]=data[key]
+ elif not data[key]:
+ result[key] = False
+ else:
+ result[key]=data[key][0]
+
+ elif mod_fields[key]['type'] in ('one2many',):
+# continue # due to this start stop recording will not record one2many field
+ rel = mod_fields[key]['relation']
+ if rel == 'mail.message':
+ continue
+ if len(data[key]):
+ res1=[]
+ for rel_id in data[key]:
+ res=[0,0]
+ res.append(self.get_copy_data(cr, uid,rel,rel_id,{}))
+ res1.append(res)
+ result[key]=res1
+ else:
+ result[key]=data[key]
+
+ elif mod_fields[key]['type'] == 'many2many':
+ result[key]=[(6,0,data[key])]
+
+ else:
+ result[key]=data[key]
+ for k,v in obj._inherits.items():
+ del result[v]
+ return result
+
+ def _create_function(self, cr, uid, doc, model, name, record_id):
+ record = doc.createElement('function')
+ record.setAttribute("name", name)
+ record.setAttribute("model", model)
+ record_list = [record]
+
+ value = doc.createElement('value')
+ value.setAttribute('eval', '[ref(\'%s\')]' % (record_id, ))
+ value.setAttribute('model', model)
+
+ record.appendChild(value)
+ return record_list, False
+
+ def _generate_object_xml(self, cr, uid, rec, recv, doc, result=None):
+ record_list = []
+ noupdate = False
+ if rec[3]=='write':
+ for id in rec[4]:
+ id,update = self._get_id(cr, uid, rec[2], id)
+ noupdate = noupdate or update
+ if not id:
+ continue
+ record,update = self._create_record(cr, uid, doc, rec[2], rec[5], id)
+ noupdate = noupdate or update
+ record_list += record
+
+ elif rec[4] in ('menu_create',):
+ for id in rec[5]:
+ id,update = self._get_id(cr, uid, rec[3], id)
+ noupdate = noupdate or update
+ if not id:
+ continue
+ record,update = self._create_function(cr, uid, doc, rec[3], rec[4], id)
+ noupdate = noupdate or update
+ record_list += record
+
+ elif rec[3]=='create':
+ id = self._create_id(cr, uid, rec[2],rec[4])
+ record,noupdate = self._create_record(cr, uid, doc, rec[2], rec[4], id)
+ self.ids[(rec[2], result)] = id
+ record_list += record
+
+ elif rec[3]=='copy':
+ data=self.get_copy_data(cr,uid,rec[2],rec[4],rec[5])
+ copy_rec=(rec[0],rec[1],rec[2],rec[3],rec[4],data,rec[5])
+ rec=copy_rec
+ rec_data=[(self.recording_data[0][0],rec,self.recording_data[0][2],self.recording_data[0][3])]
+ self.recording_data=rec_data
+ id = self._create_id(cr, uid, rec[2],rec[5])
+ record,noupdate = self._create_record(cr, uid, doc, rec[2], rec[5], id)
+ self.ids[(rec[2], result)] = id
+ record_list += record
+
+ return record_list,noupdate
+
+ def _generate_object_yaml(self, cr, uid, rec, result=None):
+ if self.mode=="create":
+ yml_id = self._create_id(cr, uid, rec[2],rec[4])
+ self.ids[(rec[2], result)] = yml_id
+ record = self._create_yaml_record(cr, uid, rec[2], rec[4], yml_id)
+ return record
+ if self.mode=="workflow":
+ id,update = self._get_id(cr, uid, rec[2], rec[4])
+ data = {}
+ data['model'] = rec[2]
+ data['action'] = rec[3]
+ data['ref'] = id
+ return data
+ if self.mode=="write":
+ id,update = self._get_id(cr, uid, rec[2],rec[4][0])
+ record = self._create_yaml_record(cr, uid, rec[2], rec[5], id)
+ return record
+ data=self.get_copy_data(cr,uid,rec[2],rec[4],rec[5])
+ copy_rec=(rec[0],rec[1],rec[2],rec[3],rec[4],data,rec[5])
+ rec=copy_rec
+ rec_data=[(self.recording_data[0][0],rec,self.recording_data[0][2],self.recording_data[0][3])]
+ self.recording_data=rec_data
+ id = self._create_id(cr, uid, rec[2],rec[5])
+ record = self._create_yaml_record(cr, uid, str(rec[2]), rec[5], id)
+ self.ids[(rec[2], result)] = id
+ return record
+
+ def _generate_function_yaml(self, cr, uid, args):
+ db, uid, model, action, ids, context = args
+ temp_context = context.copy()
+ active_id = temp_context['active_id']
+ active_model = temp_context['active_model']
+ active_id, update = self._get_id(cr, uid, active_model, active_id)
+ if not active_id:
+ active_id = 1
+ rec_id, noupdate = self._get_id(cr, uid, model, ids[0])
+ temp_context['active_id'] = "ref('%s')"%unicode(active_id)
+ temp_context['active_ids'][0] = "ref('%s')"%str(active_id)
+ function={}
+ function['model'] = model
+ function['action'] = action
+ attrs = "self.%s(cr, uid, [ref('%s')], {" %(action, rec_id, )
+ for k, v in temp_context.iteritems():
+ if isinstance(v, str):
+ f= "'"+k+"': "+"'%s'"%v + ", "
+ else:
+ v=str(v).replace('"', '')
+ f= "'"+k+"': "+"%s"%v + ", "
+ attrs = attrs + f
+ attrs=str(attrs)+'})'
+ function['attrs'] = attrs
+ return function
+
+ def _generate_assert_xml(self, rec, doc):
+ pass
+
+ def generate_xml(self, cr, uid):
+ # Create the minidom document
+ if len(self.recording_data):
+ self.ids = {}
+ doc = minidom.Document()
+ terp = doc.createElement("openerp")
+ doc.appendChild(terp)
+ for rec in self.recording_data:
+ if rec[0]=='workflow':
+ rec_id,noupdate = self._get_id(cr, uid, rec[1][2], rec[1][4])
+ if not rec_id:
+ continue
+ data = doc.createElement("data")
+ terp.appendChild(data)
+ wkf = doc.createElement('workflow')
+ data.appendChild(wkf)
+ wkf.setAttribute("model", rec[1][2])
+ wkf.setAttribute("action", rec[1][3])
+ if noupdate:
+ data.setAttribute("noupdate", "1")
+ wkf.setAttribute("ref", rec_id)
+ if rec[0]=='query':
+ res_list,noupdate = self._generate_object_xml(cr, uid, rec[1], rec[2], doc, rec[3])
+ data = doc.createElement("data")
+ if noupdate:
+ data.setAttribute("noupdate", "1")
+ if res_list:
+ terp.appendChild(data)
+ for res in res_list:
+ data.appendChild(res)
+ elif rec[0]=='assert':
+ pass
+ return doc.toprettyxml(indent="\t").encode('utf-8')
+
+ def generate_yaml(self, cr, uid):
+ self.ids = {}
+ if len(self.recording_data):
+ yaml_file='''\n'''
+
+ for rec in self.recording_data:
+ if rec[1][3] == 'create':
+ self.mode="create"
+ elif rec[1][3] == 'write':
+ self.mode="write"
+ elif rec[1][3] == 'copy':
+ self.mode="copy"
+ elif rec[0] == 'workflow':
+ self.mode="workflow"
+ elif rec[0] == 'osv_memory_action':
+ self.mode='osv_memory_action'
+ else:
+ continue
+ if self.mode == "workflow":
+ record = self._generate_object_yaml(cr, uid, rec[1],rec[0])
+ yaml_file += "!comment Performing a workflow action %s on module %s"%(record['action'], record['model']) + '''\n'''
+ object = yaml.load(unicode('''\n !workflow %s \n'''%record,'iso-8859-1'))
+ yaml_file += str(object) + '''\n\n'''
+ elif self.mode == 'osv_memory_action':
+ osv_action = self._generate_function_yaml(cr, uid, rec[1])
+ yaml_file += "!comment Performing an osv_memory action %s on module %s"%(osv_action['action'], osv_action['model']) + '''\n'''
+ osv_action = yaml.load(unicode('''\n !python %s \n'''%osv_action,'iso-8859-1'))
+ yaml_file += str(osv_action) + '''\n'''
+ attrs = yaml.dump(osv_action.attrs, default_flow_style=False)
+ attrs = attrs.replace("''", '"')
+ attrs = attrs.replace("'", '')
+ yaml_file += attrs + '''\n\n'''
+ else:
+ record = self._generate_object_yaml(cr, uid, rec[1], rec[3])
+ if self.mode == "create" or self.mode == "copy":
+ yaml_file += "!comment Creating a %s record"%(record['model']) + '''\n'''
+ else:
+ yaml_file += "!comment Modifying a %s record"%(record['model']) + '''\n'''
+ object = yaml.load(unicode('''\n !record %s \n'''%record,'iso-8859-1'))
+ yaml_file += str(object) + '''\n'''
+ attrs = yaml.dump(object.attrs, default_flow_style=False)
+ yaml_file += attrs + '''\n\n'''
+
+ yaml_result=''''''
+ for line in yaml_file.split('\n'):
+ line=line.replace("''","'")
+ if (line.find('!record') == 0) or (line.find('!workflow') == 0) or (line.find('!python') == 0):
+ line = "- \n" + " " + line
+ elif line.find('!comment') == 0:
+ line=line.replace('!comment','- \n ')
+ elif line.find('- -') != -1:
+ line=line.replace('- -',' -')
+ line = " " + line
+ else:
+ line = " " + line
+ yaml_result += line + '''\n'''
+ return yaml_result
+
+base_module_record()
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
=== added directory 'base_module_record/images'
=== added file 'base_module_record/images/base_module_record1.jpeg'
Binary 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'
Binary 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'
Binary 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 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_ir_module_record,ir.module.record,model_ir_module_record,base.group_system,1,1,1,1
=== 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 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from . import base_module_save
+from . import base_module_record_objects
+from . import base_module_record_data
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
=== 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 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from openerp.osv import orm, fields, osv
+from openerp import tools
+from openerp.tools.translate import _
+
+import time
+
+class base_module_data(orm.TransientModel):
+ _name = 'base.module.data'
+ _description = "Base Module Data"
+
+ _columns = {
+ 'check_date': fields.datetime('Record from Date', required=True),
+ 'objects': fields.many2many('ir.model', 'base_module_record_model_rel', 'objects', 'model_id', 'Objects'),
+ 'filter_cond': fields.selection([('created', 'Created'), ('modified', 'Modified'), ('created_modified', 'Created & Modified')], 'Records only', required=True),
+ 'info_yaml': fields.boolean('YAML'),
+ }
+
+ def _get_default_objects(self, cr, uid, context=None):
+ names = ('ir.ui.view', 'ir.ui.menu', 'ir.model', 'ir.model.fields', 'ir.model.access',
+ 'res.partner', 'res.partner.category', 'workflow',
+ 'workflow.activity', 'workflow.transition', 'ir.actions.server', 'ir.server.object.lines')
+ return self.pool.get('ir.model').search(cr, uid, [('model', 'in', names)])
+
+ _defaults = {
+ 'check_date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
+ 'objects': _get_default_objects,
+ 'filter_cond': 'created',
+ }
+
+ def _create_xml(self, cr, uid, data, context=None):
+ mod = self.pool.get('ir.module.record')
+ res_xml = mod.generate_xml(cr, uid)
+ return {'res_text': res_xml }
+
+ def _create_yaml(self, cr, uid, data, context=None):
+ mod = self.pool.get('ir.module.record')
+ res_xml = mod.generate_yaml(cr, uid)
+ return { 'res_text': res_xml }
+
+ def record_objects(self, cr, uid, ids, context=None):
+ data = self.read(cr, uid, ids, [], context=context)[0]
+ check_date = data['check_date']
+ filter = data['filter_cond']
+ user = (self.pool.get('res.users').browse(cr, uid, uid)).login
+ mod = self.pool.get('ir.module.record')
+ mod_obj = self.pool.get('ir.model')
+ mod.recording_data = []
+ for id in data['objects']:
+ obj_name=(mod_obj.browse(cr, uid, id)).model
+ obj_pool=self.pool.get(obj_name)
+ if filter =='created':
+ search_condition =[('create_date','>',check_date)]
+ elif filter =='modified':
+ search_condition =[('write_date','>',check_date)]
+ elif filter =='created_modified':
+ search_condition =['|',('create_date','>',check_date),('write_date','>',check_date)]
+ if '_log_access' in dir(obj_pool):
+ if not (obj_pool._log_access):
+ search_condition=[]
+ if '_auto' in dir(obj_pool):
+ if not obj_pool._auto:
+ continue
+ search_ids=obj_pool.search(cr,uid,search_condition)
+ for s_id in search_ids:
+ args=(cr.dbname,uid,obj_name,'copy', s_id,{}, context)
+ mod.recording_data.append(('query', args, {}, s_id))
+
+ mod_obj = self.pool.get('ir.model.data')
+ if len(mod.recording_data):
+ if data['info_yaml']:
+ res=self._create_yaml(cr, uid, data, context)
+ else:
+ res=self._create_xml(cr, uid, data, context)
+ model_data_ids = mod_obj.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'module_create_xml_view')], context=context)
+ resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
+ return {
+ 'name': _('Data Recording'),
+ 'context': {'default_res_text': tools.ustr(res['res_text'])},
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'base.module.record.data',
+ 'views': [(resource_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+
+ model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'module_recording_message_view')], context=context)
+ resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
+ return {
+ 'name': _('Module Recording'),
+ 'context': context,
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'base.module.record.objects',
+ 'views': [(resource_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+
+base_module_data()
+
+class base_module_record_data(orm.TransientModel):
+ _name = 'base.module.record.data'
+ _description = "Base Module Record Data"
+
+ _columns = {
+ 'res_text': fields.text('Result'),
+ }
+
+base_module_record_data()
+
+#vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+
+ <record id="base_module_record_data_view" model="ir.ui.view">
+ <field name="name">base_module_record_data</field>
+ <field name="model">base.module.data</field>
+ <field name="arch" type="xml">
+ <form string="Data Recording" version="7.0">
+ <sheet>
+ <group>
+ <field name="check_date"/>
+ <newline/>
+ <field name="filter_cond"/>
+ <separator string="Choose objects to record" colspan="4"/>
+ <field name="objects" colspan="4" nolabel="1"/>
+ </group>
+ <group><field name="info_yaml"/></group>
+ <footer>
+ <button icon="gtk-cancel" string="Cancel" special="cancel"/>
+ <button name="record_objects" icon="gtk-ok" string="Record" type="object"/>
+ </footer>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="action_base_module_record_data">
+ <field name="name">Export Customizations as Data</field>
+ <field name="res_model">base.module.data</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ <field name="view_id" ref="base_module_record_data_view"/>
+ </record>
+
+
+ <menuitem
+ parent="menu_wizard_base_mod_rec"
+ name="Export Customizations As Data file"
+ action="action_base_module_record_data"
+ id="menu_wizard_base_module_record_data"/>
+
+ <act_window
+ id="act_base_module_record_data"
+ name="Export Customizations As Data File"
+ res_model="base.module.data"
+ src_model="ir.module.module"
+ view_mode="form"
+ target="new"
+ multi="True"
+ key2="client_action_multi"/>
+
+ <record id="module_create_xml_view" model="ir.ui.view">
+ <field name="name">module.create.xml.form</field>
+ <field name="model">base.module.record.data</field>
+ <field name="arch" type="xml">
+ <form string="Data Recording" version="7.0">
+ <sheet>
+ <group>
+ <separator string="Result, paste this to your module's xml" colspan="4"/>
+ <field name="res_text" nolabel="1" colspan="4"/>
+ </group>
+ <footer>
+ <button icon="gtk-close" string="Close" special="cancel"/>
+ </footer>
+ </sheet>
+ </form>
+ </field>
+ </record>
+ </data>
+</openerp>
=== 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+
+ <record id="base_module_record_objects_view" model="ir.ui.view">
+ <field name="name">base_module_record_objects</field>
+ <field name="model">base.module.record</field>
+ <field name="arch" type="xml">
+ <form string="Objects Recording" version="7.0">
+ <sheet>
+ <group>
+ <field name="check_date"/>
+ <newline/>
+ <field name="filter_cond"/>
+ <separator string="Choose objects to record" colspan="4"/>
+ <field name="objects" colspan="4" nolabel="1"/>
+ </group>
+ <group><field name="info_yaml"/></group>
+ <separator colspan="4"/>
+ <footer>
+ <button icon="gtk-cancel" string="Cancel" special="cancel"/>
+ <button name="record_objects" icon="gtk-ok" string="Record" type="object"/>
+ </footer>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="action_base_module_record_objects">
+ <field name="name">Export Customizations as a Module</field>
+ <field name="res_model">base.module.record</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ <field name="view_id" ref="base_module_record_objects_view"/>
+ </record>
+
+ <menuitem
+ parent="base.menu_custom"
+ name="Module Creation"
+ id="menu_wizard_base_mod_rec"/>
+<!-- groups="base.group_extended"/> -->
+
+ <menuitem
+ parent="menu_wizard_base_mod_rec"
+ name="Export Customizations As a Module"
+ action="action_base_module_record_objects"
+ id="menu_wizard_base_module_record_objects"/>
+
+ <act_window
+ id="act_base_module_record_objects"
+ name="Export Customizations As a Module"
+ res_model="base.module.record"
+ src_model="ir.module.module"
+ view_mode="form"
+ target="new"
+ multi="True"
+ key2="client_action_multi"/>
+
+ <record id="module_create_form_view" model="ir.ui.view">
+ <field name="name">module.create.form</field>
+ <field name="model">base.module.record.objects</field>
+ <field name="arch" type="xml">
+ <form string="Module Recording" version="7.0">
+ <sheet>
+ <group>
+ <separator string="Module successfully created !" colspan="4"/>
+ <field name="module_filename"/>
+ <newline/>
+ <field name="module_file"/>
+ </group>
+ <separator string="Information" colspan="4"/>
+ <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"/>
+ <label string="Thanks in advance for your contribution." colspan="4" align="0.0"/>
+ <separator colspan="4"/>
+ <footer>
+ <button icon="gtk-close" string="Close" special="cancel"/>
+ </footer>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="action_module_created">
+ <field name="name">Module Recording</field>
+ <field name="res_model">base.module.record.objects</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ <field name="view_id" ref="module_create_form_view"/>
+ </record>
+
+ <record id="info_start_form_view" model="ir.ui.view">
+ <field name="name">info.start.form.view</field>
+ <field name="model">base.module.record.objects</field>
+ <field name="arch" type="xml">
+ <form string="Module Recording" version="7.0">
+ <sheet>
+ <group>
+ <separator string="Module Information" colspan="4"/>
+ <field name="name"/>
+ <field name="directory_name"/>
+ <field name="version"/>
+ <field name="author"/>
+ <field name="website"/>
+ <field name="category"/>
+ <field name="data_kind"/>
+ <newline/>
+ <field name="description"/>
+ <separator colspan="4"/>
+ <footer>
+ <button icon="gtk-cancel" string="Cancel" special="cancel"/>
+ <button string="Continue" name="inter_call" type="object" icon="gtk-ok"/>
+ </footer>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="module_recording_message_view" model="ir.ui.view">
+ <field name="name">module_recording_message</field>
+ <field name="model">base.module.record.objects</field>
+ <field name="arch" type="xml">
+ <form string="Module Recording" version="7.0">
+ <sheet>
+ <label string="Thanks For using Module Recorder" colspan="4" align="0.0"/>
+ <separator string="" colspan="4"/>
+ <footer>
+ <button icon="gtk-ok" string="OK" special="cancel"/>
+ </footer>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="yml_save_form_view" model="ir.ui.view">
+ <field name="name">yml.save.form</field>
+ <field name="model">base.module.record.objects</field>
+ <field name="arch" type="xml">
+ <form string="Module Recording" version="7.0">
+ <sheet>
+ <separator string="YAML file successfully created !" colspan="4"/>
+ <newline/>
+ <field name="yaml_file" filename="module_filename"/>
+ <separator colspan="4"/>
+ <footer>
+ <button icon="gtk-close" string="Close" special="cancel"/>
+ </footer>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ </data>
+</openerp>
=== 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 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from openerp.osv import orm, fields, osv
+from openerp import tools
+from openerp.tools.translate import _
+from . import base_module_save
+
+import time
+
+class base_module_record(orm.TransientModel):
+ _name = 'base.module.record'
+ _description = "Base Module Record"
+
+ _columns = {
+ 'check_date': fields.datetime('Record from Date', required=True),
+ 'objects': fields.many2many('ir.model', 'base_module_record_object_rel', 'objects', 'model_id', 'Objects'),
+ 'filter_cond': fields.selection([('created', 'Created'), ('modified', 'Modified'), ('created_modified', 'Created & Modified')], 'Records only', required=True),
+ 'info_yaml': fields.boolean('YAML'),
+ }
+
+ def _get_default_objects(self, cr, uid, context=None):
+ names = ('ir.ui.view', 'ir.ui.menu', 'ir.model', 'ir.model.fields', 'ir.model.access',
+ 'res.partner', 'res.partner.address', 'res.partner.category', 'workflow',
+ 'workflow.activity', 'workflow.transition', 'ir.actions.server', 'ir.server.object.lines')
+ return self.pool.get('ir.model').search(cr, uid, [('model', 'in', names)])
+
+ _defaults = {
+ 'check_date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
+ 'objects': _get_default_objects,
+ 'filter_cond': 'created',
+ }
+
+ def record_objects(self, cr, uid, ids, context=None):
+ data = self.read(cr, uid, ids, [], context=context)[0]
+ check_date=data['check_date']
+ filter=data['filter_cond']
+ user=(self.pool.get('res.users').browse(cr,uid,uid)).login
+ mod = self.pool.get('ir.module.record')
+ mod_obj = self.pool.get('ir.model')
+ mod.recording_data = []
+ for id in data['objects']:
+ obj_name=(mod_obj.browse(cr,uid,id)).model
+ obj_pool=self.pool.get(obj_name)
+ if filter =='created':
+ search_condition =[('create_date', '>', check_date)]
+ elif filter =='modified':
+ search_condition =[('write_date', '>', check_date)]
+ elif filter =='created_modified':
+ search_condition =['|',('create_date', '>', check_date), ('write_date', '>', check_date)]
+ if '_log_access' in dir(obj_pool):
+ if not (obj_pool._log_access):
+ search_condition=[]
+ if '_auto' in dir(obj_pool):
+ if not obj_pool._auto:
+ continue
+ search_ids = obj_pool.search(cr,uid,search_condition)
+ for s_id in search_ids:
+ args=(cr.dbname, uid,obj_name, 'copy', s_id,{},context)
+ mod.recording_data.append(('query', args, {}, s_id))
+
+ mod_obj = self.pool.get('ir.model.data')
+ if len(mod.recording_data):
+ if data['info_yaml']:
+ mod = self.pool.get('ir.module.record')
+ res=base_module_save._create_yaml(self, cr, uid, data, context)
+ model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'yml_save_form_view')], context=context)
+ resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
+ return {
+ 'name': _('Message'),
+ 'context': {'default_yaml_file': tools.ustr(res['yaml_file'])},
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'base.module.record.objects',
+ 'views': [(resource_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+ else:
+ model_data_ids = mod_obj.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'info_start_form_view')], context=context)
+ resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
+ return {
+ 'name': _('Message'),
+ 'context': context,
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'base.module.record.objects',
+ 'views': [(resource_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+
+ model_data_ids = mod_obj.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'module_recording_message_view')], context=context)
+ resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
+ return {
+ 'name': _('Message'),
+ 'context': context,
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'base.module.record.objects',
+ 'views': [(resource_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+
+base_module_record()
+
+class base_module_record_objects(orm.TransientModel):
+ _name = 'base.module.record.objects'
+ _description = "Base Module Record Objects"
+
+ def inter_call(self,cr,uid,data,context=None):
+ res=base_module_save._create_module(self, cr, uid, data, context)
+ mod_obj = self.pool.get('ir.model.data')
+ model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'module_create_form_view')], context=context)
+ resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
+ context.update(res)
+
+ return {
+ 'name': _('Message'),
+ 'context': {
+ 'default_module_filename': tools.ustr(res['module_filename']),
+ 'default_module_file': tools.ustr(res['module_file']),
+ },
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'base.module.record.objects',
+ 'views': [(resource_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+
+ _columns = {
+ 'name': fields.char('Module Name', size=64, required=True),
+ 'directory_name': fields.char('Directory Name', size=32, required=True),
+ 'version': fields.char('Version', size=16, required=True),
+ 'author': fields.char('Author', size=64, required=True),
+ 'category': fields.char('Category', size=64, required=True),
+ 'website': fields.char('Documentation URL', size=64, required=True),
+ 'description': fields.text('Full Description', required=True),
+ 'data_kind': fields.selection([('demo', 'Demo Data'), ('update', 'Normal Data')], 'Type of Data', required=True),
+ 'module_file': fields.binary('Module .zip File', filename="module_filename"),
+ 'module_filename': fields.char('Filename', size=64),
+ 'yaml_file': fields.binary('Module .zip File'),
+ }
+ _defaults = {
+ 'author': 'OpenERP SA',
+ 'category': 'Vertical Modules/Parametrization',
+ 'website': 'http://www.openerp.com',
+ 'data_kind': 'update',
+ }
+
+base_module_record_objects()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
=== 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 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2012-Today Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import zipfile
+import StringIO
+import base64
+
+from openerp import tools
+from openerp.tools.translate import _
+from openerp.osv import orm, fields, osv
+
+
+def _create_yaml(self, cr, uid, data, context=None):
+ mod = self.pool.get('ir.module.record')
+ try:
+ res_xml = mod.generate_yaml(cr, uid)
+ except Exception, e:
+ raise osv.except_osv(_('Error'),_(str(e)))
+ return {
+ 'yaml_file': base64.encodestring(res_xml),
+}
+
+def _create_module(self, cr, uid, ids, context=None):
+ mod = self.pool.get('ir.module.record')
+ res_xml = mod.generate_xml(cr, uid)
+ data = self.read(cr, uid, ids, [], context=context)[0]
+ s = StringIO.StringIO()
+ zip = zipfile.ZipFile(s, 'w')
+ dname = data['directory_name']
+ data['update_name'] = ''
+ data['demo_name'] = ''
+ if ['data_kind'] =='demo':
+ data['demo_name'] = '"%(directory_name)s_data.xml"' % data
+ else:
+ data['update_name'] = '"%(directory_name)s_data.xml"' % data
+ data['depends'] = ','.join(map(lambda x: '"'+x+'"', mod.depends.keys()))
+ _terp = """{
+ "name" : "%(name)s",
+ "version" : "%(version)s",
+ "author" : "%(author)s",
+ "website" : "%(website)s",
+ "category" : "%(category)s",
+ "description": \"\"\"%(description)s\"\"\",
+ "depends" : [%(depends)s],
+ "init_xml" : [ ],
+ "demo_xml" : [ %(demo_name)s],
+ "update_xml" : [%(update_name)s],
+ "installable": True
+} """ % data
+ filewrite = {
+ '__init__.py':'#\n# Generated by the OpenERP module recorder !\n#\n',
+ '__openerp__.py':_terp,
+ dname+'_data.xml': res_xml
+ }
+ for name,datastr in filewrite.items():
+ info = zipfile.ZipInfo(dname+'/'+name)
+ info.compress_type = zipfile.ZIP_DEFLATED
+ info.external_attr = 2175008768
+ if not datastr:
+ datastr = ''
+ zip.writestr(info, datastr)
+ zip.close()
+ return {
+ 'module_file': base64.encodestring(s.getvalue()),
+ 'module_filename': data['directory_name']+'-'+data['version']+'.zip'
+ }
+
+class base_module_save(orm.TransientModel):
+ _name = 'base.module.save'
+ _description = "Base Module Save"
+
+ def default_get(self, cr, uid, fields, context=None):
+ mod = self.pool.get('ir.module.record')
+ result = {}
+ info = "Details of "+str(len(mod.recording_data))+" Operation(s):\n\n"
+ res = super(base_module_save, self).default_get(cr, uid, fields, context=context)
+ for line in mod.recording_data:
+ result.setdefault(line[0],{})
+ result[line[0]].setdefault(line[1][3], {})
+ result[line[0]][line[1][3]].setdefault(line[1][3], 0)
+ result[line[0]][line[1][3]][line[1][3]]+=1
+ for key1,val1 in result.items():
+ info+=key1+"\n"
+ for key2,val2 in val1.items():
+ info+="\t"+key2+"\n"
+ for key3,val3 in val2.items():
+ info+="\t\t"+key3+" : "+str(val3)+"\n"
+ if 'info_text' in fields:
+ res.update({'info_text': info})
+ if 'info_status' in fields:
+ info_status = mod.recording and 'record' or 'no'
+ res.update({'info_status': info_status})
+ return res
+
+ _columns = {
+ 'info_text': fields.text('Information', readonly=True),
+ 'info_status': fields.selection([('no', 'Not Recording'),('record', 'Recording')], 'Status', readonly=True),
+ 'info_yaml': fields.boolean('YAML'),
+ }
+
+ def record_save(self, cr, uid, ids, context=None):
+ data = self.read(cr, uid, ids, [], context=context)[0]
+ mod = self.pool.get('ir.module.record')
+ mod_obj = self.pool.get('ir.model.data')
+ if len(mod.recording_data):
+ if data['info_yaml']:
+ mod = self.pool.get('ir.module.record')
+ res=_create_yaml(self, cr, uid, data, context)
+ model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'yml_save_form_view')], context=context)
+ resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
+ return {
+ 'name': _('Message'),
+ 'context': {
+ 'default_yaml_file': tools.ustr(res['yaml_file']),
+ },
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'base.module.record.objects',
+ 'views': [(resource_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+ else:
+ model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'info_start_form_view')], context=context)
+ resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
+ return {
+ 'name': _('Message'),
+ 'context': context,
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'base.module.record.objects',
+ 'views': [(resource_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+ model_data_ids = mod_obj.search(cr, uid,[('model', '=', 'ir.ui.view'), ('name', '=', 'module_recording_message_view')], context=context)
+ resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
+
+ return {
+ 'name': _('Message'),
+ 'context': context,
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'base.module.record.objects',
+ 'views': [(resource_id, 'form')],
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ }
+
+base_module_save()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
=== 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+ <data>
+
+ <record id="base_module_save_view" model="ir.ui.view">
+ <field name="name">base_module_save</field>
+ <field name="model">base.module.save</field>
+ <field name="arch" type="xml">
+ <form string="Module Recording" version="7.0">
+ <sheet>
+ <separator string="Recording Information" colspan="4"/>
+ <field name="info_status"/>
+ <field name="info_text" colspan="4" nolabel="1"/>
+ <field name="info_yaml" colspan="4"/>
+ <separator colspan="4"/>
+ <group colspan="4" col="2">
+ <button icon="gtk-cancel" string="Cancel" special="cancel"/>
+ <button name="record_save" icon="gtk-ok" string="Continue" type="object"/>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="action_base_module_save">
+ <field name="name">Publish as module</field>
+ <field name="res_model">base.module.save</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form</field>
+ <field name="target">new</field>
+ <field name="view_id" ref="base_module_save_view"/>
+ </record>
+
+ <menuitem
+ parent="menu_wizard_base_mod_rec"
+ name="Publish as Module"
+ action="action_base_module_save"
+ id="menu_wizard_base_module_save"/>
+
+ <act_window
+ id="act_base_module_save"
+ name="Publish as Module"
+ res_model="base.module.save"
+ src_model="ir.module.module"
+ view_mode="form"
+ target="new"
+ multi="True"
+ key2="client_action_multi"/>
+
+ </data>
+</openerp>
Follow ups