2323from osgeo import gdal
2424from importer .celery_app import importer_app
2525from geonode .storage .manager import storage_manager
26+ from geonode .assets .handlers import asset_handler_registry
27+ from geonode .assets .models import Asset
28+ from geonode .assets .utils import create_link
2629
2730logger = logging .getLogger (__name__ )
2831
@@ -190,6 +193,11 @@ def extract_resource_to_publish(
190193 self , files , action , layer_name , alternate , ** kwargs
191194 ):
192195 if action == exa .COPY .value :
196+ nl = kwargs .get ("new_file_location" ) or kwargs .get ("kwargs" , {}).get ("new_file_location" , {})
197+ raster_path = None
198+ if nl :
199+ files_list = nl .get ("files" ) or []
200+ raster_path = files_list [0 ] if files_list else None
193201 return [
194202 {
195203 "name" : alternate ,
@@ -199,9 +207,7 @@ def extract_resource_to_publish(
199207 )
200208 .first ()
201209 .srid ,
202- "raster_path" : kwargs ["kwargs" ]
203- .get ("new_file_location" )
204- .get ("files" )[0 ],
210+ "raster_path" : raster_path
205211 }
206212 ]
207213
@@ -466,6 +472,19 @@ def overwrite_resourcehandlerinfo(
466472 return self .create_resourcehandlerinfo (
467473 handler_module_path , resource , execution_id , ** kwargs
468474 )
475+ def _prepare_assets_for_copy (self , resource , kwargs ):
476+ """
477+ Prepare assets for copying.
478+ It gets the cloned asset and identifies other assets to be linked.
479+ """
480+ _nl = kwargs .get ("new_file_location" ) or kwargs .get ("kwargs" , {}).get ("new_file_location" , {})
481+ _asset = _nl .get ("asset" )
482+ _asset_id = _nl .get ("asset_id" )
483+ if not _asset and _asset_id :
484+ _asset = Asset .objects .filter (pk = _asset_id ).first ()
485+
486+ assets_to_link = Asset .objects .filter (link__resource = resource ).exclude (title = "Original" )
487+ return _asset , assets_to_link
469488
470489 def copy_geonode_resource (
471490 self ,
@@ -476,16 +495,18 @@ def copy_geonode_resource(
476495 new_alternate : str ,
477496 ** kwargs ,
478497 ):
479- resource = self .create_geonode_resource (
498+ cloned_asset , assets_to_link = self ._prepare_assets_for_copy (resource , kwargs )
499+
500+ new_resource = self .create_geonode_resource (
480501 layer_name = data_to_update .get ("title" ),
481502 alternate = new_alternate ,
482503 execution_id = str (_exec .exec_id ),
483- asset = kwargs .get ("kwargs" , {})
484- .get ("new_file_location" , {})
485- .get ("asset" , []),
504+ asset = cloned_asset ,
486505 )
487- resource .refresh_from_db ()
488- return resource
506+ [create_link (new_resource , asset ) for asset in assets_to_link ]
507+
508+ new_resource .refresh_from_db ()
509+ return new_resource
489510
490511 def _get_execution_request_object (self , execution_id : str ):
491512 return ExecutionRequest .objects .filter (exec_id = execution_id ).first ()
@@ -538,16 +559,25 @@ def copy_raster_file(
538559
539560 original_dataset = original_dataset .first ()
540561
541- if not original_dataset .files :
562+ # Ensure the dataset has at least one Asset associated
563+ filters = {"link__resource" : original_dataset , "title" : "Original" }
564+ if not Asset .objects .filter ().exists ():
542565 raise InvalidGeoTiffException (
543- "The original file of the dataset is not available, Is not possible to copy the dataset"
566+ "The dataset does not have any original asset associated; cannot copy the dataset"
544567 )
568+ original_asset = Asset .objects .filter (** filters ).last ()
545569
546- new_file_location = orchestrator .load_handler (
547- handler_module_path
548- ).copy_original_file (original_dataset )
570+ # The original asset is cloned here, as it is required for the creation of the new cloned resource. Other associated assets will be linked to the new resource later in the process.
571+ cloned_asset = asset_handler_registry .get_handler (original_asset ).clone (original_asset )
572+ new_file_location = {
573+ "files" : cloned_asset .location if getattr (cloned_asset , "location" , None ) else [],
574+ "asset_id" : cloned_asset .id ,
575+ }
576+ if not new_file_location ["files" ]:
577+ raise InvalidGeoTiffException ("Could not determine the location of the copied file" )
549578
550- new_dataset_alternate = create_alternate (original_dataset .title , exec_id )
579+ sanitized_title = BaseHandler ().fixup_name (original_dataset .title )
580+ new_dataset_alternate = create_alternate (sanitized_title , exec_id )
551581
552582 additional_kwargs = {
553583 "original_dataset_alternate" : original_dataset .alternate ,
0 commit comments