← Back to team overview

openerp-community-reviewer team mailing list archive

[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