Files

84 lines
3.2 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import io
import logging
import zipfile
from odoo.http import (
Controller,
content_disposition,
request,
route,
serialize_exception,
)
from werkzeug.exceptions import Forbidden, InternalServerError, NotFound
from .export_utils import StudioExportSerializer
_logger = logging.getLogger(__name__)
class StudioExporter(Controller):
@route('/web_studio/export', type='http', auth='user')
def export(self, token, active_id):
""" Exports a zip file containing the 'studio_customization' module
gathering all customizations done with Studio (customizations of
existing apps and freshly created apps) along with the
StudioExportModel's related data.
Returns:
Response: A zip file containing the exported data
Raises:
Forbidden: If the user is not an admin.
NotFound: If the export wizard is not found.
InternalServerError: If the export wizard is not found.
"""
if not self.env.is_admin():
raise Forbidden()
module = self.env['ir.module.module'].get_studio_module()
wizard_id = int(active_id)
wizard = self.env['studio.export.wizard'].browse(wizard_id).exists()
if not wizard:
raise NotFound()
try:
export_info = wizard.get_export_info()
content = self.generate_archive(module, export_info)
return request.make_response(content, headers=[
('Content-Disposition', content_disposition('customizations.zip')),
('Content-Type', 'application/zip'),
('Content-Length', len(content)),
])
except Exception as e:
_logger.warning("Error while generating studio export %s", module.name, exc_info=True)
se = serialize_exception(e)
error = {
'code': 0,
'message': "Odoo Server Error",
'data': se
}
res = request.make_json_response(error, status=500)
raise InternalServerError(response=res) from e
def generate_archive(self, module, export_info):
""" Returns a zip file containing the given module with the given data.
Returns:
bytes: A byte string containing the zip file.
"""
with io.BytesIO() as f:
with zipfile.ZipFile(f, 'w', zipfile.ZIP_STORED) as archive:
for filename, content in self.generate_module_files(module, export_info):
archive.writestr(module.name + '/' + filename, content)
return f.getvalue()
def generate_module_files(self, module, export_info):
""" Return an iterator of pairs (filename, content) to put in the exported
module. Returned filenames are local to the module directory.
Groups exported data by model in separated files.
The content of the files is yielded as an encoded bytestring (utf-8)
Yields:
tuple: A tuple containing the filename and content.
"""
yield from StudioExportSerializer(self.env, module, export_info).serialize()