Example #1
0
 def get_mimetypes_mapping(cls) -> typing.List[MimetypeMapping]:
     mimetypes_mapping = [MimetypeMapping("image/webp", ".webp")
                          ]  # type: typing.List[MimetypeMapping]
     mimetypes_mapping = (mimetypes_mapping +
                          cls.SUPPORTED_RAW_CAMERA_MIMETYPE_MAPPING +
                          cls.SUPPORTED_HEIC_MIMETYPE_MAPPING)
     return mimetypes_mapping
Example #2
0
class ImagePreviewBuilderSketch(PreviewBuilder):
    SKETCH_MIMETYPES_MAPPING = [
        MimetypeMapping("application/sketch", ".sketch")
    ]

    @classmethod
    def get_label(cls) -> str:
        return "Images generator from sketch files"

    @classmethod
    def get_supported_mimetypes(cls) -> typing.List[str]:
        mimetypes = []
        for mimetype_mapping in cls.get_mimetypes_mapping():
            mimetypes.append(mimetype_mapping.mimetype)
        return mimetypes

    @classmethod
    def get_mimetypes_mapping(cls) -> typing.List[MimetypeMapping]:
        return cls.SKETCH_MIMETYPES_MAPPING

    def build_jpeg_preview(
        self,
        file_path: str,
        preview_name: str,
        cache_path: str,
        page_id: int,
        extension: str = ".jpg",
        size: ImgDims = None,
        mimetype: str = "",
    ) -> None:
        if not size:
            size = self.default_size
        with tempfile.TemporaryDirectory(
                prefix="preview-generator-") as tmp_dir:
            with open(file_path, "rb") as filestream:
                zip = zipfile.ZipFile(filestream)
                zip.extract("previews/preview.png", tmp_dir)
                zip.close()

                ImagePreviewBuilderPillow().build_jpeg_preview(
                    tmp_dir + "/previews/preview.png",
                    preview_name,
                    cache_path,
                    page_id,
                    extension,
                    size,
                    mimetype,
                )

    def has_jpeg_preview(self) -> bool:
        return True

    def get_page_number(self,
                        file_path: str,
                        preview_name: str,
                        cache_path: str,
                        mimetype: str = "") -> int:
        return 1
Example #3
0
class ImagePreviewBuilderVtk(PreviewBuilder):
    PLY_MIMETYPES_MAPPING = [MimetypeMapping("application/ply", ".ply")]
    OBJ_MIMETYPES_MAPPING = [
        MimetypeMapping("application/wobj", ".obj"),
        MimetypeMapping("application/object", ".obj"),
        MimetypeMapping("model/obj", ".obj"),
    ]
    STL_MIMETYPES_MAPPING = [
        MimetypeMapping("application/sla", ".stl"),
        MimetypeMapping("application/vnd.ms-pki.stl", ".stl"),
        MimetypeMapping("application/x-navistyle", ".stl"),
        MimetypeMapping("model/stl", ".stl"),
    ]

    @classmethod
    def get_label(cls) -> str:
        return "Images generator from 3d file - based on Vtk"

    @classmethod
    def get_supported_mimetypes(cls) -> typing.List[str]:
        mimetypes = []
        for mimetype_mapping in cls.get_mimetypes_mapping():
            mimetypes.append(mimetype_mapping.mimetype)
        return mimetypes

    @classmethod
    def get_mimetypes_mapping(cls) -> typing.List[MimetypeMapping]:
        return cls.STL_MIMETYPES_MAPPING + cls.OBJ_MIMETYPES_MAPPING + cls.PLY_MIMETYPES_MAPPING

    @classmethod
    def check_dependencies(cls) -> None:
        if not vtk_installed:
            raise BuilderDependencyNotFound(
                "this builder requires vtk to be available")

    @classmethod
    def dependencies_versions(cls) -> typing.Optional[str]:
        vtk_version = vtkVersion()
        return "VTK version :{}".format(vtk_version.GetVTKVersion())

    @classmethod
    def _get_vtk_reader(cls, mimetype: str) -> "vtkAbstractPolyDataReader":
        if mimetype in [
                mapping.mimetype for mapping in cls.STL_MIMETYPES_MAPPING
        ]:
            return vtkSTLReader()
        elif mimetype in [
                mapping.mimetype for mapping in cls.OBJ_MIMETYPES_MAPPING
        ]:
            return vtkOBJReader()
        elif mimetype in [
                mapping.mimetype for mapping in cls.PLY_MIMETYPES_MAPPING
        ]:
            return vtkPLYReader()
        else:
            raise UnsupportedMimeType(
                "Unsupported mimetype: {}".format(mimetype))

    def build_jpeg_preview(
        self,
        file_path: str,
        preview_name: str,
        cache_path: str,
        page_id: int,
        extension: str = ".jpg",
        size: ImgDims = None,
        mimetype: str = "",
    ) -> None:
        if not size:
            size = self.default_size

        colors = vtkNamedColors()

        if not mimetype:
            guessed_mimetype, _ = mimetypes_storage.guess_type(file_path,
                                                               strict=False)
            # INFO - G.M - 2019-11-22 - guessed_mimetype can be None
            mimetype = guessed_mimetype or ""
        reader = self._get_vtk_reader(mimetype)
        reader.SetFileName(file_path)

        mapper = vtkPolyDataMapper()
        mapper.SetInputConnection(reader.GetOutputPort())

        actor = vtkActor()
        actor.SetMapper(mapper)

        rotation = (-70, 0, 45)
        R_x, R_y, R_z = rotation  # TODO set a good looking default orientation
        actor.RotateX(R_x)
        actor.RotateY(R_y)
        actor.RotateZ(R_z)

        # Create a rendering window and renderer
        ren = vtkRenderer()
        renWin = vtkRenderWindow()
        renWin.OffScreenRenderingOn()
        renWin.AddRenderer(ren)
        renWin.SetSize(size.width, size.height)
        ren.SetBackground(colors.GetColor3d("white"))

        # Assign actor to the renderer
        ren.AddActor(actor)

        renWin.Render()

        # Write image
        windowto_image_filter = vtkWindowToImageFilter()
        windowto_image_filter.SetInput(renWin)
        # windowto_image_filter.SetScale(scale)  # image scale
        windowto_image_filter.SetInputBufferTypeToRGBA()

        with tempfile.NamedTemporaryFile("w+b",
                                         prefix="preview-generator-",
                                         suffix=".png") as tmp_png:
            writer = vtkPNGWriter()
            writer.SetFileName(tmp_png.name)
            writer.SetInputConnection(windowto_image_filter.GetOutputPort())
            writer.Write()

            return ImagePreviewBuilderPillow().build_jpeg_preview(
                tmp_png.name, preview_name, cache_path, page_id, extension,
                size, mimetype)

    def has_jpeg_preview(self) -> bool:
        return True

    def get_page_number(self,
                        file_path: str,
                        preview_name: str,
                        cache_path: str,
                        mimetype: str = "") -> int:
        return 1
Example #4
0
class ImagePreviewBuilderRawpy(ImagePreviewBuilder):
    weight = 150

    SUPPORTED_RAW_CAMERA_MIMETYPE_MAPPING = [
        MimetypeMapping("image/x-sony-arw", ".arw"),
        MimetypeMapping("image/x-adobe-dng", ".dng"),
        MimetypeMapping("image/x-sony-sr2", ".sr2"),
        MimetypeMapping("image/x-sony-srf", ".srf"),
        MimetypeMapping("image/x-sigma-x3f", ".x3f"),
        MimetypeMapping("image/x-canon-crw", ".crw"),
        MimetypeMapping("image/x-canon-cr2", ".cr2"),
        MimetypeMapping("image/x-epson-erf", ".erf"),
        MimetypeMapping("image/x-fuji-raf", ".raf"),
        MimetypeMapping("image/x-nikon-nef", ".nef"),
        MimetypeMapping("image/x-olympus-orf", ".orf"),
        MimetypeMapping("image/x-panasonic-raw", ".raw"),
        MimetypeMapping("image/x-panasonic-rw2", ".rw2"),
        MimetypeMapping("image/x-pentax-pef", ".pef"),
        MimetypeMapping("image/x-kodak-dcr", ".dcr"),
        MimetypeMapping("image/x-kodak-k25", ".k25"),
        MimetypeMapping("image/x-kodak-kdc", ".kdc"),
        MimetypeMapping("image/x-minolta-mrw", ".mrw"),
        MimetypeMapping("image/x-samsung-srw", ".srw"),
    ]

    @classmethod
    def get_label(cls) -> str:
        return "Rawpy Preview Builder"

    @classmethod
    def get_supported_mimetypes(cls) -> typing.List[str]:
        mimes = []
        for mimetype_mapping in cls.SUPPORTED_RAW_CAMERA_MIMETYPE_MAPPING:
            mimes.append(mimetype_mapping.mimetype)
        return mimes

    @classmethod
    def get_mimetypes_mapping(cls) -> typing.List[MimetypeMapping]:
        return cls.SUPPORTED_RAW_CAMERA_MIMETYPE_MAPPING

    @classmethod
    def check_dependencies(cls) -> None:
        if not rawpy_installed:
            raise BuilderDependencyNotFound("this builder requires rawpy to be available")

    def build_jpeg_preview(
        self,
        file_path: str,
        preview_name: str,
        cache_path: str,
        page_id: int,
        extension: str = ".jpeg",
        size: ImgDims = None,
        mimetype: str = "",
    ) -> None:
        if not size:
            size = self.default_size
        with tempfile.NamedTemporaryFile(
            "w+b", prefix="preview-generator", suffix=".tiff"
        ) as tmp_tiff:
            with rawpy.imread(file_path) as raw:
                processed_image = raw.postprocess(use_auto_wb=True)
                with Image.from_array(processed_image) as img:
                    img.save(filename=tmp_tiff.name)

            return ImagePreviewBuilderWand().build_jpeg_preview(
                tmp_tiff.name, preview_name, cache_path, page_id, extension, size, mimetype
            )
Example #5
0
class ImagePreviewBuilderIMConvert(ImagePreviewBuilder):

    MIMETYPES = []  # type: typing.List[str]
    # TODO - G.M - 2019-11-21 - find better storage solution for mimetype mapping
    # dict and/or list.
    # see https://github.com/algoo/preview-generator/pull/148#discussion_r346381508
    SUPPORTED_RAW_CAMERA_MIMETYPE_MAPPING = [
        MimetypeMapping("image/x-sony-arw", ".arw"),
        MimetypeMapping("image/x-adobe-dng", ".dng"),
        MimetypeMapping("image/x-sony-sr2", ".sr2"),
        MimetypeMapping("image/x-sony-srf", ".srf"),
        MimetypeMapping("image/x-sigma-x3f", ".x3f"),
        MimetypeMapping("image/x-canon-crw", ".crw"),
        MimetypeMapping("image/x-canon-cr2", ".cr2"),
        MimetypeMapping("image/x-epson-erf", ".erf"),
        MimetypeMapping("image/x-fuji-raf", ".raf"),
        MimetypeMapping("image/x-nikon-nef", ".nef"),
        MimetypeMapping("image/x-olympus-orf", ".orf"),
        MimetypeMapping("image/x-panasonic-raw", ".raw"),
        MimetypeMapping("image/x-panasonic-rw2", ".rw2"),
        MimetypeMapping("image/x-pentax-pef", ".pef"),
        MimetypeMapping("image/x-kodak-dcr", ".dcr"),
        MimetypeMapping("image/x-kodak-k25", ".k25"),
        MimetypeMapping("image/x-kodak-kdc", ".kdc"),
        MimetypeMapping("image/x-minolta-mrw", ".mrw"),
    ]

    SUPPORTED_HEIC_MIMETYPE_MAPPING = [
        MimetypeMapping("image/heic", ".heic"),
        MimetypeMapping("image/heic", ".heif"),
    ]
    """ IM means Image Magick"""
    @classmethod
    def get_label(cls) -> str:
        return "Images - based on convert command (Image magick)"

    @classmethod
    def __load_mimetypes(cls) -> typing.List[str]:
        """
        Load supported mimetypes from WAND library
        :return: list of supported mime types
        """

        mimes = imagemagick_supported_mimes()  # type: typing.List[str]
        # HACK - G.M - 2019-10-31 - Handle raw format only if ufraw-batch is installed as most common
        # default imagemagick configuration delegate raw format to ufraw-batch.
        if executable_is_available("ufraw-batch"):
            for mimetype_mapping in cls.SUPPORTED_RAW_CAMERA_MIMETYPE_MAPPING:
                mimes.append(mimetype_mapping.mimetype)

        # HACK - G.M - 2019-11-14 - disable support for postscript file in imagemagick to use
        # pillow instead
        mimes.remove("application/postscript")
        mimes.append("application/x-xcf")
        mimes.append("image/x-xcf")
        return mimes

    @classmethod
    def get_supported_mimetypes(cls) -> typing.List[str]:
        """
        :return: list of supported mime types
        """
        if len(ImagePreviewBuilderIMConvert.MIMETYPES) == 0:
            ImagePreviewBuilderIMConvert.MIMETYPES = cls.__load_mimetypes()
        return ImagePreviewBuilderIMConvert.MIMETYPES

    @classmethod
    def get_mimetypes_mapping(cls) -> typing.List[MimetypeMapping]:
        mimetypes_mapping = []  # type: typing.List[MimetypeMapping]
        mimetypes_mapping = (mimetypes_mapping +
                             cls.SUPPORTED_RAW_CAMERA_MIMETYPE_MAPPING +
                             cls.SUPPORTED_HEIC_MIMETYPE_MAPPING)
        return mimetypes_mapping

    @classmethod
    def check_dependencies(cls) -> None:
        if not executable_is_available("convert"):
            raise BuilderDependencyNotFound(
                "this builder requires convert to be available")

    @classmethod
    def dependencies_versions(cls) -> typing.Optional[str]:
        return "{} from {}".format(
            check_output(["convert", "--version"],
                         universal_newlines=True).split("\n")[0],
            which("convert"),
        )

    def build_jpeg_preview(
        self,
        file_path: str,
        preview_name: str,
        cache_path: str,
        page_id: int,
        extension: str = ".jpg",
        size: ImgDims = None,
        mimetype: str = "",
    ) -> None:
        if not size:
            size = self.default_size
        # inkscape tesselation-P3.svg  -e
        with tempfile.NamedTemporaryFile("w+b",
                                         prefix="preview-generator-",
                                         suffix=".png") as tmp_png:
            build_png_result_code = self._imagemagick_convert(
                source_path=file_path,
                dest_path=tmp_png.name,
                mimetype=mimetype)

            if build_png_result_code != 0:
                raise IntermediateFileBuildingFailed(
                    "Building PNG intermediate file using convert "
                    "failed with status {}".format(build_png_result_code))

            return ImagePreviewBuilderPillow().build_jpeg_preview(
                tmp_png.name, preview_name, cache_path, page_id, extension,
                size)

    def _imagemagick_convert(self,
                             source_path: str,
                             dest_path: str,
                             mimetype: typing.Optional[str] = None) -> int:
        """
        Try convert using both explicit or implicit input type convert.
        """
        assert mimetype != ""
        # INFO - G.M - 2019-11-14 - use explicit input type to clarify conversion for imagemagick
        do_an_explicit_convert = False
        input_file_extension = ""  # type: str
        if mimetype is not None:
            input_file_extension = mimetypes_storage.guess_extension(
                mimetype, strict=False) or ""
            if input_file_extension:
                do_an_explicit_convert = True

        if do_an_explicit_convert:
            explicit_source_path = "{}:{}".format(
                input_file_extension.lstrip("."), source_path)
            build_image_result_code = check_call(
                [
                    "convert", explicit_source_path, "-layers", "merge",
                    dest_path
                ],
                stdout=DEVNULL,
                stderr=STDOUT,
            )
            # INFO - G.M - 2019-11-14 - if explicit convert failed, fallback to
            # implicit input type convert
            if build_image_result_code != 0:
                build_image_result_code = check_call(
                    ["convert", source_path, "-layers", "merge", dest_path],
                    stdout=DEVNULL,
                    stderr=STDOUT,
                )
        else:
            build_image_result_code = check_call(
                ["convert", source_path, "-layers", "merge", dest_path],
                stdout=DEVNULL,
                stderr=STDOUT,
            )

        return build_image_result_code
Example #6
0
 def get_mimetypes_mapping(cls) -> typing.List[MimetypeMapping]:
     return [
         MimetypeMapping(
             "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ".xlsx"
         )
     ]
Example #7
0
class ImagePreviewBuilderWand(ImagePreviewBuilder):

    weight = 30
    MIMETYPES = []  # type: typing.List[str]
    # TODO - G.M - 2019-11-21 - find better storage solution for mimetype mapping
    # dict and/or list.
    # see https://github.com/algoo/preview-generator/pull/148#discussion_r346381508
    SUPPORTED_RAW_CAMERA_MIMETYPE_MAPPING = [
        MimetypeMapping("image/x-sony-arw", ".arw"),
        MimetypeMapping("image/x-adobe-dng", ".dng"),
        MimetypeMapping("image/x-sony-sr2", ".sr2"),
        MimetypeMapping("image/x-sony-srf", ".srf"),
        MimetypeMapping("image/x-sigma-x3f", ".x3f"),
        MimetypeMapping("image/x-canon-crw", ".crw"),
        MimetypeMapping("image/x-canon-cr2", ".cr2"),
        MimetypeMapping("image/x-epson-erf", ".erf"),
        MimetypeMapping("image/x-fuji-raf", ".raf"),
        MimetypeMapping("image/x-nikon-nef", ".nef"),
        MimetypeMapping("image/x-olympus-orf", ".orf"),
        MimetypeMapping("image/x-panasonic-raw", ".raw"),
        MimetypeMapping("image/x-panasonic-rw2", ".rw2"),
        MimetypeMapping("image/x-pentax-pef", ".pef"),
        MimetypeMapping("image/x-kodak-dcr", ".dcr"),
        MimetypeMapping("image/x-kodak-k25", ".k25"),
        MimetypeMapping("image/x-kodak-kdc", ".kdc"),
        MimetypeMapping("image/x-minolta-mrw", ".mrw"),
    ]

    SUPPORTED_HEIC_MIMETYPE_MAPPING = [
        MimetypeMapping("image/heic", ".heic"),
        MimetypeMapping("image/heic", ".heif"),
    ]

    def __init__(
        self,
        quality: int = DEFAULT_JPEG_QUALITY,
        progressive: bool = DEFAULT_JPEG_PROGRESSIVE,
    ):
        super().__init__()
        self.quality = quality
        self.progressive = progressive

    @classmethod
    def get_label(cls) -> str:
        return "Images - based on WAND (image magick)"

    @classmethod
    def dependencies_versions(cls) -> typing.Optional[str]:
        return "wand {} from {}".format(wand.version.VERSION,
                                        ", ".join(wand.__path__))

    @classmethod
    def __load_mimetypes(cls) -> typing.List[str]:
        """
        Load supported mimetypes from WAND library
        :return: list of supported mime types
        """

        mimes = imagemagick_supported_mimes()  # type: typing.List[str]
        # HACK - G.M - 2019-10-31 - Handle raw format only if ufraw-batch is installed as most common
        # default imagemagick configuration delegate raw format to ufraw-batch.
        if executable_is_available("ufraw-batch"):
            for mimetype_mapping in cls.SUPPORTED_RAW_CAMERA_MIMETYPE_MAPPING:
                mimes.append(mimetype_mapping.mimetype)
        if executable_is_available("dwebp"):
            mimes.append("image/webp")
        return mimes

    @classmethod
    def get_mimetypes_mapping(cls) -> typing.List[MimetypeMapping]:
        mimetypes_mapping = [MimetypeMapping("image/webp", ".webp")
                             ]  # type: typing.List[MimetypeMapping]
        mimetypes_mapping = (mimetypes_mapping +
                             cls.SUPPORTED_RAW_CAMERA_MIMETYPE_MAPPING +
                             cls.SUPPORTED_HEIC_MIMETYPE_MAPPING)
        return mimetypes_mapping

    @classmethod
    def check_dependencies(cls) -> None:
        if not executable_is_available("convert"):
            raise BuilderDependencyNotFound(
                "this builder requires convert to be available")

    @classmethod
    def get_supported_mimetypes(cls) -> typing.List[str]:
        """
        :return: list of supported mime types
        """
        if len(ImagePreviewBuilderWand.MIMETYPES) == 0:
            ImagePreviewBuilderWand.MIMETYPES = cls.__load_mimetypes()
        mimetypes = ImagePreviewBuilderWand.MIMETYPES

        extra_mimetypes = ["application/x-xcf", "image/x-xcf"]
        mimetypes.extend(extra_mimetypes)

        return mimetypes

    def build_jpeg_preview(
        self,
        file_path: str,
        preview_name: str,
        cache_path: str,
        page_id: int,
        extension: str = ".jpeg",
        size: ImgDims = None,
        mimetype: str = "",
    ) -> None:
        if not size:
            size = self.default_size
        preview_name = preview_name + extension
        dest_path = os.path.join(cache_path, preview_name)
        self.image_to_jpeg_wand(file_path, size, dest_path, mimetype=mimetype)

    def image_to_jpeg_wand(self, file_path: str, preview_dims: ImgDims,
                           dest_path: str,
                           mimetype: typing.Optional[str]) -> None:
        try:
            with self._convert_image(file_path, preview_dims) as img:
                img.save(filename=dest_path)
        except (CoderError, CoderFatalError, CoderWarning) as e:
            assert mimetype
            file_ext = mimetypes_storage.guess_extension(mimetype,
                                                         strict=False) or ""
            if file_ext:
                file_path = file_ext.lstrip(".") + ":" + file_path
                with self._convert_image(file_path, preview_dims) as img:
                    img.save(filename=dest_path)
            else:
                raise e

    def _convert_image(self, file_path: str, preview_dims: ImgDims) -> Image:
        """
        refer: https://legacy.imagemagick.org/Usage/thumbnails/
        like cmd: convert -layers merge  -background white -thumbnail widthxheight \
        -auto-orient -quality 85 -interlace plane input.jpeg output.jpeg
        """

        img = Image(filename=file_path)
        resize_dim = compute_resize_dims(dims_in=ImgDims(width=img.width,
                                                         height=img.height),
                                         dims_out=preview_dims)

        img.auto_orient()
        img.iterator_reset()
        img.background_color = Color("white")
        img.merge_layers("merge")

        if self.progressive:
            img.interlace_scheme = "plane"

        img.compression_quality = self.quality

        img.thumbnail(resize_dim.width, resize_dim.height)

        return img
class ImagePreviewBuilderDrawio(PreviewBuilder):
    DRAWIO_MIMETYPES_MAPPING = [
        MimetypeMapping("application/drawio", ".drawio")
    ]

    @classmethod
    def check_dependencies(cls) -> None:
        if not executable_is_available("xvfb-run"):
            raise BuilderDependencyNotFound(
                "this builder requires xvfb-run to be available")

        if not executable_is_available("/usr/bin/drawio"):
            raise BuilderDependencyNotFound(
                "this builder requires drawio to be available")

    @classmethod
    def get_label(cls) -> str:
        return "Images generator from Drawio files"

    @classmethod
    def get_supported_mimetypes(cls) -> typing.List[str]:
        mimetypes = []
        for mimetype_mapping in cls.get_mimetypes_mapping():
            mimetypes.append(mimetype_mapping.mimetype)
        return mimetypes

    @classmethod
    def get_mimetypes_mapping(cls) -> typing.List[MimetypeMapping]:
        return cls.DRAWIO_MIMETYPES_MAPPING

    def build_jpeg_preview(
        self,
        file_path: str,
        preview_name: str,
        cache_path: str,
        page_id: int,
        extension: str = ".jpg",
        size: ImgDims = None,
        mimetype: str = "",
    ) -> None:
        if not size:
            size = self.default_size
        with tempfile.NamedTemporaryFile("w+b",
                                         prefix="preview-generator-",
                                         suffix=".jpg") as tmp_jpg:
            with Xvfb():
                build_jpg_result_code = check_call(
                    [
                        "/usr/bin/drawio",
                        "--no-sandbox",
                        "-x",
                        "-f",
                        "jpg",
                        "-o",
                        tmp_jpg.name,
                        file_path,
                    ],
                    stdout=DEVNULL,
                    stderr=STDOUT,
                    timeout=30,
                )

            if build_jpg_result_code != 0:
                raise IntermediateFileBuildingFailed(
                    "Building JPG intermediate file using drawio "
                    "failed with status {}".format(build_jpg_result_code))

            ImagePreviewBuilderPillow().build_jpeg_preview(
                tmp_jpg.name,
                preview_name,
                cache_path,
                page_id,
                extension,
                size,
                mimetype,
            )

    def has_jpeg_preview(self) -> bool:
        return True

    def get_page_number(self,
                        file_path: str,
                        preview_name: str,
                        cache_path: str,
                        mimetype: str = "") -> int:
        return 1
Example #9
0
class ImagePreviewBuilderDrawio(PreviewBuilder):
    DRAWIO_MIMETYPES_MAPPING = [
        MimetypeMapping("application/drawio", ".drawio")
    ]
    weight = 120

    @classmethod
    def check_dependencies(cls) -> None:
        if not xvfbwrapper_installed:
            raise BuilderDependencyNotFound(
                "this builder requires xvfbwrapper")
        if not executable_is_available("xvfb-run"):
            raise BuilderDependencyNotFound(
                "this builder requires xvfb-run to be available")

        if not executable_is_available("drawio"):
            raise BuilderDependencyNotFound(
                "this builder requires drawio to be available")

    @classmethod
    def get_label(cls) -> str:
        return "Images generator from Drawio files"

    @classmethod
    def get_supported_mimetypes(cls) -> typing.List[str]:
        mimetypes = []
        for mimetype_mapping in cls.get_mimetypes_mapping():
            mimetypes.append(mimetype_mapping.mimetype)
        return mimetypes

    @classmethod
    def get_mimetypes_mapping(cls) -> typing.List[MimetypeMapping]:
        return cls.DRAWIO_MIMETYPES_MAPPING

    def build_jpeg_preview(
        self,
        file_path: str,
        preview_name: str,
        cache_path: str,
        page_id: int,
        extension: str = ".jpg",
        size: ImgDims = None,
        mimetype: str = "",
    ) -> None:
        if not size:
            size = self.default_size
        with tempfile.NamedTemporaryFile("w+b",
                                         prefix="preview-generator-",
                                         suffix=".jpg") as tmp_jpg:
            with Xvfb():
                build_jpg_result_code = check_call(
                    [
                        "drawio",
                        "-x",
                        "-f",
                        "jpg",
                        "-o",
                        tmp_jpg.name,
                        file_path,
                        # INFO - G.M - 12/11/2021 - Add no-sandbox at the end as putting it before
                        # doesn't work, see:
                        # https://github.com/jgraph/drawio-desktop/issues/249#issuecomment-695179747
                        "--no-sandbox",
                    ],
                    stdout=DEVNULL,
                    stderr=STDOUT,
                    timeout=30,
                )

            if build_jpg_result_code != 0:
                raise IntermediateFileBuildingFailed(
                    "Building JPG intermediate file using drawio "
                    "failed with status {}".format(build_jpg_result_code))

            ImagePreviewBuilderWand().build_jpeg_preview(
                tmp_jpg.name, preview_name, cache_path, page_id, extension,
                size, mimetype)

    def has_jpeg_preview(self) -> bool:
        return True

    def get_page_number(self,
                        file_path: str,
                        preview_name: str,
                        cache_path: str,
                        mimetype: str = "") -> int:
        return 1
Example #10
0
 def get_mimetypes_mapping(cls) -> typing.List[MimetypeMapping]:
     return [
         MimetypeMapping("application/x-preview-generator-test", ".runpy")
     ]
Example #11
0
 def get_mimetypes_mapping(cls) -> typing.List[MimetypeMapping]:
     mimetypes_mapping = []
     for mimetype, extension in LO_MIMETYPES.items():
         mimetypes_mapping.append(
             MimetypeMapping(mimetype, ".{}".format(extension)))
     return mimetypes_mapping