66import logging
77import os
88from urllib .parse import urljoin
9- from pywps .exceptions import NotEnoughStorage
9+ from pywps .exceptions import NotEnoughStorage , FileStorageError
1010from pywps import configuration as config
1111from pywps .inout .basic import IOHandler
1212
@@ -22,7 +22,8 @@ class FileStorageBuilder(StorageImplementationBuilder):
2222 def build (self ):
2323 file_path = config .get_config_value ('server' , 'outputpath' )
2424 base_url = config .get_config_value ('server' , 'outputurl' )
25- return FileStorage (file_path , base_url )
25+ copy_function = config .get_config_value ('server' , 'storage_copy_function' )
26+ return FileStorage (file_path , base_url , copy_function = copy_function )
2627
2728
2829def _build_output_name (output ):
@@ -59,17 +60,17 @@ class FileStorage(CachedStorage):
5960 True
6061 """
6162
62- def __init__ (self , output_path , output_url ):
63+ def __init__ (self , output_path , output_url , copy_function = None ):
6364 """
6465 """
6566 CachedStorage .__init__ (self )
6667 self .target = output_path
6768 self .output_url = output_url
69+ self .copy_function = copy_function
6870
6971 def _do_store (self , output ):
7072 import platform
7173 import math
72- import shutil
7374 import tempfile
7475 import uuid
7576
@@ -103,8 +104,12 @@ def _do_store(self, output):
103104 dir = target )[1 ]
104105
105106 full_output_name = os .path .join (target , output_name )
106- LOGGER .info ('Storing file output to {}' .format (full_output_name ))
107- shutil .copy2 (output .file , full_output_name )
107+ LOGGER .info (f'Storing file output to { full_output_name } ({ self .copy_function } ).' )
108+ try :
109+ self .copy (output .file , full_output_name , self .copy_function )
110+ except Exception :
111+ LOGGER .exception (f"Could not copy { output_name } ." )
112+ raise FileStorageError ("Could not copy output file." )
108113
109114 just_file_name = os .path .basename (output_name )
110115
@@ -113,6 +118,27 @@ def _do_store(self, output):
113118
114119 return (STORE_TYPE .PATH , output_name , url )
115120
121+ @staticmethod
122+ def copy (src , dst , copy_function = None ):
123+ """Copy file from source to destination using `copy_function`.
124+
125+ Values of `copy_function` (default=`copy`):
126+ * copy: using `shutil.copy2`
127+ * move: using `shutil.move`
128+ * link: using `os.link` (hardlink)
129+ """
130+ import shutil
131+ if copy_function == 'move' :
132+ shutil .move (src , dst )
133+ elif copy_function == 'link' :
134+ try :
135+ os .link (src , dst )
136+ except Exception :
137+ LOGGER .warn ("Could not create hardlink. Fallback to copy." )
138+ FileStorage .copy (src , dst )
139+ else :
140+ shutil .copy2 (src , dst )
141+
116142 def write (self , data , destination , data_format = None ):
117143 """
118144 Write data to self.target
0 commit comments