1515# limitations under the License.
1616"""Dataset business logic."""
1717
18+ import imghdr
1819import os
1920import shutil
2021import urllib
3536from renku .core .dataset .providers .factory import ProviderFactory
3637from renku .core .dataset .providers .git import GitProvider
3738from renku .core .dataset .providers .models import DatasetUpdateAction , ProviderDataset
38- from renku .core .dataset .request_model import ImageRequestModel
3939from renku .core .dataset .tag import get_dataset_by_tag , prompt_access_token , prompt_tag_selection
40+ from renku .core .image import ImageObjectRequest
4041from renku .core .interface .dataset_gateway import IDatasetGateway
4142from renku .core .storage import check_external_storage , track_paths_in_storage
4243from renku .core .util import communication
5051 get_absolute_path ,
5152 get_file_size ,
5253 get_files ,
54+ get_relative_path ,
5355 get_safe_relative_path ,
5456 hash_file ,
5557 is_path_empty ,
@@ -109,7 +111,7 @@ def create_dataset(
109111 description : Optional [str ] = None ,
110112 creators : Optional [List [Person ]] = None ,
111113 keywords : Optional [List [str ]] = None ,
112- images : Optional [List [ImageRequestModel ]] = None ,
114+ images : Optional [List [ImageObjectRequest ]] = None ,
113115 update_provenance : bool = True ,
114116 custom_metadata : Optional [Dict [str , Any ]] = None ,
115117 storage : Optional [str ] = None ,
@@ -123,7 +125,7 @@ def create_dataset(
123125 description(Optional[str], optional): Dataset description (Default value = None).
124126 creators(Optional[List[Person]], optional): Dataset creators (Default value = None).
125127 keywords(Optional[List[str]], optional): Dataset keywords (Default value = None).
126- images(Optional[List[ImageRequestModel ]], optional): Dataset images (Default value = None).
128+ images(Optional[List[ImageObjectRequest ]], optional): Dataset images (Default value = None).
127129 update_provenance(bool, optional): Whether to add this dataset to dataset provenance
128130 (Default value = True).
129131 custom_metadata(Optional[Dict[str, Any]], optional): Custom JSON-LD metadata (Default value = None).
@@ -199,7 +201,7 @@ def edit_dataset(
199201 description : Optional [Union [str , NoValueType ]],
200202 creators : Optional [Union [List [Person ], NoValueType ]],
201203 keywords : Optional [Union [List [str ], NoValueType ]] = NO_VALUE ,
202- images : Optional [Union [List [ImageRequestModel ], NoValueType ]] = NO_VALUE ,
204+ images : Optional [Union [List [ImageObjectRequest ], NoValueType ]] = NO_VALUE ,
203205 custom_metadata : Optional [Union [Dict , List [Dict ], NoValueType ]] = NO_VALUE ,
204206 custom_metadata_source : Optional [Union [str , NoValueType ]] = NO_VALUE ,
205207):
@@ -211,7 +213,7 @@ def edit_dataset(
211213 description(Optional[Union[str, NoValueType]]): New description for the dataset.
212214 creators(Optional[Union[List[Person], NoValueType]]): New creators for the dataset.
213215 keywords(Optional[Union[List[str], NoValueType]]): New keywords for dataset (Default value = ``NO_VALUE``).
214- images(Optional[Union[List[ImageRequestModel ], NoValueType]]): New images for dataset
216+ images(Optional[Union[List[ImageObjectRequest ], NoValueType]]): New images for dataset
215217 (Default value = ``NO_VALUE``).
216218 custom_metadata(Optional[Union[Dict, List[Dict], NoValueType]]): Custom JSON-LD metadata
217219 (Default value = ``NO_VALUE``).
@@ -248,7 +250,7 @@ def edit_dataset(
248250 if images == NO_VALUE :
249251 images_updated = False
250252 else :
251- images_updated = set_dataset_images (dataset = dataset , images = cast (Optional [List [ImageRequestModel ]], images ))
253+ images_updated = set_dataset_images (dataset = dataset , images = cast (Optional [List [ImageObjectRequest ]], images ))
252254
253255 if images_updated :
254256 updated ["images" ] = (
@@ -855,12 +857,12 @@ def add_datadir_files_to_dataset(dataset: Dataset) -> None:
855857 dataset .add_or_update_files (dataset_files )
856858
857859
858- def set_dataset_images (dataset : Dataset , images : Optional [List [ImageRequestModel ]]):
860+ def set_dataset_images (dataset : Dataset , images : Optional [List [ImageObjectRequest ]]):
859861 """Set a dataset's images.
860862
861863 Args:
862864 dataset(Dataset): The dataset to set images on.
863- images(List[ImageRequestModel ]): The images to set.
865+ images(List[ImageObjectRequest ]): The images to set.
864866
865867 Returns:
866868 True if images were set/modified.
@@ -875,10 +877,30 @@ def set_dataset_images(dataset: Dataset, images: Optional[List[ImageRequestModel
875877 dataset .images = []
876878 images_updated = False
877879 for img in images :
878- img_object = img .to_image_object (dataset )
880+ image_folder = project_context .dataset_images_path / dataset .initial_identifier
881+ try :
882+ img_object = img .to_image_object (owner_id = dataset .id )
883+ except errors .ImageError as e :
884+ raise errors .DatasetImageError (e ) from e
885+
886+ path = img_object .content_url
887+
888+ if not img_object .is_remote :
889+ # NOTE: only copy dataset image if it's not in .renku/datasets/<id>/images/ already
890+ if not path .startswith (str (image_folder )):
891+ image_type = imghdr .what (path )
892+ if image_type :
893+ ext = f".{ image_type } "
894+ else :
895+ _ , ext = os .path .splitext (path )
896+ target_image_path : Union [Path , str ] = image_folder / f"{ img_object .position } { ext } "
879897
880- if not img_object :
881- continue
898+ image_folder .parent .mkdir (parents = True , exist_ok = True )
899+ shutil .copy (path , target_image_path )
900+ else :
901+ target_image_path = path
902+
903+ img_object .content_url = get_relative_path (target_image_path , base = project_context .path ) # type: ignore
882904
883905 if any (i .position == img_object .position for i in dataset .images ):
884906 raise errors .DatasetImageError (f"Duplicate dataset image specified for position { img_object .position } " )
0 commit comments