Пример #1
0
def geoserver_post_save(instance, sender, created, **kwargs):
    from geonode.messaging import producer
    # this is attached to various models, (ResourceBase, Document)
    # so we should select what will be handled here
    if isinstance(instance, Layer):
        instance_dict = model_to_dict(instance)
        payload = json_serializer_producer(instance_dict)
        try:
            producer.geoserver_upload_layer(payload)
        except Exception as e:
            logger.error(e)
        if getattr(settings, 'DELAYED_SECURITY_SIGNALS', False):
            instance.set_dirty_state()
Пример #2
0
def download(request, resourceid, sender=Layer):

    _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, Layer):
        # Create Target Folder
        dirpath = tempfile.mkdtemp()
        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)

        layer_files = []
        try:
            upload_session = instance.get_upload_session()
            if upload_session:
                layer_files = [
                    item for idx, item in enumerate(
                        LayerFile.objects.filter(
                            upload_session=upload_session))
                ]
                if layer_files:
                    # Copy all Layer related files into a temporary folder
                    for lyr in layer_files:
                        if storage.exists(str(lyr.file)):
                            geonode_layer_path = storage.path(str(lyr.file))
                            shutil.copy2(geonode_layer_path, target_folder)
                        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 layer_files:
                return HttpResponse(loader.render_to_string(
                    '401.html',
                    context={
                        'error_title': _("No files found."),
                        'error_message': _no_files_found
                    },
                    request=request),
                                    status=404)

            # Let's check for associated SLD files (if any)
            try:
                for s in instance.styles.all():
                    sld_file_path = os.path.join(target_folder,
                                                 "".join([s.name, ".sld"]))
                    with open(sld_file_path, "w") as sld_file:
                        sld_file.write(s.sld_body.strip())
                    try:
                        # Collecting headers and cookies
                        headers, access_token = get_headers(
                            request, urlsplit(s.sld_url), s.sld_url)

                        response, content = http_client.get(s.sld_url,
                                                            headers=headers,
                                                            timeout=TIMEOUT,
                                                            user=request.user)
                        sld_remote_content = response.text
                        sld_file_path = os.path.join(
                            target_folder, "".join([s.name, "_remote.sld"]))
                        with open(sld_file_path, "w") as sld_file:
                            sld_file.write(sld_remote_content.strip())
                    except Exception:
                        traceback.print_exc()
                        tb = traceback.format_exc()
                        logger.debug(tb)
            except Exception:
                traceback.print_exc()
                tb = traceback.format_exc()
                logger.debug(tb)

            # Let's dump metadata
            target_md_folder = os.path.join(target_folder, ".metadata")
            if not os.path.exists(target_md_folder):
                os.makedirs(target_md_folder)

            try:
                dump_file = os.path.join(target_md_folder,
                                         "".join([instance.name, ".dump"]))
                with open(dump_file, 'w') as outfile:
                    serialized_obj = json_serializer_producer(
                        model_to_dict(instance))
                    json.dump(serialized_obj, outfile)

                links = Link.objects.filter(resource=instance.resourcebase_ptr)
                for link in links:
                    link_name = slugify(link.name)
                    link_file = os.path.join(
                        target_md_folder,
                        "".join([link_name, ".%s" % link.extension]))
                    if link.link_type in ('data'):
                        # Skipping 'data' download links
                        continue
                    elif link.link_type in ('metadata', 'image'):
                        # Dumping metadata files and images
                        with open(link_file, "wb"):
                            try:
                                # Collecting headers and cookies
                                headers, access_token = get_headers(
                                    request, urlsplit(link.url), link.url)

                                response, raw = http_client.get(
                                    link.url,
                                    stream=True,
                                    headers=headers,
                                    timeout=TIMEOUT,
                                    user=request.user)
                                raw.decode_content = True
                                shutil.copyfileobj(raw, link_file)
                            except Exception:
                                traceback.print_exc()
                                tb = traceback.format_exc()
                                logger.debug(tb)
                    elif link.link_type.startswith('OGC'):
                        # Dumping OGC/OWS links
                        with open(link_file, "w") as link_file:
                            link_file.write(link.url.strip())
            except Exception:
                traceback.print_exc()
                tb = traceback.format_exc()
                logger.debug(tb)

            # 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'] = 'attachment; filename="%s"' % target_file_name
            return response
        except NotImplementedError:
            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)
Пример #3
0
def download(request, resourceid, sender=Layer):

    _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, Layer):
        layer_files = []
        file_list = []  # Store file info to be returned
        try:
            upload_session = instance.get_upload_session()
            if upload_session:
                layer_files = [
                    item for idx, item in enumerate(
                        LayerFile.objects.filter(
                            upload_session=upload_session))
                ]
                if layer_files:
                    # Copy all Layer related files into a temporary folder
                    for lyr in layer_files:
                        if storage.exists(str(lyr.file)):
                            geonode_layer_path = storage.path(str(lyr.file))
                            file_list.append({
                                "zip_folder":
                                "",
                                "name":
                                lyr.file.name.split('/')[-1],
                                "data_src_file":
                                geonode_layer_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 layer_files:
                return HttpResponse(loader.render_to_string(
                    '401.html',
                    context={
                        'error_title': _("No files found."),
                        'error_message': _no_files_found
                    },
                    request=request),
                                    status=404)

            # Let's check for associated SLD files (if any)
            try:
                for s in instance.styles.all():
                    sld_file_name = "".join([s.name, ".sld"])
                    file_list.append({
                        "zip_folder": "",
                        "name": sld_file_name,
                        "data_str": s.sld_body.strip(),
                    })
                    try:
                        # Collecting headers and cookies
                        headers, access_token = get_headers(
                            request, urlsplit(s.sld_url), s.sld_url)

                        response, content = http_client.get(s.sld_url,
                                                            headers=headers,
                                                            timeout=TIMEOUT,
                                                            user=request.user)
                        sld_remote_content = response.text
                        remote_sld_file_name = "".join([s.name, "_remote.sld"])
                        file_list.append({
                            "zip_folder": "",
                            "name": remote_sld_file_name,
                            "data_str": sld_remote_content,
                        })
                    except Exception:
                        traceback.print_exc()
                        tb = traceback.format_exc()
                        logger.debug(tb)
            except Exception:
                traceback.print_exc()
                tb = traceback.format_exc()
                logger.debug(tb)

            # Let's dump metadata
            try:
                dump_file_name = "".join([instance.name, ".dump"])
                serialized_obj = json_serializer_producer(
                    model_to_dict(instance))
                file_list.append({
                    "zip_folder": ".metadata/",
                    "name": dump_file_name,
                    "data_str": json.dumps(serialized_obj),
                })
                links = Link.objects.filter(resource=instance.resourcebase_ptr)
                for link in links:
                    link_name = slugify(link.name)
                    link_file_name = "".join([link_name, f".{link.extension}"])
                    link_file_obj = None

                    if link.link_type in ('data'):
                        # Skipping 'data' download links
                        continue
                    elif link.link_type in ('metadata', 'image'):
                        # Dumping metadata files and images
                        try:
                            # Collecting headers and cookies
                            headers, access_token = get_headers(
                                request, urlsplit(link.url), link.url)

                            response, raw = http_client.get(link.url,
                                                            stream=True,
                                                            headers=headers,
                                                            timeout=TIMEOUT,
                                                            user=request.user)
                            raw.decode_content = True
                            if raw and raw is not None:
                                link_file_obj = {
                                    "zip_folder": ".metadata/",
                                    "name": link_file_name,
                                    "data_iter": raw,
                                }
                        except Exception:
                            traceback.print_exc()
                            tb = traceback.format_exc()
                            logger.debug(tb)
                    elif link.link_type.startswith('OGC'):
                        # Dumping OGC/OWS links
                        link_file_obj = {
                            "zip_folder": ".metadata/",
                            "name": link_file_name,
                            "data_str": link.url.strip(),
                        }
                    # Add file_info to the file list
                    if link_file_obj is not None:
                        file_list.append(link_file_obj)
            except Exception:
                traceback.print_exc()
                tb = traceback.format_exc()
                logger.debug(tb)

            # 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:
                zip_file_name = "".join(
                    [file_info['zip_folder'], file_info['name']])
                # The zip can be built from 3 data sources: str, iterable or a file path
                if 'data_str' in file_info and file_info[
                        'data_str'] is not None:
                    target_zip.writestr(arcname=zip_file_name,
                                        data=bytes(file_info['data_str'],
                                                   'utf-8'))
                elif 'data_iter' in file_info and file_info[
                        'data_iter'] is not None:
                    target_zip.write_iter(arcname=zip_file_name,
                                          iterable=_iterable(
                                              file_info['data_iter']))
                elif 'data_src_file' in file_info and file_info[
                        'data_src_file'] is not None:
                    target_zip.write(filename=file_info['data_src_file'],
                                     arcname=zip_file_name)

            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:
            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)