[ADD] add wizard to import zipped module
This commit is contained in:
parent
b27a3351af
commit
41147025b8
|
@ -13,7 +13,7 @@ for customization purpose.
|
||||||
'depends': ['web'],
|
'depends': ['web'],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'auto_install': False,
|
'auto_install': False,
|
||||||
'data': [],
|
'data': ['views/base_import_module.xml'],
|
||||||
'qweb': [],
|
'qweb': [],
|
||||||
'test': [],
|
'test': [],
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import functools
|
import functools
|
||||||
import os
|
|
||||||
import zipfile
|
|
||||||
from os.path import join as opj
|
|
||||||
|
|
||||||
import openerp
|
import openerp
|
||||||
from openerp.http import Controller, route, request, Response
|
from openerp.http import Controller, route, request, Response
|
||||||
|
|
||||||
MAX_FILE_SIZE = 100 * 1024 * 1024 # in megabytes
|
|
||||||
|
|
||||||
def webservice(f):
|
def webservice(f):
|
||||||
@functools.wraps(f)
|
@functools.wraps(f)
|
||||||
def wrap(*args, **kw):
|
def wrap(*args, **kw):
|
||||||
|
@ -42,32 +36,4 @@ class ImportModule(Controller):
|
||||||
@webservice
|
@webservice
|
||||||
def upload(self, mod_file=None, **kw):
|
def upload(self, mod_file=None, **kw):
|
||||||
self.check_user()
|
self.check_user()
|
||||||
imm = request.registry['ir.module.module']
|
return request.registry['ir.module.module'].import_zipfile(request.cr, request.uid, mod_file, context=request.context)
|
||||||
|
|
||||||
if not mod_file:
|
|
||||||
raise Exception("No file sent.")
|
|
||||||
if not zipfile.is_zipfile(mod_file):
|
|
||||||
raise Exception("Not a zipfile.")
|
|
||||||
|
|
||||||
success = []
|
|
||||||
errors = dict()
|
|
||||||
with zipfile.ZipFile(mod_file, "r") as z:
|
|
||||||
for zf in z.filelist:
|
|
||||||
if zf.file_size > MAX_FILE_SIZE:
|
|
||||||
raise Exception("File '%s' exceed maximum allowed file size" % zf.filename)
|
|
||||||
|
|
||||||
with openerp.tools.osutil.tempdir() as module_dir:
|
|
||||||
z.extractall(module_dir)
|
|
||||||
dirs = [d for d in os.listdir(module_dir) if os.path.isdir(opj(module_dir, d))]
|
|
||||||
for mod_name in dirs:
|
|
||||||
try:
|
|
||||||
# assert mod_name.startswith('theme_')
|
|
||||||
path = opj(module_dir, mod_name)
|
|
||||||
imm.import_module(request.cr, request.uid, mod_name, path, context=request.context)
|
|
||||||
success.append(mod_name)
|
|
||||||
except Exception, e:
|
|
||||||
errors[mod_name] = str(e)
|
|
||||||
r = ["Successfully imported module '%s'" % mod for mod in success]
|
|
||||||
for mod, error in errors.items():
|
|
||||||
r.append("Error while importing module '%s': %r" % (mod, error))
|
|
||||||
return '\n'.join(r)
|
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import ir_module
|
import ir_module
|
||||||
|
import base_import_module
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
import base64
|
||||||
|
from StringIO import StringIO
|
||||||
|
from io import BytesIO
|
||||||
|
from openerp.osv import osv, fields
|
||||||
|
|
||||||
|
class base_import_module(osv.TransientModel):
|
||||||
|
""" Import Module """
|
||||||
|
_name = "base.import.module"
|
||||||
|
_description = "Import Module"
|
||||||
|
|
||||||
|
_columns = {
|
||||||
|
'module_file': fields.binary('Module .ZIP file', required=True),
|
||||||
|
'state':fields.selection([('init','init'),('done','done')], 'Status', readonly=True),
|
||||||
|
'module_name': fields.char('Module Name', size=128),
|
||||||
|
}
|
||||||
|
|
||||||
|
_defaults = {
|
||||||
|
'state': 'init',
|
||||||
|
}
|
||||||
|
|
||||||
|
def import_module(self, cr, uid, ids, context=None):
|
||||||
|
module_obj = self.pool.get('ir.module.module')
|
||||||
|
data = self.browse(cr, uid, ids[0] , context=context)
|
||||||
|
zip_data = base64.decodestring(data.module_file)
|
||||||
|
fp = BytesIO()
|
||||||
|
fp.write(zip_data)
|
||||||
|
module_obj.import_zipfile(cr, uid, fp, context=context)
|
||||||
|
fp.close()
|
||||||
|
self.write(cr, uid, ids, {'state': 'done'}, context=context)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def action_module_open(self, cr, uid, ids, context):
|
||||||
|
data = self.browse(cr, uid, ids[0] , context=context)
|
||||||
|
return {
|
||||||
|
'domain': str([('name', '=', data.module_name)]),
|
||||||
|
'name': 'Modules',
|
||||||
|
'view_type': 'form',
|
||||||
|
'view_mode': 'tree,form',
|
||||||
|
'res_model': 'ir.module.module',
|
||||||
|
'view_id': False,
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
}
|
||||||
|
|
||||||
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -1,14 +1,18 @@
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import zipfile
|
||||||
from os.path import join as opj
|
from os.path import join as opj
|
||||||
|
|
||||||
import openerp
|
import openerp
|
||||||
from openerp.osv import osv
|
from openerp.osv import osv
|
||||||
from openerp.tools import convert_file
|
from openerp.tools import convert_file
|
||||||
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
MAX_FILE_SIZE = 100 * 1024 * 1024 # in megabytes
|
||||||
|
|
||||||
class view(osv.osv):
|
class view(osv.osv):
|
||||||
_inherit = "ir.module.module"
|
_inherit = "ir.module.module"
|
||||||
|
|
||||||
|
@ -22,7 +26,7 @@ class view(osv.osv):
|
||||||
|
|
||||||
unmet_dependencies = set(terp['depends']).difference(known_mods_names.keys())
|
unmet_dependencies = set(terp['depends']).difference(known_mods_names.keys())
|
||||||
if unmet_dependencies:
|
if unmet_dependencies:
|
||||||
raise Exception("Unmet module dependencies: %s" % ', '.join(unmet_dependencies))
|
raise osv.except_osv(_('Error !'), _("Unmet module dependencies: %s" % ', '.join(unmet_dependencies)))
|
||||||
|
|
||||||
if mod:
|
if mod:
|
||||||
self.write(cr, uid, mod.id, values)
|
self.write(cr, uid, mod.id, values)
|
||||||
|
@ -69,3 +73,31 @@ class view(osv.osv):
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def import_zipfile(self, cr, uid, module_file, context=None):
|
||||||
|
if not module_file:
|
||||||
|
raise Exception("No file sent.")
|
||||||
|
if not zipfile.is_zipfile(module_file):
|
||||||
|
raise osv.except_osv(_('Error !'), _('File is not a zip file!'))
|
||||||
|
|
||||||
|
success = []
|
||||||
|
errors = dict()
|
||||||
|
with zipfile.ZipFile(module_file, "r") as z:
|
||||||
|
for zf in z.filelist:
|
||||||
|
if zf.file_size > MAX_FILE_SIZE:
|
||||||
|
raise osv.except_osv(_('Error !'), _("File '%s' exceed maximum allowed file size" % zf.filename))
|
||||||
|
|
||||||
|
with openerp.tools.osutil.tempdir() as module_dir:
|
||||||
|
z.extractall(module_dir)
|
||||||
|
dirs = [d for d in os.listdir(module_dir) if os.path.isdir(opj(module_dir, d))]
|
||||||
|
for mod_name in dirs:
|
||||||
|
try:
|
||||||
|
# assert mod_name.startswith('theme_')
|
||||||
|
path = opj(module_dir, mod_name)
|
||||||
|
self.import_module(cr, uid, mod_name, path, context=context)
|
||||||
|
success.append(mod_name)
|
||||||
|
except Exception, e:
|
||||||
|
errors[mod_name] = str(e)
|
||||||
|
r = ["Successfully imported module '%s'" % mod for mod in success]
|
||||||
|
for mod, error in errors.items():
|
||||||
|
r.append("Error while importing module '%s': %r" % (mod, error))
|
||||||
|
return '\n'.join(r)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<record id="view_base_module_import" model="ir.ui.view">
|
<record id="view_base_module_import" model="ir.ui.view">
|
||||||
<field name="name">Module Import</field>
|
<field name="name">Module Import</field>
|
||||||
<field name="model">base.module.import</field>
|
<field name="model">base.import.module</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<form string="Import module" version="7.0">
|
<form string="Import module" version="7.0">
|
||||||
<field name="state" invisible="1"/>
|
<field name="state" invisible="1"/>
|
||||||
|
@ -17,11 +17,14 @@
|
||||||
<label string="Module file successfully imported!" colspan="4"/>
|
<label string="Module file successfully imported!" colspan="4"/>
|
||||||
</group>
|
</group>
|
||||||
<footer>
|
<footer>
|
||||||
<button name="importzip" string="Import module" type="object" states="init" class="oe_highlight"/>
|
<div states="init">
|
||||||
<label string="or" states="init"/>
|
<button name="import_module" string="Import Module" type="object" class="oe_highlight"/> or
|
||||||
<button name="action_module_open" string="Open Modules" type="object" states="done" class="oe_highlight"/>
|
<button special="cancel" string="Cancel" class="oe_link"/>
|
||||||
<label string="or" states="done"/>
|
</div>
|
||||||
<button string="Cancel" class="oe_link" special="cancel"/>
|
<div states="done">
|
||||||
|
<button name="action_module_open" string="Open Modules" type="object" class="oe_highlight"/> or
|
||||||
|
<button special="cancel" string="Close" class="oe_link"/>
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</form>
|
</form>
|
||||||
</field>
|
</field>
|
||||||
|
@ -30,22 +33,21 @@
|
||||||
<record id="action_view_base_module_import" model="ir.actions.act_window">
|
<record id="action_view_base_module_import" model="ir.actions.act_window">
|
||||||
<field name="name">Module Import</field>
|
<field name="name">Module Import</field>
|
||||||
<field name="type">ir.actions.act_window</field>
|
<field name="type">ir.actions.act_window</field>
|
||||||
<field name="res_model">base.module.import</field>
|
<field name="res_model">base.import.module</field>
|
||||||
<field name="view_type">form</field>
|
<field name="view_type">form</field>
|
||||||
<field name="view_mode">form</field>
|
<field name="view_mode">form</field>
|
||||||
<field name="target">new</field>
|
<field name="target">new</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<!-- This feature is now deprecated, but may come back later.
|
|
||||||
<menuitem
|
<menuitem
|
||||||
name="Import Module"
|
name="Import Module"
|
||||||
action="action_view_base_module_import"
|
action="action_view_base_module_import"
|
||||||
id="menu_view_base_module_import"
|
id="menu_view_base_module_import"
|
||||||
parent="menu_management"
|
parent="base.menu_management"
|
||||||
groups="base.group_no_one"
|
groups="base.group_no_one"
|
||||||
sequence="6"/>
|
sequence="6"/>
|
||||||
-->
|
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,6 @@ The kernel of OpenERP, needed for all installation.
|
||||||
'module/module_view.xml',
|
'module/module_view.xml',
|
||||||
'module/module_data.xml',
|
'module/module_data.xml',
|
||||||
'module/module_report.xml',
|
'module/module_report.xml',
|
||||||
'module/wizard/base_module_import_view.xml',
|
|
||||||
'module/wizard/base_module_update_view.xml',
|
'module/wizard/base_module_update_view.xml',
|
||||||
'module/wizard/base_language_install_view.xml',
|
'module/wizard/base_language_install_view.xml',
|
||||||
'module/wizard/base_import_language_view.xml',
|
'module/wizard/base_import_language_view.xml',
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import base_module_import
|
|
||||||
import base_module_update
|
import base_module_update
|
||||||
import base_language_install
|
import base_language_install
|
||||||
import base_import_language
|
import base_import_language
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# OpenERP, Open Source Management Solution
|
|
||||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
|
||||||
#
|
|
||||||
# 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 base64
|
|
||||||
import os
|
|
||||||
from StringIO import StringIO
|
|
||||||
import zipfile
|
|
||||||
|
|
||||||
from openerp import tools
|
|
||||||
from openerp.osv import osv, fields
|
|
||||||
from openerp.tools.translate import _
|
|
||||||
|
|
||||||
class base_module_import(osv.osv_memory):
|
|
||||||
""" Import Module """
|
|
||||||
|
|
||||||
_name = "base.module.import"
|
|
||||||
_description = "Import Module"
|
|
||||||
_columns = {
|
|
||||||
'module_file': fields.binary('Module .ZIP file', required=True),
|
|
||||||
'state':fields.selection([('init','init'),('done','done')],
|
|
||||||
'Status', readonly=True),
|
|
||||||
'module_name': fields.char('Module Name', size=128),
|
|
||||||
}
|
|
||||||
|
|
||||||
_defaults = {
|
|
||||||
'state': 'init',
|
|
||||||
}
|
|
||||||
|
|
||||||
def importzip(self, cr, uid, ids, context):
|
|
||||||
#TODO: drop this model and the corresponding view/action in trunk
|
|
||||||
raise NotImplementedError('This feature is not available')
|
|
||||||
|
|
||||||
def action_module_open(self, cr, uid, ids, context):
|
|
||||||
(data,) = self.browse(cr, uid, ids , context=context)
|
|
||||||
return {
|
|
||||||
'domain': str([('name', '=', data.module_name)]),
|
|
||||||
'name': 'Modules',
|
|
||||||
'view_type': 'form',
|
|
||||||
'view_mode': 'tree,form',
|
|
||||||
'res_model': 'ir.module.module',
|
|
||||||
'type': 'ir.actions.act_window',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
Loading…
Reference in New Issue