[ADD] add wizard to import zipped module

This commit is contained in:
tpa-odoo 2014-05-22 15:51:51 +05:30
parent b27a3351af
commit 41147025b8
9 changed files with 92 additions and 112 deletions

View File

@ -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': [],
} }

View File

@ -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)

View File

@ -1,2 +1,3 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import ir_module import ir_module
import base_import_module

View File

@ -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:

View File

@ -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)

View File

@ -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>

View File

@ -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',

View File

@ -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

View File

@ -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: