Exemplo n.º 1
0
import shutil
import typing

from PIL import Image
import pytest

from preview_generator.exception import UnavailablePreviewType
from preview_generator.manager import PreviewManager
from tests import test_utils

CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
CACHE_DIR = "/tmp/preview-generator-tests/cache"
IMAGE_FILE_PATH = os.path.join(CURRENT_DIR, "test_heic.heic")

manager = PreviewManager(cache_folder_path=CACHE_DIR, create_folder=True)
if "image/heic" not in manager.get_supported_mimetypes():
    pytest.skip("heif-convert is not available.", allow_module_level=True)


def setup_function(function: typing.Callable) -> None:
    shutil.rmtree(CACHE_DIR, ignore_errors=True)


def test_to_jpeg() -> None:
    manager = PreviewManager(cache_folder_path=CACHE_DIR, create_folder=True)
    assert manager.has_jpeg_preview(file_path=IMAGE_FILE_PATH) is True
    path_to_file = manager.get_jpeg_preview(file_path=IMAGE_FILE_PATH,
                                            height=256,
                                            width=512,
                                            force=True)
    assert os.path.exists(path_to_file) is True
Exemplo n.º 2
0
class Document:
    def __init__(self, index, id, routing):
        self.index = index
        self.id = id
        self.routing = routing
        self.source = {}
        self.setup_target_directory()
        self.manager = PreviewManager(self.thumbnail_directory,
                                      create_folder=True)

    @property
    def meta_url(self):
        url = urljoin(settings.ds_host,
                      settings.ds_document_meta_path % (self.index, self.id))
        # Optional routing parameter
        if self.routing is not None:
            url = urljoin(
                url, '?_source=contentLength,contentType,path&routing=%s' %
                self.routing)
        return url

    @property
    def src_url(self):
        url = urljoin(settings.ds_host,
                      settings.ds_document_src_path % (self.index, self.id))
        # Optional routing parameter
        if self.routing is not None:
            url = urljoin(url, '?routing=%s' % self.routing)
        return url

    @property
    def target_path(self):
        if self.target_ext is None:
            return os.path.join(self.target_directory, 'raw')
        else:
            return os.path.join(self.target_directory, 'raw' + self.target_ext)

    @property
    def target_directory(self):
        return os.path.join(DOCUMENTS_PATH, self.index, self.id)

    @property
    def target_ext(self):
        if self.target_path_ext == '':
            if self.target_content_type is None:
                return None
            return self.manager.get_file_extension()
        return self.target_path_ext

    @property
    def target_path_ext(self):
        return Path(self.source.get('path', '')).suffix

    @property
    def target_content_type(self):
        return self.source.get('contentType', None)

    @property
    def thumbnail_directory(self):
        return os.path.join(THUMBNAILS_PATH, self.index, self.id)

    def setup_target_directory(self):
        return os.makedirs(self.target_directory, exist_ok=True)

    async def download_document_with_steam(self, cookies):
        # Download meta if none
        if not self.source: await self.download_meta(cookies)
        # Open a stream on the document URL
        async with httpx.AsyncClient() as client:
            async with client.stream('GET', self.src_url,
                                     cookies=cookies) as response:
                with open(self.target_path, "wb") as file:
                    async for chunk in response.aiter_bytes():
                        file.write(chunk)
        return self.target_path

    async def download_document(self, cookies):
        # Ensure the file style doesn't exist
        if not Path(self.target_path).exists():
            # Build the document URL
            await self.download_document_with_steam(cookies)
        return self.target_path

    async def download_meta(self, cookies):
        async with httpx.AsyncClient() as client:
            response = await client.get(self.meta_url, cookies=cookies)
        # Raise exception if the document request didn't succeed
        if response.status_code == 401:
            raise DocumentUnauthorized()
        # Any other error
        elif response.status_code != httpx.codes.OK:
            raise DocumentNotPreviewable()
        # Save the source meta
        self.source = response.json().get('_source', {})

    async def check_user_authorization(self, cookies):
        # Download meta if none
        if not self.source: await self.download_meta(cookies)
        # Read contentType and contentLength from source
        content_type = self.source.get('contentType', None)
        content_length = self.source.get('contentLength', 0)
        # Raise exception if the contentType is not previewable
        if not self.is_content_type_previewable(content_type):
            raise DocumentNotPreviewable()
        # Raise exception if the contentType is not previewable
        if content_length > int(settings.ds_document_max_size):
            raise DocumentTooBig()

    def get_jpeg_preview(self, params):
        return self.manager.get_jpeg_preview(**params)

    def get_json_preview(self, params, content_type):
        # Only spreadsheet preview is supported yet
        if is_content_type_spreadsheet(content_type) or is_ext_spreadsheet(
                params['file_ext']):
            return get_spreadsheet_preview(params)
        else:
            return None

    def is_content_type_previewable(self, content_type):
        return content_type in self.manager.get_supported_mimetypes()