@@ -108,6 +108,12 @@ def delete_file(self, channel: str, destination: str):
108108 def move_file (self , channel : str , source : str , destination : str ):
109109 """move file from source to destination in package store"""
110110
111+ @abc .abstractmethod
112+ def copy_file (
113+ self , source_channel : str , source : str , target_channel : str , destination : str
114+ ):
115+ """move file from source to destination in package store"""
116+
111117 @abc .abstractmethod
112118 def file_exists (self , channel : str , destination : str ):
113119 """Return True if the file exists"""
@@ -206,6 +212,15 @@ def move_file(self, channel: str, source: str, destination: str):
206212 path .join (self .channels_dir , channel , destination ),
207213 )
208214
215+ def copy_file (
216+ self , source_channel : str , source : str , target_channel : str , destination : str
217+ ):
218+ with self ._atomic_open (target_channel , destination ) as f :
219+ package = self .fs .open (
220+ path .join (self .channels_dir , source_channel , source ), "rb"
221+ )
222+ shutil .copyfileobj (package , f )
223+
209224 def file_exists (self , channel : str , destination : str ):
210225 return self .fs .exists (path .join (self .channels_dir , channel , destination ))
211226
@@ -405,6 +420,17 @@ def move_file(self, channel: str, source: str, destination: str):
405420 path .join (channel_bucket , destination ),
406421 )
407422
423+ def copy_file (
424+ self , source_channel : str , source : str , target_channel : str , destination : str
425+ ):
426+ source_channel_bucket = self ._bucket_map (source_channel )
427+ target_channel_bucket = self ._bucket_map (target_channel )
428+ with self ._get_fs () as fs :
429+ fs .copy (
430+ path .join (source_channel_bucket , source ),
431+ path .join (target_channel_bucket , destination ),
432+ )
433+
408434 def file_exists (self , channel : str , destination : str ):
409435 channel_bucket = self ._bucket_map (channel )
410436 with self ._get_fs () as fs :
@@ -559,6 +585,17 @@ def move_file(self, channel: str, source: str, destination: str):
559585 path .join (channel_container , destination ),
560586 )
561587
588+ def copy_file (
589+ self , source_channel : str , source : str , target_channel : str , destination : str
590+ ):
591+ source_channel_container = self ._container_map (source_channel )
592+ target_channel_container = self ._container_map (target_channel )
593+ with self ._get_fs () as fs :
594+ fs .copy (
595+ path .join (source_channel_container , source ),
596+ path .join (target_channel_container , destination ),
597+ )
598+
562599 def file_exists (self , channel : str , destination : str ):
563600 channel_container = self ._container_map (channel )
564601 with self ._get_fs () as fs :
@@ -728,6 +765,18 @@ def move_file(self, channel: str, source: str, destination: str):
728765 path .join (channel_container , destination ),
729766 )
730767
768+ def copy_file (
769+ self , source_channel : str , source : str , target_channel : str , destination : str
770+ ):
771+ source_channel_container = self ._bucket_map (source_channel )
772+ target_channel_container = self ._bucket_map (target_channel )
773+
774+ with self ._get_fs () as fs :
775+ fs .copy (
776+ path .join (source_channel_container , source ),
777+ path .join (target_channel_container , destination ),
778+ )
779+
731780 def file_exists (self , channel : str , destination : str ):
732781 channel_container = self ._bucket_map (channel )
733782 with self ._get_fs () as fs :
0 commit comments