mirror of https://github.com/muk-it/muk_base
MuK IT GmbH
6 years ago
21 changed files with 622 additions and 325 deletions
-
1muk_converter/__init__.py
-
12muk_converter/__manifest__.py
-
6muk_converter/data/params.xml
-
5muk_converter/doc/changelog.rst
-
7muk_converter/doc/index.rst
-
3muk_converter/models/__init__.py
-
82muk_converter/models/converter.py
-
83muk_converter/models/res_config_settings.py
-
10muk_converter/models/store.py
-
1muk_converter/service/__init__.py
-
89muk_converter/service/provider.py
-
303muk_converter/service/unoconv.py
-
BINmuk_converter/static/description/icon.png
-
1muk_converter/static/description/icon.svg
-
51muk_converter/static/description/index.html
-
34muk_converter/tests/test_converter.py
-
7muk_converter/tests/test_unoconv.py
-
88muk_converter/tools/converter.py
-
6muk_converter/views/convert.xml
-
64muk_converter/views/res_config_settings_view.xml
-
94muk_converter/wizards/convert.py
@ -0,0 +1,83 @@ |
|||||
|
################################################################################### |
||||
|
# |
||||
|
# Copyright (C) 2017 MuK IT GmbH |
||||
|
# |
||||
|
# 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 logging |
||||
|
import textwrap |
||||
|
|
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
class ResConfigSettings(models.TransientModel): |
||||
|
|
||||
|
_inherit = 'res.config.settings' |
||||
|
|
||||
|
converter_service = fields.Selection( |
||||
|
selection=[ |
||||
|
("unoconv", "Local"), |
||||
|
("provider", "Service")], |
||||
|
string="Converter", |
||||
|
default="provider", |
||||
|
help=textwrap.dedent("""\ |
||||
|
Converter engine, which is used for the conversion: |
||||
|
- Local: Use a locally installed unoconv installation |
||||
|
- Service: Use a service to do the conversion |
||||
|
""")) |
||||
|
|
||||
|
converter_max_store = fields.Integer( |
||||
|
string="Storage Size", |
||||
|
help=textwrap.dedent("""\ |
||||
|
To certify the conversion, converted files can be saved |
||||
|
and loaded from memory if necessary. You can set a maximum |
||||
|
size of the storage to prevent massive memory requirements. |
||||
|
""")) |
||||
|
|
||||
|
converter_credit = fields.Boolean( |
||||
|
compute='_compute_converter_credit', |
||||
|
string="Converter insufficient credit") |
||||
|
|
||||
|
@api.multi |
||||
|
def set_values(self): |
||||
|
res = super(ResConfigSettings, self).set_values() |
||||
|
param = self.env['ir.config_parameter'].sudo() |
||||
|
param.set_param("muk_converter.service", self.converter_service) |
||||
|
param.set_param("muk_converter.max_store", self.converter_max_store) |
||||
|
return res |
||||
|
|
||||
|
@api.model |
||||
|
def get_values(self): |
||||
|
res = super(ResConfigSettings, self).get_values() |
||||
|
params = self.env['ir.config_parameter'].sudo() |
||||
|
res.update( |
||||
|
converter_service=params.get_param("muk_converter.service", default="provider"), |
||||
|
converter_max_store=int(params.get_param("muk_converter.max_store", default=20)) |
||||
|
) |
||||
|
return res |
||||
|
|
||||
|
@api.multi |
||||
|
def _compute_converter_credit(self): |
||||
|
credits = self.env['iap.account'].get_credits('muk_converter') |
||||
|
for record in self: |
||||
|
record.converter_credit = credits <= 0 |
||||
|
@api.multi |
||||
|
def redirect_to_buy_converter_credit(self): |
||||
|
url = self.env['iap.account'].get_credits_url('muk_converter') |
||||
|
return { |
||||
|
'type': 'ir.actions.act_url', |
||||
|
'url': url, |
||||
|
'target': '_new', |
||||
|
} |
@ -0,0 +1,89 @@ |
|||||
|
################################################################################### |
||||
|
# |
||||
|
# Copyright (C) 2018 MuK IT GmbH |
||||
|
# |
||||
|
# 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 logging |
||||
|
|
||||
|
from odoo.addons.iap import jsonrpc |
||||
|
|
||||
|
from odoo.addons.muk_utils.tools.cache import memoize |
||||
|
from odoo.addons.muk_utils.tools.file import guess_extension |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
CONVERTER_DEFAULT_ENDPOINT = 'https://iap-converter.mukit.at' |
||||
|
CONVERTER_ENDPOINT_FORMATS = '/iap/converter/1/formats' |
||||
|
CONVERTER_ENDPOINT_IMPORTS = '/iap/converter/1/imports' |
||||
|
CONVERTER_ENDPOINT_CONVERT = '/iap/converter/1/convert' |
||||
|
|
||||
|
class RemoteConverter(object): |
||||
|
|
||||
|
def __init__(self, env): |
||||
|
self.params = env['ir.config_parameter'].sudo() |
||||
|
self.account = env['iap.account'].get('muk_converter') |
||||
|
|
||||
|
def endpoint(self, route): |
||||
|
return "%s%s" % (self.params.get_param('muk_converter.endpoint', CONVERTER_DEFAULT_ENDPOINT), route) |
||||
|
|
||||
|
def payload(self, params={}): |
||||
|
params.update({ |
||||
|
'account_token': self.account.account_token, |
||||
|
'database_uuid': self.params.get_param('database.uuid'), |
||||
|
}) |
||||
|
return params |
||||
|
|
||||
|
@property |
||||
|
@memoize(timeout=3600) |
||||
|
def formats(self): |
||||
|
return jsonrpc(self.endpoint(CONVERTER_ENDPOINT_FORMATS), params=self.payload()) |
||||
|
|
||||
|
@property |
||||
|
@memoize(timeout=3600) |
||||
|
def imports(self): |
||||
|
return jsonrpc(self.endpoint(CONVERTER_ENDPOINT_IMPORTS), params=self.payload()) |
||||
|
|
||||
|
def convert(self, binary, mimetype=None, filename=None, export="binary", doctype="document", format="pdf"): |
||||
|
""" Converts a binary value to the given format. |
||||
|
|
||||
|
:param binary: The binary value. |
||||
|
:param mimetype: The mimetype of the binary value. |
||||
|
:param filename: The filename of the binary value. |
||||
|
:param export: The output format (binary, file, base64). |
||||
|
:param doctype: Specify the document type (document, graphics, presentation, spreadsheet). |
||||
|
:param format: Specify the output format for the document. |
||||
|
:return: Returns the output depending on the given format. |
||||
|
:raises ValueError: The file extension could not be determined or the format is invalid. |
||||
|
""" |
||||
|
params = { |
||||
|
'format': format, |
||||
|
'doctype': doctype, |
||||
|
'mimetype': mimetype, |
||||
|
'filename': filename, |
||||
|
'content': base64.b64encode(binary), |
||||
|
} |
||||
|
result = jsonrpc(self.endpoint(CONVERTER_ENDPOINT_CONVERT), params=self.payload(params)) |
||||
|
if export == 'base64': |
||||
|
return result |
||||
|
if export == 'file': |
||||
|
output = io.BytesIO() |
||||
|
output.write(base64.b64decode(result)) |
||||
|
output.close() |
||||
|
return output |
||||
|
else: |
||||
|
return base64.b64decode(result) |
@ -1,156 +1,147 @@ |
|||||
################################################################################### |
|
||||
# |
|
||||
# Copyright (C) 2018 MuK IT GmbH |
|
||||
# |
|
||||
# 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 os |
|
||||
import io |
|
||||
import base64 |
|
||||
import shutil |
|
||||
import urllib |
|
||||
import logging |
|
||||
import tempfile |
|
||||
import mimetypes |
|
||||
|
|
||||
from subprocess import Popen |
|
||||
from subprocess import PIPE |
|
||||
from subprocess import CalledProcessError |
|
||||
|
|
||||
from contextlib import closing |
|
||||
|
|
||||
from odoo.tools import config |
|
||||
from odoo.tools.mimetypes import guess_mimetype |
|
||||
|
|
||||
from odoo.addons.muk_utils.tools import utils_os |
|
||||
|
|
||||
_logger = logging.getLogger(__name__) |
|
||||
|
|
||||
FORMATS = [ |
|
||||
"bib", "bmp", "csv", "dbf", "dif", "doc", "doc6", "doc95", "docbook", "docx", "docx7", "emf", |
|
||||
"eps", "fodg", "fodp", "fods", "fodt", "gif", "html", "jpg", "latex", "mediawiki", "met", "odd", |
|
||||
"odg", "odp", "ods", "odt", "ooxml", "otg", "otp", "ots", "ott", "pbm", "pct", "pdb", "pdf", "pgm", |
|
||||
"png", "pot", "potm", "ppm", "pps", "ppt", "pptx", "psw", "pwp", "pxl", "ras", "rtf", "sda", "sdc", |
|
||||
"sdc3", "sdc4", "sdd", "sdd3", "sdd4", "sdw", "sdw3", "sdw4", "slk", "stc", "std", "sti", "stw", |
|
||||
"svg", "svm", "swf", "sxc", "sxd", "sxd3", "sxd5", "sxi", "sxw", "text", "tiff", "txt", "uop", "uos", |
|
||||
"uot", "vor", "vor3", "vor4", "vor5", "wmf", "wps", "xhtml", "xls", "xls5", "xls95", "xlsx", "xlt", |
|
||||
"xlt5", "xlt95", "xpm""bib", "bmp", "csv", "dbf", "dif", "doc", "doc6", "doc95", "docbook", "docx", |
|
||||
"docx7", "emf", "eps", "fodg", "fodp", "fods", "fodt", "gif", "html", "jpg", "latex", "mediawiki", |
|
||||
"met", "odd", "odg", "odp", "ods", "odt", "ooxml", "otg", "otp", "ots", "ott", "pbm", "pct", "pdb", |
|
||||
"pdf", "pgm", "png", "pot", "potm", "ppm", "pps", "ppt", "pptx", "psw", "pwp", "pxl", "ras", "rtf", |
|
||||
"sda", "sdc", "sdc3", "sdc4", "sdd", "sdd3", "sdd4", "sdw", "sdw3", "sdw4", "slk", "stc", "std", |
|
||||
"sti", "stw", "svg", "svm", "swf", "sxc", "sxd", "sxd3", "sxd5", "sxi", "sxw", "text", "tiff", |
|
||||
"txt", "uop", "uos", "uot", "vor", "vor3", "vor4", "vor5", "wmf", "wps", "xhtml", "xls", "xls5", |
|
||||
"xls95", "xlsx", "xlt", "xlt5", "xlt95", "xpm" |
|
||||
] |
|
||||
|
|
||||
IMPORTS = [ |
|
||||
"bmp", "csv", "dbf", "dif", "doc", "docx", "dot", "emf", "eps", "epub", "fodg", "fodp", "fods", |
|
||||
"fodt", "gif", "gnm", "gnumeric", "htm", "html", "jpeg", "jpg", "met", "mml", "odb", "odf", "odg", |
|
||||
"odp", "ods", "odt", "pbm", "pct", "pdb", "pdf", "pgm", "png", "pot", "ppm", "pps", "ppt", "pptx", |
|
||||
"psw", "pxl", "ras", "rtf", "sda", "sdc", "sdd", "sdp", "sdw", "sgl", "slk", "stc", "std", "sti", |
|
||||
"stw", "svg", "svm", "swf", "sxc", "sxd", "sxi", "sxm", "sxw", "tif", "tiff", "txt", "uof", "uop", |
|
||||
"uos", "uot", "vor", "wmf", "wri", "xls", "xlsx", "xlt", "xlw", "xml", "xpm""bmp", "csv", "dbf", |
|
||||
"dif", "doc", "docx", "dot", "emf", "eps", "epub", "fodg", "fodp", "fods", "fodt", "gif", "gnm", |
|
||||
"gnumeric", "htm", "html", "jpeg", "jpg", "met", "mml", "odb", "odf", "odg", "odp", "ods", "odt", |
|
||||
"pbm", "pct", "pdb", "pdf", "pgm", "png", "pot", "ppm", "pps", "ppt", "pptx", "psw", "pxl", "ras", |
|
||||
"rtf", "sda", "sdc", "sdd", "sdp", "sdw", "sgl", "slk", "stc", "std", "sti", "stw", "svg", "svm", |
|
||||
"swf", "sxc", "sxd", "sxi", "sxm", "sxw", "tif", "tiff", "text", "uof", "uop", "uos", "uot", "vor", |
|
||||
"wmf", "wri", "xls", "xlsx", "xlt", "xlw", "xml", "xpm" |
|
||||
] |
|
||||
|
|
||||
def formats(): |
|
||||
return FORMATS |
|
||||
|
|
||||
def imports(): |
|
||||
return IMPORTS |
|
||||
|
|
||||
def unoconv_environ(): |
|
||||
env = os.environ.copy() |
|
||||
uno_path = config.get('uno_path', False) |
|
||||
if uno_path: |
|
||||
env['UNO_PATH'] = config['uno_path'] |
|
||||
return env |
|
||||
|
|
||||
def convert(input_path, output_path, doctype="document", format="pdf"): |
|
||||
""" |
|
||||
Convert a file to the given format. |
|
||||
|
|
||||
:param input_path: The path of the file to convert. |
|
||||
:param output_path: The path of the output where the converted file is to be saved. |
|
||||
:param doctype: Specify the document type (document, graphics, presentation, spreadsheet). |
|
||||
:param format: Specify the output format for the document. |
|
||||
:raises CalledProcessError: The command returned non-zero exit status 1. |
|
||||
:raises OSError: This exception is raised when a system function returns a system-related error. |
|
||||
""" |
|
||||
try: |
|
||||
env = unoconv_environ() |
|
||||
shell = True if os.name in ('nt', 'os2') else False |
|
||||
args = ['unoconv', '--format=%s' % format, '--output=%s' % output_path, input_path] |
|
||||
process = Popen(args, stdout=PIPE, env=env, shell=shell) |
|
||||
outs, errs = process.communicate() |
|
||||
return_code = process.wait() |
|
||||
if return_code: |
|
||||
raise CalledProcessError(return_code, args, outs, errs) |
|
||||
except CalledProcessError: |
|
||||
_logger.exception("Error while running unoconv.") |
|
||||
raise |
|
||||
except OSError: |
|
||||
_logger.exception("Error while running unoconv.") |
|
||||
raise |
|
||||
|
|
||||
def convert_binary(binary, mimetype=None, filename=None, export="binary", doctype="document", format="pdf"): |
|
||||
""" |
|
||||
Converts a binary value to the given format. |
|
||||
|
|
||||
:param binary: The binary value. |
|
||||
:param mimetype: The mimetype of the binary value. |
|
||||
:param filename: The filename of the binary value. |
|
||||
:param export: The output format (binary, file, base64). |
|
||||
:param doctype: Specify the document type (document, graphics, presentation, spreadsheet). |
|
||||
:param format: Specify the output format for the document. |
|
||||
:return: Returns the output depending on the given format. |
|
||||
:raises ValueError: The file extension could not be determined or the format is invalid. |
|
||||
""" |
|
||||
extension = utils_os.get_extension(binary, filename, mimetype) |
|
||||
if not extension: |
|
||||
raise ValueError("The file extension could not be determined.") |
|
||||
if format not in FORMATS: |
|
||||
raise ValueError("Invalid export format.") |
|
||||
if extension not in IMPORTS: |
|
||||
raise ValueError("Invalid import format.") |
|
||||
tmp_dir = tempfile.mkdtemp() |
|
||||
try: |
|
||||
tmp_wpath = os.path.join(tmp_dir, "tmpfile." + extension) |
|
||||
tmp_ppath = os.path.join(tmp_dir, "tmpfile." + format) |
|
||||
if os.name == 'nt': |
|
||||
tmp_wpath = tmp_wpath.replace("\\", "/") |
|
||||
tmp_ppath = tmp_ppath.replace("\\", "/") |
|
||||
with closing(open(tmp_wpath, 'wb')) as file: |
|
||||
file.write(binary) |
|
||||
convert(tmp_wpath, tmp_ppath, doctype, format) |
|
||||
with closing(open(tmp_ppath, 'rb')) as file: |
|
||||
if export == 'file': |
|
||||
output = io.BytesIO() |
|
||||
output.write(file.read()) |
|
||||
output.close() |
|
||||
return output |
|
||||
elif export == 'base64': |
|
||||
return base64.b64encode(file.read()) |
|
||||
else: |
|
||||
return file.read() |
|
||||
finally: |
|
||||
shutil.rmtree(tmp_dir) |
|
||||
|
################################################################################### |
||||
|
# |
||||
|
# Copyright (C) 2018 MuK IT GmbH |
||||
|
# |
||||
|
# 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 os |
||||
|
import io |
||||
|
import base64 |
||||
|
import shutil |
||||
|
import urllib |
||||
|
import logging |
||||
|
import tempfile |
||||
|
import mimetypes |
||||
|
|
||||
|
from subprocess import Popen |
||||
|
from subprocess import PIPE |
||||
|
from subprocess import CalledProcessError |
||||
|
|
||||
|
from contextlib import closing |
||||
|
|
||||
|
from odoo.tools import config |
||||
|
from odoo.tools.mimetypes import guess_mimetype |
||||
|
|
||||
|
from odoo.addons.muk_utils.tools.file import guess_extension |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
UNOCONV_FORMATS = [ |
||||
|
"bib", "bmp", "csv", "dbf", "dif", "doc", "doc6", "doc95", "docbook", "docx", "docx7", "emf", |
||||
|
"eps", "fodg", "fodp", "fods", "fodt", "gif", "html", "jpg", "latex", "mediawiki", "met", "odd", |
||||
|
"odg", "odp", "ods", "odt", "ooxml", "otg", "otp", "ots", "ott", "pbm", "pct", "pdb", "pdf", "pgm", |
||||
|
"png", "pot", "potm", "ppm", "pps", "ppt", "pptx", "psw", "pwp", "pxl", "ras", "rtf", "sda", "sdc", |
||||
|
"sdc3", "sdc4", "sdd", "sdd3", "sdd4", "sdw", "sdw3", "sdw4", "slk", "stc", "std", "sti", "stw", |
||||
|
"svg", "svm", "swf", "sxc", "sxd", "sxd3", "sxd5", "sxi", "sxw", "text", "tiff", "txt", "uop", "uos", |
||||
|
"uot", "vor", "vor3", "vor4", "vor5", "wmf", "wps", "xhtml", "xls", "xls5", "xls95", "xlsx", "xlt", |
||||
|
"xlt5", "xlt95", "xpm""bib", "bmp", "csv", "dbf", "dif", "doc", "doc6", "doc95", "docbook", "docx", |
||||
|
"docx7", "emf", "eps", "fodg", "fodp", "fods", "fodt", "gif", "html", "jpg", "latex", "mediawiki", |
||||
|
"met", "odd", "odg", "odp", "ods", "odt", "ooxml", "otg", "otp", "ots", "ott", "pbm", "pct", "pdb", |
||||
|
"pdf", "pgm", "png", "pot", "potm", "ppm", "pps", "ppt", "pptx", "psw", "pwp", "pxl", "ras", "rtf", |
||||
|
"sda", "sdc", "sdc3", "sdc4", "sdd", "sdd3", "sdd4", "sdw", "sdw3", "sdw4", "slk", "stc", "std", |
||||
|
"sti", "stw", "svg", "svm", "swf", "sxc", "sxd", "sxd3", "sxd5", "sxi", "sxw", "text", "tiff", |
||||
|
"txt", "uop", "uos", "uot", "vor", "vor3", "vor4", "vor5", "wmf", "wps", "xhtml", "xls", "xls5", |
||||
|
"xls95", "xlsx", "xlt", "xlt5", "xlt95", "xpm" |
||||
|
] |
||||
|
|
||||
|
UNOCONV_IMPORTS = [ |
||||
|
"bmp", "csv", "dbf", "dif", "doc", "docx", "dot", "emf", "eps", "epub", "fodg", "fodp", "fods", |
||||
|
"fodt", "gif", "gnm", "gnumeric", "htm", "html", "jpeg", "jpg", "met", "mml", "odb", "odf", "odg", |
||||
|
"odp", "ods", "odt", "pbm", "pct", "pdb", "pdf", "pgm", "png", "pot", "ppm", "pps", "ppt", "pptx", |
||||
|
"psw", "pxl", "ras", "rtf", "sda", "sdc", "sdd", "sdp", "sdw", "sgl", "slk", "stc", "std", "sti", |
||||
|
"stw", "svg", "svm", "swf", "sxc", "sxd", "sxi", "sxm", "sxw", "tif", "tiff", "txt", "uof", "uop", |
||||
|
"uos", "uot", "vor", "wmf", "wri", "xls", "xlsx", "xlt", "xlw", "xml", "xpm""bmp", "csv", "dbf", |
||||
|
"dif", "doc", "docx", "dot", "emf", "eps", "epub", "fodg", "fodp", "fods", "fodt", "gif", "gnm", |
||||
|
"gnumeric", "htm", "html", "jpeg", "jpg", "met", "mml", "odb", "odf", "odg", "odp", "ods", "odt", |
||||
|
"pbm", "pct", "pdb", "pdf", "pgm", "png", "pot", "ppm", "pps", "ppt", "pptx", "psw", "pxl", "ras", |
||||
|
"rtf", "sda", "sdc", "sdd", "sdp", "sdw", "sgl", "slk", "stc", "std", "sti", "stw", "svg", "svm", |
||||
|
"swf", "sxc", "sxd", "sxi", "sxm", "sxw", "tif", "tiff", "text", "uof", "uop", "uos", "uot", "vor", |
||||
|
"wmf", "wri", "xls", "xlsx", "xlt", "xlw", "xml", "xpm" |
||||
|
] |
||||
|
|
||||
|
class UnoconvConverter(object): |
||||
|
|
||||
|
@property |
||||
|
def formats(self): |
||||
|
return UNOCONV_FORMATS |
||||
|
|
||||
|
@property |
||||
|
def imports(self): |
||||
|
return UNOCONV_IMPORTS |
||||
|
|
||||
|
def environ(self): |
||||
|
env = os.environ.copy() |
||||
|
uno_path = config.get('uno_path', False) |
||||
|
if uno_path: |
||||
|
env['UNO_PATH'] = config['uno_path'] |
||||
|
return env |
||||
|
|
||||
|
def convert(self, binary, mimetype=None, filename=None, export="binary", doctype="document", format="pdf"): |
||||
|
""" Converts a binary value to the given format. |
||||
|
|
||||
|
:param binary: The binary value. |
||||
|
:param mimetype: The mimetype of the binary value. |
||||
|
:param filename: The filename of the binary value. |
||||
|
:param export: The output format (binary, file, base64). |
||||
|
:param doctype: Specify the document type (document, graphics, presentation, spreadsheet). |
||||
|
:param format: Specify the output format for the document. |
||||
|
:return: Returns the output depending on the given format. |
||||
|
:raises ValueError: The file extension could not be determined or the format is invalid. |
||||
|
""" |
||||
|
extension = guess_extension(filename=filename, mimetype=mimetype, binary=binary) |
||||
|
if not extension: |
||||
|
raise ValueError("The file extension could not be determined.") |
||||
|
if format not in self.formats: |
||||
|
raise ValueError("Invalid export format.") |
||||
|
if extension not in self.imports: |
||||
|
raise ValueError("Invalid import format.") |
||||
|
tmp_dir = tempfile.mkdtemp() |
||||
|
try: |
||||
|
tmp_wpath = os.path.join(tmp_dir, "tmpfile." + extension) |
||||
|
tmp_ppath = os.path.join(tmp_dir, "tmpfile." + format) |
||||
|
if os.name == 'nt': |
||||
|
tmp_wpath = tmp_wpath.replace("\\", "/") |
||||
|
tmp_ppath = tmp_ppath.replace("\\", "/") |
||||
|
with closing(open(tmp_wpath, 'wb')) as file: |
||||
|
file.write(binary) |
||||
|
shell = True if os.name in ('nt', 'os2') else False |
||||
|
args = ['unoconv', '--format=%s' % format, '--output=%s' % tmp_ppath, tmp_wpath] |
||||
|
process = Popen(args, stdout=PIPE, env=self.environ(), shell=shell) |
||||
|
outs, errs = process.communicate() |
||||
|
return_code = process.wait() |
||||
|
if return_code: |
||||
|
raise CalledProcessError(return_code, args, outs, errs) |
||||
|
with closing(open(tmp_ppath, 'rb')) as file: |
||||
|
if export == 'file': |
||||
|
output = io.BytesIO() |
||||
|
output.write(file.read()) |
||||
|
output.close() |
||||
|
return output |
||||
|
elif export == 'base64': |
||||
|
return base64.b64encode(file.read()) |
||||
|
else: |
||||
|
return file.read() |
||||
|
except CalledProcessError: |
||||
|
_logger.exception("Error while running unoconv.") |
||||
|
raise |
||||
|
except OSError: |
||||
|
_logger.exception("Error while running unoconv.") |
||||
|
raise |
||||
|
finally: |
||||
|
shutil.rmtree(tmp_dir) |
||||
|
|
||||
|
unoconv = UnoconvConverter() |
||||
|
|
Before Width: 250 | Height: 250 | Size: 19 KiB After Width: 250 | Height: 250 | Size: 20 KiB |
1
muk_converter/static/description/icon.svg
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,45 +1,45 @@ |
|||||
################################################################################### |
|
||||
# |
|
||||
# Copyright (C) 2018 MuK IT GmbH |
|
||||
# |
|
||||
# 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 logging |
|
||||
|
|
||||
from odoo import tools |
|
||||
|
|
||||
from odoo.addons.muk_converter.service import unoconv |
|
||||
|
|
||||
_logger = logging.getLogger(__name__) |
|
||||
|
|
||||
def formats(): |
|
||||
return unoconv.formats() |
|
||||
|
|
||||
def selection_formats(): |
|
||||
return list(map(lambda format: (format, format.upper()), unoconv.formats())) |
|
||||
|
|
||||
def imports(): |
|
||||
return unoconv.imports() |
|
||||
|
|
||||
def convert(filename, content, format): |
|
||||
return unoconv.convert_binary(binary=content, filename=filename, format=format) |
|
||||
|
|
||||
def convert2pdf(filename, content): |
|
||||
return unoconv.convert_binary(binary=content, filename=filename) |
|
||||
|
|
||||
def convert2html(filename, content): |
|
||||
output = unoconv.convert_binary(binary=content, filename=filename, format="html") |
|
||||
|
################################################################################### |
||||
|
# |
||||
|
# Copyright (C) 2018 MuK IT GmbH |
||||
|
# |
||||
|
# 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 logging |
||||
|
|
||||
|
from odoo import tools |
||||
|
|
||||
|
from odoo.addons.muk_converter.service.unoconv import unoconv |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
def formats(): |
||||
|
return unoconv.formats |
||||
|
|
||||
|
def selection_formats(): |
||||
|
return list(map(lambda format: (format, format.upper()), unoconv.formats) |
||||
|
|
||||
|
def imports(): |
||||
|
return unoconv.imports |
||||
|
|
||||
|
def convert(filename, content, format): |
||||
|
return unoconv.convert(content, filename=filename, format=format) |
||||
|
|
||||
|
def convert2pdf(filename, content): |
||||
|
return unoconv.convert(content, filename=filename, format="pdf") |
||||
|
|
||||
|
def convert2html(filename, content): |
||||
|
output = unoconv.convert(content, filename=filename, format="html") |
||||
return tools.html_sanitize(output) |
return tools.html_sanitize(output) |
@ -0,0 +1,64 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
|
||||
|
<!-- |
||||
|
Copyright (C) 2017 MuK IT GmbH |
||||
|
|
||||
|
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/>. |
||||
|
--> |
||||
|
|
||||
|
<odoo> |
||||
|
|
||||
|
<record id="res_config_settings_view_form" model="ir.ui.view"> |
||||
|
<field name="name">res.config.settings.view.form</field> |
||||
|
<field name="model">res.config.settings</field> |
||||
|
<field name="inherit_id" ref="base_setup.res_config_settings_view_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<div name="multi_company" position="after"> |
||||
|
<h2>File Converter</h2> |
||||
|
<div class="row mt16 o_settings_container" name="web_client"> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"></div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="converter_service"/> |
||||
|
<div class="text-muted"> |
||||
|
Converter engine, which is used for the conversion |
||||
|
</div> |
||||
|
<div class="mt8"> |
||||
|
<field name="converter_service" class="o_light_label" widget="radio" required="True"/> |
||||
|
</div> |
||||
|
<div class="content-group" attrs="{'invisible': [('converter_service','!=','provider')]}"> |
||||
|
<div id="partner_autocomplete_settings" position="inside"> |
||||
|
<widget name="iap_credit_checker" service_name="muk_converter"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-xs-12 col-md-6 o_setting_box"> |
||||
|
<div class="o_setting_left_pane"></div> |
||||
|
<div class="o_setting_right_pane"> |
||||
|
<label for="converter_max_store"/> |
||||
|
<div class="text-muted"> |
||||
|
Maximum storage size of the converter store |
||||
|
</div> |
||||
|
<div class="mt8"> |
||||
|
<field name="converter_max_store" class="o_light_label" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue