Beispiel #1
0
def get_download_response(request, docid, attachment=False):
    """
    Returns a download response if user has access to download the document of a given id,
    and an http response if they have no permissions to download it.
    """
    document = get_object_or_404(Document, pk=docid)

    if not request.user.has_perm('base.download_resourcebase',
                                 obj=document.get_self_resource()):
        return HttpResponse(loader.render_to_string(
            '401.html',
            context={
                'error_message':
                _("You are not allowed to view this document.")
            },
            request=request),
                            status=401)
    if attachment:
        register_event(request, EventType.EVENT_DOWNLOAD, document)
    filename = slugify(os.path.splitext(os.path.basename(document.title))[0])

    if document.files and storage_manager.exists(document.files[0]):
        return DownloadResponse(storage_manager.open(document.files[0]).file,
                                basename=f'{filename}.{document.extension}',
                                attachment=attachment)
    return HttpResponse("File is not available", status=404)
Beispiel #2
0
def update_thumbnail_urls_and_delete_curated_thumbs_folder(
        apps, schema_editor):
    query = '''
    SELECT base_resourcebase.id, base_curatedthumbnail.img FROM base_resourcebase
    INNER JOIN base_curatedthumbnail
    ON base_resourcebase.id=base_curatedthumbnail.resource_id;
    '''
    c = connection.cursor()
    c.execute(query)
    results = c.fetchall()
    for result in results:
        resource_id, image = result
        resource = ResourceBase.objects.filter(id=resource_id).first()
        try:
            bytes_file = storage_manager.open(image).read()
        except Exception:
            bytes_file = None

        if resource and bytes_file:
            filename = _generate_thumbnail_name(resource.get_real_instance())
            resource.save_thumbnail(filename, bytes_file)
Beispiel #3
0
def create_document_thumbnail(self, object_id):
    """
    Create thumbnail for a document.
    """
    logger.debug(f"Generating thumbnail for document #{object_id}.")

    try:
        document = Document.objects.get(id=object_id)
    except Document.DoesNotExist:
        logger.error(f"Document #{object_id} does not exist.")
        raise

    image_path = None
    image_file = None

    if document.is_image:
        dname = storage_manager.path(document.files[0])
        if storage_manager.exists(dname):
            image_file = storage_manager.open(dname, 'rb')
    elif document.is_video or document.is_audio:
        image_file = open(document.find_placeholder(), 'rb')
    elif document.is_file:
        dname = storage_manager.path(document.files[0])
        try:
            document_location = storage_manager.path(dname)
        except NotImplementedError as e:
            logger.debug(e)

            document_location = storage_manager.url(dname)

        try:
            image_path = render_document(document_location)
            if image_path is not None:
                try:
                    image_file = open(image_path, 'rb')
                except Exception as e:
                    logger.debug(
                        f"Failed to render document #{object_id}: {e}")
            else:
                logger.debug(f"Failed to render document #{object_id}")
        except ConversionError as e:
            logger.debug(f"Could not convert document #{object_id}: {e}.")
        except NotImplementedError as e:
            logger.debug(f"Failed to render document #{object_id}: {e}")

    thumbnail_content = None
    try:
        try:
            thumbnail_content = generate_thumbnail_content(image_file)
        except Exception as e:
            logger.debug(
                f"Could not generate thumbnail, falling back to 'placeholder': {e}"
            )
            thumbnail_content = generate_thumbnail_content(
                document.find_placeholder())
    except Exception as e:
        logger.error(f"Could not generate thumbnail: {e}")
        return
    finally:
        if image_file is not None:
            image_file.close()

        if image_path is not None:
            os.remove(image_path)

    if not thumbnail_content:
        logger.warning(f"Thumbnail for document #{object_id} empty.")
    filename = f'document-{document.uuid}-thumb.png'
    document.save_thumbnail(filename, thumbnail_content)
    logger.debug(f"Thumbnail for document #{object_id} created.")
Beispiel #4
0
def thumb_open(filename):
    """Returns file handler of a thumbnail on the storage"""
    return storage_manager.open(thumb_path(filename))
Beispiel #5
0
def download(request, resourceid, sender=Dataset):

    _not_authorized = _("You are not authorized to download this resource.")
    _not_permitted = _("You are not permitted to save or edit this resource.")
    _no_files_found = _(
        "No files have been found for this resource. Please, contact a system administrator."
    )

    instance = resolve_object(request,
                              sender, {'pk': resourceid},
                              permission='base.download_resourcebase',
                              permission_msg=_not_permitted)

    if isinstance(instance, ResourceBase):
        dataset_files = []
        file_list = []  # Store file info to be returned
        try:
            files = instance.resourcebase_ptr.files
            # Copy all Dataset related files into a temporary folder
            for file_path in files:
                if storage_manager.exists(file_path):
                    dataset_files.append(file_path)
                    filename = os.path.basename(file_path)
                    file_list.append({
                        "name":
                        filename,
                        "data_iter":
                        storage_manager.open(file_path),
                    })
                else:
                    return HttpResponse(loader.render_to_string(
                        '401.html',
                        context={
                            'error_title': _("No files found."),
                            'error_message': _no_files_found
                        },
                        request=request),
                                        status=404)

            # Check we can access the original files
            if not dataset_files:
                return HttpResponse(loader.render_to_string(
                    '401.html',
                    context={
                        'error_title': _("No files found."),
                        'error_message': _no_files_found
                    },
                    request=request),
                                    status=404)

            # ZIP everything and return
            target_file_name = "".join([instance.name, ".zip"])

            target_zip = zipstream.ZipFile(mode='w',
                                           compression=zipstream.ZIP_DEFLATED,
                                           allowZip64=True)

            # Iterable: Needed when the file_info has it's data as a stream
            def _iterable(source_iter):
                while True:
                    buf = source_iter.read(BUFFER_CHUNK_SIZE)
                    if not buf:
                        break
                    yield buf

            # Add files to zip
            for file_info in file_list:
                target_zip.write_iter(arcname=file_info['name'],
                                      iterable=_iterable(
                                          file_info['data_iter']))

            register_event(request, 'download', instance)

            # Streaming content response
            response = StreamingHttpResponse(target_zip,
                                             content_type='application/zip')
            response[
                'Content-Disposition'] = f'attachment; filename="{target_file_name}"'
            return response
        except (NotImplementedError, Upload.DoesNotExist):
            traceback.print_exc()
            tb = traceback.format_exc()
            logger.debug(tb)
            return HttpResponse(loader.render_to_string(
                '401.html',
                context={
                    'error_title': _("No files found."),
                    'error_message': _no_files_found
                },
                request=request),
                                status=404)
    return HttpResponse(loader.render_to_string('401.html',
                                                context={
                                                    'error_title':
                                                    _("Not Authorized"),
                                                    'error_message':
                                                    _not_authorized
                                                },
                                                request=request),
                        status=403)
Beispiel #6
0
    def _execute_resource_import(self, instance, files: list, user, action_type: str, importer_session_opts: typing.Optional[typing.Dict] = None):
        from geonode.upload.files import ALLOWED_EXTENSIONS
        session_opts = dict(importer_session_opts) if importer_session_opts is not None else {}

        spatial_files_type = get_spatial_files_dataset_type(ALLOWED_EXTENSIONS, files)

        if not spatial_files_type:
            raise Exception(f"No suitable Spatial Files avaialable for 'ALLOWED_EXTENSIONS' = {ALLOWED_EXTENSIONS}.")

        upload_session, _ = Upload.objects.get_or_create(resource=instance.get_real_instance().resourcebase_ptr, user=user)
        upload_session.resource = instance.get_real_instance().resourcebase_ptr
        upload_session.save()

        _name = instance.get_real_instance().name
        if not _name:
            _name = session_opts.get('name', None) or os.path.splitext(os.path.basename(spatial_files_type.base_file))[0]
        instance.get_real_instance().name = _name

        gs_dataset = None
        try:
            gs_dataset = gs_catalog.get_layer(_name)
        except Exception as e:
            logger.debug(e)

        _workspace = None
        _target_store = None
        if gs_dataset:
            _target_store = gs_dataset.resource.store.name if instance.get_real_instance().subtype == 'vector' else None
            _workspace = gs_dataset.resource.workspace.name if gs_dataset.resource.workspace else None

        if not _workspace:
            _workspace = session_opts.get('workspace', instance.get_real_instance().workspace)
            if not _workspace:
                _workspace = instance.get_real_instance().workspace or settings.DEFAULT_WORKSPACE

        if not _target_store:
            if instance.get_real_instance().subtype == 'vector' or spatial_files_type.dataset_type == 'vector':
                _dsname = ogc_server_settings.datastore_db['NAME']
                _ds = create_geoserver_db_featurestore(store_name=_dsname, workspace=_workspace)
                if _ds:
                    _target_store = session_opts.get('target_store', None) or _dsname

        #  opening Import session for the selected layer
        # Let's reset the connections first
        gs_catalog._cache.clear()
        gs_catalog.reset()
        # Let's now try the new ingestion
        import_session = gs_uploader.start_import(
            import_id=upload_session.id,
            name=_name,
            target_store=_target_store
        )

        upload_session.set_processing_state(enumerations.STATE_PROCESSED)
        upload_session.import_id = import_session.id
        upload_session.name = _name
        upload_session.complete = True
        upload_session.processed = True
        upload_session.save()

        _gs_import_session_info = GeoServerImporterSessionInfo(
            upload_session=upload_session,
            import_session=import_session,
            spatial_files_type=spatial_files_type,
            dataset_name=None,
            workspace=_workspace,
            target_store=_target_store
        )

        _local_files = []
        _temporary_files = []
        try:
            for _f in files:
                if os.path.exists(_f) and os.path.isfile(_f):
                    _local_files.append(os.path.abspath(_f))
                    try:
                        os.close(_f)
                    except Exception:
                        pass
                else:
                    _suffix = os.path.splitext(os.path.basename(_f))[1] if len(os.path.splitext(os.path.basename(_f))) else None
                    with tempfile.NamedTemporaryFile(mode="wb+", delete=False, dir=settings.MEDIA_ROOT, suffix=_suffix) as _tmp_file:
                        _tmp_file.write(storage_manager.open(_f, 'rb+').read())
                        _tmp_file.seek(0)
                        _tmp_file_name = f'{_tmp_file.name}'
                        _local_files.append(os.path.abspath(_tmp_file_name))
                        _temporary_files.append(os.path.abspath(_tmp_file_name))
                    try:
                        storage_manager.close(_f)
                    except Exception:
                        pass
        except Exception as e:
            logger.exception(e)

        if _local_files:
            try:
                import_session.upload_task(_local_files)
                task = import_session.tasks[0]
                #  Changing layer name, mode and target
                task.layer.set_target_layer_name(_name)
                task.set_update_mode(action_type.upper())
                task.set_target(
                    store_name=_target_store,
                    workspace=_workspace
                )
                transforms = session_opts.get('transforms', None)
                if transforms:
                    task.set_transforms(transforms)
                #  Starting import process
                import_session.commit()
                import_session = import_session.reload()

                try:
                    # Updating Resource with the files replaced
                    if action_type.lower() == 'replace':
                        updated_files_list = storage_manager.replace(instance, files)
                        # Using update instead of save in order to avoid calling
                        # side-effect function of the resource
                        r = ResourceBase.objects.filter(id=instance.id)
                        r.update(**updated_files_list)
                    else:
                        instance.files = files
                except Exception as e:
                    logger.exception(e)

                _gs_import_session_info.import_session = import_session
                _gs_import_session_info.dataset_name = import_session.tasks[0].layer.name
            finally:
                for _f in _temporary_files:
                    try:
                        os.remove(_f)
                    except Exception as e:
                        logger.debug(e)

        return _gs_import_session_info
Beispiel #7
0
def download(request, resourceid, sender=Dataset):

    _not_authorized = _("You are not authorized to download this resource.")
    _not_permitted = _("You are not permitted to save or edit this resource.")
    _no_files_found = _("No files have been found for this resource. Please, contact a system administrator.")

    instance = resolve_object(request,
                              sender,
                              {'pk': resourceid},
                              permission='base.download_resourcebase',
                              permission_msg=_not_permitted)

    if isinstance(instance, ResourceBase):
        # Create Target Folder
        dirpath = tempfile.mkdtemp(dir=settings.STATIC_ROOT)
        dir_time_suffix = get_dir_time_suffix()
        target_folder = os.path.join(dirpath, dir_time_suffix)
        if not os.path.exists(target_folder):
            os.makedirs(target_folder)

        dataset_files = []
        try:
            files = instance.resourcebase_ptr.files
            # Copy all Dataset related files into a temporary folder
            for file_path in files:
                if storage_manager.exists(file_path):
                    dataset_files.append(file_path)
                    filename = os.path.basename(file_path)
                    with open(f"{target_folder}/{filename}", 'wb+') as f:
                        f.write(storage_manager.open(file_path).read())
                else:
                    return HttpResponse(
                        loader.render_to_string(
                            '401.html',
                            context={
                                'error_title': _("No files found."),
                                'error_message': _no_files_found
                            },
                            request=request), status=404)

            # Check we can access the original files
            if not dataset_files:
                return HttpResponse(
                    loader.render_to_string(
                        '401.html',
                        context={
                            'error_title': _("No files found."),
                            'error_message': _no_files_found
                        },
                        request=request), status=404)

            # ZIP everything and return
            target_file_name = "".join([instance.name, ".zip"])
            target_file = os.path.join(dirpath, target_file_name)
            zip_dir(target_folder, target_file)
            register_event(request, 'download', instance)
            response = HttpResponse(
                content=open(target_file, mode='rb'),
                status=200,
                content_type="application/zip")
            response['Content-Disposition'] = f'attachment; filename="{target_file_name}"'
            return response
        except (NotImplementedError, Upload.DoesNotExist):
            traceback.print_exc()
            tb = traceback.format_exc()
            logger.debug(tb)
            return HttpResponse(
                loader.render_to_string(
                    '401.html',
                    context={
                        'error_title': _("No files found."),
                        'error_message': _no_files_found
                    },
                    request=request), status=404)
        finally:
            if target_folder is not None:
                shutil.rmtree(target_folder, ignore_errors=True)
    return HttpResponse(
        loader.render_to_string(
            '401.html',
            context={
                'error_title': _("Not Authorized"),
                'error_message': _not_authorized
            },
            request=request), status=403)