You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

132 lines
4.7 KiB

# -*- encoding: utf-8 -*-
# #############################################################################
#
# OpenERP, Open Source Management Solution
# This module copyright (C) 2010 - 2014 Savoir-faire Linux
# (<http://www.savoirfairelinux.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 StringIO
import base64
import os
import zipfile
from collections import namedtuple
from openerp import fields, models, api
class PrototypeModuleExport(models.TransientModel):
_name = "module_prototyper.module.export"
name = fields.Char('File Name', readonly=True)
api_version = fields.Selection(
[
('8.0', '8.0'),
],
'API version',
required=True,
default='8.0'
)
data = fields.Binary('File', readonly=True)
state = fields.Selection(
[
('choose', 'choose'), # choose version
('get', 'get') # get module
],
default='choose'
)
@api.model
def action_export(self, ids):
"""
Export a zip file containing the module based on the information
provided in the prototype, using the templates chosen in the wizard.
"""
if isinstance(ids, (int, long)):
ids = [ids]
wizard = self.browse(ids)
active_model = self._context.get('active_model')
# checking if the wizard was called by a prototype.
msg = '{} has to be called from a "module_prototyper" , not a "{}"'
assert active_model == 'module_prototyper', msg.format(
self, active_model
)
# getting the prototype of the wizard
prototypes = self.env[active_model].browse(
[self._context.get('active_id')]
)
zip_details = self.zip_files(wizard, prototypes)
if len(prototypes) == 1:
zip_name = prototypes[0].name
else:
zip_name = "prototyper_export"
wizard.write(
{
'name': '{}.zip'.format(zip_name),
'state': 'get',
'data': base64.encodestring(zip_details.stringIO.getvalue())
}
)
return {
'type': 'ir.actions.act_window',
'res_model': 'module_prototyper.module.export',
'view_mode': 'form',
'view_type': 'form',
'res_id': wizard.id,
'views': [(False, 'form')],
'target': 'new',
}
@staticmethod
def zip_files(wizard, prototypes):
"""Takes a set of file and zips them.
:param file_details: tuple (filename, file_content)
:return: tuple (zip_file, stringIO)
"""
zip_details = namedtuple('Zip_details', ['zip_file', 'stringIO'])
out = StringIO.StringIO()
with zipfile.ZipFile(out, 'w') as target:
for prototype in prototypes:
# setting the jinja environment.
# They will help the program to find the template to render the
# files with.
prototype.set_jinja_env(wizard.api_version)
# generate_files ask the prototype to investigate the input and
# to generate the file templates according to it. zip_files,
# in another hand, put all the template files into a package
# ready to be saved by the user.
file_details = prototype.generate_files()
for filename, file_content in file_details:
if isinstance(file_content, unicode):
file_content = file_content.encode('utf-8')
# Prefix all names with module technical name
filename = os.path.join(prototype.name, filename)
info = zipfile.ZipInfo(filename)
info.compress_type = zipfile.ZIP_DEFLATED
info.external_attr = 2175008768 # specifies mode 0644
target.writestr(info, file_content)
return zip_details(zip_file=target, stringIO=out)