Browse Source

publish muk_thumbnails - 11.0

pull/19/head
MuK IT GmbH 5 years ago
parent
commit
e8f3fc56c4
  1. 2
      muk_thumbnails/__manifest__.py
  2. 356
      muk_thumbnails/doc/index.rst
  3. 422
      muk_thumbnails/service/thumbnail.py

2
muk_thumbnails/__manifest__.py

@ -20,7 +20,7 @@
{
"name": 'MuK Thumbnails',
"summary": """File Thumbnails""",
"version": '11.0.1.0.2',
"version": '11.0.1.0.4',
"category": 'Document Management',
"license": "AGPL-3",
"website": "http://www.mukit.at",

356
muk_thumbnails/doc/index.rst

@ -1,178 +1,178 @@
==============
MuK Thumbnails
==============
Technical module to provide some utility features and libraries that can be used
in other applications. This module has no direct effect on the running system.
Requirements
=============
Unoconv
-------------
Universal Office Converter (unoconv) is a command line tool to convert any
document format that LibreOffice can import to any document format that
LibreOffice can export. It makes use of the LibreOffice's UNO bindings for
non-interactive conversion of documents.
To install unoconv please follow the instructions (`here <https://github.com/dagwieers/unoconv>`_).
Make sure that unoconv can be executed from the console and the conversion
is done correctly.
To set an individual path for the LibreOffice installation, the config
variable ``uno_path`` can be set accordingly in the Odoo config.
Under Windows you should rename the ``unoconv`` file to ``unoconv.py`` and set
the corresponding path for the ``uno_path`` variable. Since it does not work
reliably with the environment variable ``UNO_PATH``.
FFmpeg
-------------
FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video.
To install FFmpeg please follow the instructions (`here <https://www.ffmpeg.org/download.html>`_).
Ghostscript
-------------
Ghostscript is a suite of software based on an interpreter for Adobe Systems PostScript and
Portable Document Format (PDF) page description languages. Its main purposes are the
rasterization or rendering of such page description language files, for the display or printing
of document pages, and the conversion between PostScript and PDF files.
To install Ghostscript please follow the instructions (`here <https://www.ghostscript.com/download.html>`_).
ImageMagick
-------------
ImageMagick can be used to create, edit, compose, or convert bitmap images. It can read and write
images in a variety of formats (over 200) including PNG, JPEG, GIF, HEIC, TIFF, DPX, EXR, WebP,
Postscript, PDF, and SVG. Use ImageMagick to resize, flip, mirror, rotate, distort, shear and
transform images, adjust image colors, apply various special effects, or draw text, lines, polygons,
ellipses and Bezier curves.
To install ImageMagick please follow the instructions (`here <https://www.imagemagick.org/script/download.php>`_).
Wand
-------------
Wand is a ctypes-based simple ImageMagick binding for Python. It is used to interact with ImageMagick via a Python interface.
To install Wand please follow the instructions (`here <http://docs.wand-py.org/en/0.4.1/guide/install.html>`_).
Imageio
-------------
Imageio is a Python library that provides an easy interface to read and write a wide range of image data, including animated images, volumetric data, and scientific formats.
To install Imageio please follow the instructions (`here <https://pypi.org/project/imageio/>`_).
MoviePy
-------------
MoviePy is a Python module for video editing, which can be used for basic operations (like cuts, concatenations, title insertions), video compositing (a.k.a. non-linear editing), video processing, or to create advanced effects. It can read and write the most common video formats, including GIF.
To install MoviePy please follow the instructions (`here <https://zulko.github.io/moviepy/install.html>`_).
Installation
============
To install this module, you need to:
Download the module and add it to your Odoo addons folder. Afterward, log on to
your Odoo server and go to the Apps menu. Trigger the debug mode and update the
list by clicking on the "Update Apps List" link. Now install the module by
clicking on the install button.
Another way to install this module is via the package management for Python
(`PyPI <https://pypi.org/project/pip/>`_).
To install our modules using the package manager make sure
`odoo-autodiscover <https://pypi.org/project/odoo-autodiscover/>`_ is installed
correctly. Then open a console and install the module by entering the following
command:
``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple <module>``
The module name consists of the Odoo version and the module name, where
underscores are replaced by a dash.
**Module:**
``odoo<version>-addon-<module_name>``
**Example:**
``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
Once the installation has been successfully completed, the app is already in the
correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
debug mode and update the list by clicking on the "Update Apps List" link. Now
install the module by clicking on the install button.
The biggest advantage of this variant is that you can now also update the app
using the "pip" command. To do this, enter the following command in your console:
``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple <module>``
When the process is finished, restart your server and update the application in
Odoo. The steps are the same as for the installation only the button has changed
from "Install" to "Upgrade".
You can also view available Apps directly in our `repository <https://nexus.mukit.at/#browse/browse:odoo>`_
and find a more detailed installation guide on our `website <https://mukit.at/page/open-source>`_.
For modules licensed under OPL-1, you will receive access data when you purchase
the module. If the modules were not purchased directly from
`MuK IT <https://www.mukit.at/>`_ please contact our support (support@mukit.at)
with a confirmation of purchase to receive the corresponding access data.
Upgrade
============
To upgrade this module, you need to:
Download the module and add it to your Odoo addons folder. Restart the server
and log on to your Odoo server. Select the Apps menu and upgrade the module by
clicking on the upgrade button.
If you installed the module using the "pip" command, you can also update the
module in the same way. Just type the following command into the console:
``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple <module>``
When the process is finished, restart your server and update the application in
Odoo, just like you would normally.
Configuration
=============
No additional configuration is needed to use this module.
Usage
=============
This module has no direct visible effect on the system. It provide utility features.
Credits
=======
Contributors
------------
* Mathias Markl <mathias.markl@mukit.at>
Author & Maintainer
-------------------
This module is maintained by the `MuK IT GmbH <https://www.mukit.at/>`_.
MuK IT is an Austrian company specialized in customizing and extending Odoo.
We develop custom solutions for your individual needs to help you focus on
your strength and expertise to grow your business.
If you want to get in touch please contact us via mail
(sale@mukit.at) or visit our website (https://mukit.at).
==============
MuK Thumbnails
==============
Technical module to provide some utility features and libraries that can be used
in other applications. This module has no direct effect on the running system.
Requirements
=============
Unoconv
-------------
Universal Office Converter (unoconv) is a command line tool to convert any
document format that LibreOffice can import to any document format that
LibreOffice can export. It makes use of the LibreOffice's UNO bindings for
non-interactive conversion of documents.
To install unoconv please follow the instructions (`here <https://github.com/dagwieers/unoconv>`_).
Make sure that unoconv can be executed from the console and the conversion
is done correctly.
To set an individual path for the LibreOffice installation, the config
variable ``uno_path`` can be set accordingly in the Odoo config.
Under Windows you should rename the ``unoconv`` file to ``unoconv.py`` and set
the corresponding path for the ``uno_path`` variable. Since it does not work
reliably with the environment variable ``UNO_PATH``.
FFmpeg
-------------
FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video.
To install FFmpeg please follow the instructions (`here <https://www.ffmpeg.org/download.html>`_).
Ghostscript
-------------
Ghostscript is a suite of software based on an interpreter for Adobe Systems PostScript and
Portable Document Format (PDF) page description languages. Its main purposes are the
rasterization or rendering of such page description language files, for the display or printing
of document pages, and the conversion between PostScript and PDF files.
To install Ghostscript please follow the instructions (`here <https://www.ghostscript.com/download.html>`_).
ImageMagick
-------------
ImageMagick can be used to create, edit, compose, or convert bitmap images. It can read and write
images in a variety of formats (over 200) including PNG, JPEG, GIF, HEIC, TIFF, DPX, EXR, WebP,
Postscript, PDF, and SVG. Use ImageMagick to resize, flip, mirror, rotate, distort, shear and
transform images, adjust image colors, apply various special effects, or draw text, lines, polygons,
ellipses and Bezier curves.
To install ImageMagick please follow the instructions (`here <https://www.imagemagick.org/script/download.php>`_).
Wand
-------------
Wand is a ctypes-based simple ImageMagick binding for Python. It is used to interact with ImageMagick via a Python interface.
To install Wand please follow the instructions (`here <http://docs.wand-py.org/en/0.4.1/guide/install.html>`_).
Imageio
-------------
Imageio is a Python library that provides an easy interface to read and write a wide range of image data, including animated images, volumetric data, and scientific formats.
To install Imageio please follow the instructions (`here <https://pypi.org/project/imageio/>`_).
MoviePy
-------------
MoviePy is a Python module for video editing, which can be used for basic operations (like cuts, concatenations, title insertions), video compositing (a.k.a. non-linear editing), video processing, or to create advanced effects. It can read and write the most common video formats, including GIF.
To install MoviePy please follow the instructions (`here <https://zulko.github.io/moviepy/install.html>`_).
Installation
============
To install this module, you need to:
Download the module and add it to your Odoo addons folder. Afterward, log on to
your Odoo server and go to the Apps menu. Trigger the debug mode and update the
list by clicking on the "Update Apps List" link. Now install the module by
clicking on the install button.
Another way to install this module is via the package management for Python
(`PyPI <https://pypi.org/project/pip/>`_).
To install our modules using the package manager make sure
`odoo-autodiscover <https://pypi.org/project/odoo-autodiscover/>`_ is installed
correctly. Then open a console and install the module by entering the following
command:
``pip install --extra-index-url https://nexus.mukit.at/repository/odoo/simple <module>``
The module name consists of the Odoo version and the module name, where
underscores are replaced by a dash.
**Module:**
``odoo<version>-addon-<module_name>``
**Example:**
``sudo -H pip3 install --extra-index-url https://nexus.mukit.at/repository/odoo/simple odoo11-addon-muk-utils``
Once the installation has been successfully completed, the app is already in the
correct folder. Log on to your Odoo server and go to the Apps menu. Trigger the
debug mode and update the list by clicking on the "Update Apps List" link. Now
install the module by clicking on the install button.
The biggest advantage of this variant is that you can now also update the app
using the "pip" command. To do this, enter the following command in your console:
``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple <module>``
When the process is finished, restart your server and update the application in
Odoo. The steps are the same as for the installation only the button has changed
from "Install" to "Upgrade".
You can also view available Apps directly in our `repository <https://nexus.mukit.at/#browse/browse:odoo>`_
and find a more detailed installation guide on our `website <https://mukit.at/page/open-source>`_.
For modules licensed under OPL-1, you will receive access data when you purchase
the module. If the modules were not purchased directly from
`MuK IT <https://www.mukit.at/>`_ please contact our support (support@mukit.at)
with a confirmation of purchase to receive the corresponding access data.
Upgrade
============
To upgrade this module, you need to:
Download the module and add it to your Odoo addons folder. Restart the server
and log on to your Odoo server. Select the Apps menu and upgrade the module by
clicking on the upgrade button.
If you installed the module using the "pip" command, you can also update the
module in the same way. Just type the following command into the console:
``pip install --upgrade --extra-index-url https://nexus.mukit.at/repository/odoo/simple <module>``
When the process is finished, restart your server and update the application in
Odoo, just like you would normally.
Configuration
=============
No additional configuration is needed to use this module.
Usage
=============
This module has no direct visible effect on the system. It provide utility features.
Credits
=======
Contributors
------------
* Mathias Markl <mathias.markl@mukit.at>
Author & Maintainer
-------------------
This module is maintained by the `MuK IT GmbH <https://www.mukit.at/>`_.
MuK IT is an Austrian company specialized in customizing and extending Odoo.
We develop custom solutions for your individual needs to help you focus on
your strength and expertise to grow your business.
If you want to get in touch please contact us via mail
(sale@mukit.at) or visit our website (https://mukit.at).

422
muk_thumbnails/service/thumbnail.py

@ -1,211 +1,211 @@
###################################################################################
#
# 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 sys
import PyPDF2
import base64
import shutil
import urllib
import logging
import tempfile
import mimetypes
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
from odoo.addons.muk_converter.service import unoconv
_logger = logging.getLogger(__name__)
try:
from wand.image import Image
from wand.color import Color
except ImportError:
Image = False
Color = False
_logger.warn('Cannot `import wand`.')
try:
import imageio
except ImportError:
imageio = False
_logger.warn('Cannot `import imageio`.')
try:
from moviepy.editor import VideoFileClip
except ImportError:
VideoFileClip = False
_logger.warn('Cannot `import moviepy`.')
FORMATS = [
"png", "jpg", "jepg"
]
VIDEO_IMPORTS = [
"mp4", "mov", "wav", "avi", "mpg", "flv", "wmv", "webm"
]
PDF_IMPORTS = [
"pdf"
]
WAND_IMPORTS = [
"aai", "art", "arw", "avi", "avs", "bpg", "brf", "cals", "cgm", "cin", "cip", "cmyk", "cmyka", "svg",
"cr2", "crw", "cur", "cut", "dcm", "dcr", "dcx", "dds", "dib", "djvu", "dng", "dot", "dpx", "tim",
"emf", "epdf", "epi", "eps", "eps2", "eps3", "epsf", "epsi", "ept", "exr", "fax", "fig", "fits",
"fpx", "gplt", "gray", "graya", "hdr", "hdr", "heic", "hpgl", "hrz", "html", "ico", "info", "ttf",
"inline", "isobrl", "isobrl6", "jbig", "jng", "jp2", "jpt", "j2c", "j2k", "jxr", "json", "man", "bmp",
"mat", "miff", "mono", "mng", "m2v", "mpeg", "mpc", "mpr", "mrw", "msl", "mtv", "mvg", "nef", "yuv",
"orf", "otb", "p7", "palm", "pam", "clipboard", "pbm", "pcd", "pcds", "pcl", "pcx", "pdb", "jpe",
"pef", "pes", "pfa", "pfb", "pfm", "pgm", "picon", "pict", "pix", "png8", "png00", "png24", "tiff",
"png32", "png48", "png64", "pnm", "ppm", "ps", "ps2", "ps3", "psb", "psd", "ptif", "pwp", "rad",
"raf", "rgb", "rgba", "rgf", "rla", "rle", "sct", "sfw", "sgi", "shtml", "sid", " mrsid", "jpeg",
"sparse-color", "sun", "tga", "ubrl", "ubrl6", "uyvy", "vicar", "viff", "wbmp", "jpg", "png", "uil",
"wdp", "webp", "wmf", "wpg", "x", "xbm", "xcf", "xpm", "xwd", "x3f", "ycbcr", "ycbcra", "bmp3", "bmp2",
]
def formats():
return FORMATS
def imports():
return VIDEO_IMPORTS + PDF_IMPORTS + WAND_IMPORTS + unoconv.IMPORTS
def create_thumbnail(binary, mimetype=None, filename=None, export="binary", format="png", page=0, frame=0,
animation=False, video_resize={'width': 256}, image_resize='256x256>', image_crop=None):
"""
Converts a thumbnail for a given file.
: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 format: Specify the output format for the document.
:param page: Specifies the page if the file has several pages, e.g. if it is a PDF file.
:param frame: Specifies the frame if the file has several frames, e.g. if it is a video file.
:param animation: In this case, the parameter frame specifies the number of frames.
:param video_resize: Specify to resize the output image.
:param image_resize: Specify to resize the output image.
:param image_crop: Specify to crop the output image.
: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 (VIDEO_IMPORTS + PDF_IMPORTS + WAND_IMPORTS + unoconv.IMPORTS):
raise ValueError("Invalid import format.")
if not imageio or not Image or not VideoFileClip:
raise ValueError("Some libraries couldn't be imported.")
image_data = None
image_extension = extension
if extension in WAND_IMPORTS:
image_data = binary
elif not image_data and (extension in PDF_IMPORTS or extension in unoconv.IMPORTS):
pdf_data = binary if extension in PDF_IMPORTS else None
if not pdf_data:
image_extension = "pdf"
pdf_data = unoconv.convert_binary(binary, mimetype, filename)
reader = PyPDF2.PdfFileReader(io.BytesIO(pdf_data))
writer = PyPDF2.PdfFileWriter()
if reader.getNumPages() >= page:
writer.addPage(reader.getPage(page))
else:
writer.addPage(reader.getPage(0))
pdf_bytes = io.BytesIO()
writer.write(pdf_bytes)
image_data = pdf_bytes.getvalue()
if image_data:
with Image(blob=image_data, format=image_extension) as thumbnail:
thumbnail.format = format
if image_extension == "pdf":
thumbnail.background_color = Color('white')
thumbnail.alpha_channel = 'remove'
if image_resize:
thumbnail.transform(resize=image_resize)
if image_crop:
thumbnail.transform(crop=image_crop)
if export == 'file':
return io.BytesIO(thumbnail.make_blob())
elif export == 'base64':
return base64.b64encode(thumbnail.make_blob())
else:
return thumbnail.make_blob()
elif extension in VIDEO_IMPORTS:
tmp_dir = tempfile.mkdtemp()
try:
tmp_wpath = os.path.join(tmp_dir, "tmpfile.%s" % extension)
if os.name == 'nt':
tmp_wpath = tmp_wpath.replace("\\", "/")
with closing(open(tmp_wpath, 'wb')) as file:
file.write(binary)
clip = VideoFileClip(tmp_wpath)
try:
tmp_opath = os.path.join(tmp_dir, "output.%s" % format)
clip.resize(**video_resize)
if animation:
files = []
current_frame = 0
while clip.duration > current_frame and current_frame < frame:
filename = os.path.join(tmp_dir, "output_%s.png" % frame)
clip.save_frame(filename, t=frame)
files.append(filename)
frame += 0.25
tmp_opath = os.path.join(tmp_dir, "output.gif")
with imageio.get_writer(tmp_opath, fps=5, mode='I') as writer:
for filename in files:
image = imageio.imread(filename)
writer.append_data(image)
elif clip.duration > int(frame):
clip.save_frame(tmp_opath, t=int(frame))
else:
clip.save_frame(tmp_opath, t=int(0))
if os.path.isfile(tmp_opath):
with open(tmp_opath, 'rb') as file:
if export == 'file':
return io.BytesIO(file.read())
elif export == 'base64':
return base64.b64encode(file.read())
else:
return file.read()
else:
raise ValueError("No output could be created from the video.")
finally:
try:
clip.reader.close()
del clip.reader
if clip.audio != None:
clip.audio.reader.close_proc()
del clip.audio
del clip
except Exception as e:
sys.exc_clear()
finally:
try:
shutil.rmtree(tmp_dir)
except PermissionError:
_logger.warn("Temporary directory could not be deleted.")
else:
raise ValueError("No output could be generated.")
###################################################################################
#
# 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 sys
import PyPDF2
import base64
import shutil
import urllib
import logging
import tempfile
import mimetypes
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
from odoo.addons.muk_converter.service import unoconv
_logger = logging.getLogger(__name__)
try:
from wand.image import Image
from wand.color import Color
except ImportError:
Image = False
Color = False
_logger.warn('Cannot `import wand`.')
try:
import imageio
except ImportError:
imageio = False
_logger.warn('Cannot `import imageio`.')
try:
from moviepy.editor import VideoFileClip
except ImportError:
VideoFileClip = False
_logger.warn('Cannot `import moviepy`.')
FORMATS = [
"png", "jpg", "jepg"
]
VIDEO_IMPORTS = [
"mp4", "mov", "wav", "avi", "mpg", "flv", "wmv", "webm"
]
PDF_IMPORTS = [
"pdf"
]
WAND_IMPORTS = [
"aai", "art", "arw", "avi", "avs", "bpg", "brf", "cals", "cgm", "cin", "cip", "cmyk", "cmyka", "svg",
"cr2", "crw", "cur", "cut", "dcm", "dcr", "dcx", "dds", "dib", "djvu", "dng", "dot", "dpx", "tim",
"emf", "epdf", "epi", "eps", "eps2", "eps3", "epsf", "epsi", "ept", "exr", "fax", "fig", "fits",
"fpx", "gplt", "gray", "graya", "hdr", "hdr", "heic", "hpgl", "hrz", "html", "ico", "info", "ttf",
"inline", "isobrl", "isobrl6", "jbig", "jng", "jp2", "jpt", "j2c", "j2k", "jxr", "json", "man", "bmp",
"mat", "miff", "mono", "mng", "m2v", "mpeg", "mpc", "mpr", "mrw", "msl", "mtv", "mvg", "nef", "yuv",
"orf", "otb", "p7", "palm", "pam", "clipboard", "pbm", "pcd", "pcds", "pcl", "pcx", "pdb", "jpe",
"pef", "pes", "pfa", "pfb", "pfm", "pgm", "picon", "pict", "pix", "png8", "png00", "png24", "tiff",
"png32", "png48", "png64", "pnm", "ppm", "ps", "ps2", "ps3", "psb", "psd", "ptif", "pwp", "rad",
"raf", "rgb", "rgba", "rgf", "rla", "rle", "sct", "sfw", "sgi", "shtml", "sid", " mrsid", "jpeg",
"sparse-color", "sun", "tga", "ubrl", "ubrl6", "uyvy", "vicar", "viff", "wbmp", "jpg", "png", "uil",
"wdp", "webp", "wmf", "wpg", "x", "xbm", "xcf", "xpm", "xwd", "x3f", "ycbcr", "ycbcra", "bmp3", "bmp2",
]
def formats():
return FORMATS
def imports():
return VIDEO_IMPORTS + PDF_IMPORTS + WAND_IMPORTS + unoconv.UNOCONV_IMPORTS
def create_thumbnail(binary, mimetype=None, filename=None, export="binary", format="png", page=0, frame=0,
animation=False, video_resize={'width': 256}, image_resize='256x256>', image_crop=None):
"""
Converts a thumbnail for a given file.
: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 format: Specify the output format for the document.
:param page: Specifies the page if the file has several pages, e.g. if it is a PDF file.
:param frame: Specifies the frame if the file has several frames, e.g. if it is a video file.
:param animation: In this case, the parameter frame specifies the number of frames.
:param video_resize: Specify to resize the output image.
:param image_resize: Specify to resize the output image.
:param image_crop: Specify to crop the output image.
: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 (VIDEO_IMPORTS + PDF_IMPORTS + WAND_IMPORTS + unoconv.UNOCONV_IMPORTS):
raise ValueError("Invalid import format.")
if not imageio or not Image or not VideoFileClip:
raise ValueError("Some libraries couldn't be imported.")
image_data = None
image_extension = extension
if extension in WAND_IMPORTS:
image_data = binary
elif not image_data and (extension in PDF_IMPORTS or extension in unoconv.UNOCONV_IMPORTS):
pdf_data = binary if extension in PDF_IMPORTS else None
if not pdf_data:
image_extension = "pdf"
pdf_data = unoconv.unoconv.convert(binary, mimetype, filename)
reader = PyPDF2.PdfFileReader(io.BytesIO(pdf_data))
writer = PyPDF2.PdfFileWriter()
if reader.getNumPages() >= page:
writer.addPage(reader.getPage(page))
else:
writer.addPage(reader.getPage(0))
pdf_bytes = io.BytesIO()
writer.write(pdf_bytes)
image_data = pdf_bytes.getvalue()
if image_data:
with Image(blob=image_data, format=image_extension) as thumbnail:
thumbnail.format = format
if image_extension == "pdf":
thumbnail.background_color = Color('white')
thumbnail.alpha_channel = 'remove'
if image_resize:
thumbnail.transform(resize=image_resize)
if image_crop:
thumbnail.transform(crop=image_crop)
if export == 'file':
return io.BytesIO(thumbnail.make_blob())
elif export == 'base64':
return base64.b64encode(thumbnail.make_blob())
else:
return thumbnail.make_blob()
elif extension in VIDEO_IMPORTS:
tmp_dir = tempfile.mkdtemp()
try:
tmp_wpath = os.path.join(tmp_dir, "tmpfile.%s" % extension)
if os.name == 'nt':
tmp_wpath = tmp_wpath.replace("\\", "/")
with closing(open(tmp_wpath, 'wb')) as file:
file.write(binary)
clip = VideoFileClip(tmp_wpath)
try:
tmp_opath = os.path.join(tmp_dir, "output.%s" % format)
clip.resize(**video_resize)
if animation:
files = []
current_frame = 0
while clip.duration > current_frame and current_frame < frame:
filename = os.path.join(tmp_dir, "output_%s.png" % frame)
clip.save_frame(filename, t=frame)
files.append(filename)
frame += 0.25
tmp_opath = os.path.join(tmp_dir, "output.gif")
with imageio.get_writer(tmp_opath, fps=5, mode='I') as writer:
for filename in files:
image = imageio.imread(filename)
writer.append_data(image)
elif clip.duration > int(frame):
clip.save_frame(tmp_opath, t=int(frame))
else:
clip.save_frame(tmp_opath, t=int(0))
if os.path.isfile(tmp_opath):
with open(tmp_opath, 'rb') as file:
if export == 'file':
return io.BytesIO(file.read())
elif export == 'base64':
return base64.b64encode(file.read())
else:
return file.read()
else:
raise ValueError("No output could be created from the video.")
finally:
try:
clip.reader.close()
del clip.reader
if clip.audio != None:
clip.audio.reader.close_proc()
del clip.audio
del clip
except Exception as e:
sys.exc_clear()
finally:
try:
shutil.rmtree(tmp_dir)
except PermissionError:
_logger.warn("Temporary directory could not be deleted.")
else:
raise ValueError("No output could be generated.")
Loading…
Cancel
Save