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