1616"""
1717
1818import re
19+ import warnings
1920from datetime import datetime
2021
2122TAP_UTILS_QUERY_TOP_PATTERN = re .compile (
@@ -101,7 +102,7 @@ def set_top_in_query(query, top):
101102 else :
102103 # no all nor distinct: add top after select
103104 p = q .replace ("\n " , " " ).find ("SELECT " )
104- nq = f"{ query [0 :p + 7 ]} TOP { top } { query [p + 7 :]} "
105+ nq = f"{ query [0 :p + 7 ]} TOP { top } { query [p + 7 :]} "
105106 return nq
106107
107108
@@ -140,7 +141,7 @@ def parse_http_response_error(responseStr, status):
140141 pos2 = responseStr .find ('</li>' , pos1 )
141142 if pos2 == - 1 :
142143 return parse_http_votable_response_error (responseStr , status )
143- msg = responseStr [(pos1 + len (TAP_UTILS_HTTP_ERROR_MSG_START )):pos2 ]
144+ msg = responseStr [(pos1 + len (TAP_UTILS_HTTP_ERROR_MSG_START )):pos2 ]
144145 return f"Error { status } :\n { msg } "
145146
146147
@@ -162,7 +163,7 @@ def parse_http_votable_response_error(responseStr, status):
162163 pos2 = responseStr .find (TAP_UTILS_VOTABLE_INFO , pos1 )
163164 if pos2 == - 1 :
164165 return f"Error { status } :\n { responseStr } "
165- msg = responseStr [(pos1 + len (TAP_UTILS_HTTP_VOTABLE_ERROR )):pos2 ]
166+ msg = responseStr [(pos1 + len (TAP_UTILS_HTTP_VOTABLE_ERROR )):pos2 ]
166167 return f"Error { status } : { msg } "
167168
168169
@@ -178,7 +179,7 @@ def get_jobid_from_location(location):
178179 -------
179180 A jobid.
180181 """
181- pos = location .rfind ('/' )+ 1
182+ pos = location .rfind ('/' ) + 1
182183 jobid = location [pos :]
183184 return jobid
184185
@@ -217,26 +218,75 @@ def get_table_name(full_qualified_table_name):
217218 pos = full_qualified_table_name .rfind ('.' )
218219 if pos == - 1 :
219220 return full_qualified_table_name
220- name = full_qualified_table_name [pos + 1 :]
221+ name = full_qualified_table_name [pos + 1 :]
221222 return name
222223
223224
224- def get_suitable_output_file (conn_handler , async_job , outputFile , headers ,
225- isError , output_format ):
226- dateTime = datetime .now ().strftime ("%Y%m%d%H%M%S" )
227- fileName = ""
228- if outputFile is None :
229- fileName = conn_handler .get_file_from_header (headers )
230- if fileName is None :
225+ def get_suitable_output_file (conn_handler , async_job , output_file , headers ,
226+ is_error , output_format ):
227+ date_time = datetime .now ().strftime ("%Y%m%d%H%M%S" )
228+ if output_file is None :
229+ file_name = conn_handler .get_file_from_header (headers )
230+ if file_name is None :
231231 ext = conn_handler .get_suitable_extension (headers )
232232 if not async_job :
233- fileName = f"sync_{ dateTime } { ext } "
233+ file_name = f"sync_{ date_time } { ext } "
234234 else :
235235 ext = conn_handler .get_suitable_extension_by_format (
236236 output_format )
237- fileName = f"async_{ dateTime } { ext } "
237+ file_name = f"async_{ date_time } { ext } "
238238 else :
239- fileName = outputFile
240- if isError :
241- fileName += ".error"
242- return fileName
239+ file_name = output_file
240+ if is_error :
241+ file_name += ".error"
242+ return file_name
243+
244+
245+ def get_suitable_output_file_name_for_current_output_format (output_file , output_format ):
246+ """ renames the name given for the output_file if the results for current_output format are returned compressed by default
247+ and the name selected by the user does not contain the correct extension.
248+
249+ output_file : str, optional, default None
250+ file name selected by the user
251+ output_format : str, optional, default 'votable'
252+ results format. Available formats in TAP are: 'votable', 'votable_plain',
253+ 'fits', 'csv', 'ecsv' and 'json'. Default is 'votable'.
254+ Returned results for formats 'votable' 'ecsv' and 'fits' are compressed
255+ gzip files.
256+
257+ Returns
258+ -------
259+ A string with the new name for the file.
260+ """
261+ compressed_extension = ".gz"
262+ format_with_results_compressed = ['votable' , 'fits' , 'ecsv' ]
263+ output_file_with_extension = output_file
264+
265+ if output_file is not None :
266+ if output_format in format_with_results_compressed :
267+ # In this case we will have to take also into account the .fits format
268+ if not output_file .endswith (compressed_extension ):
269+ warnings .warn ('By default, results in "votable", "ecsv" and "fits" format are returned in '
270+ f'compressed format therefore your file { output_file } '
271+ f'will be renamed to { output_file } .gz' )
272+ if output_format == 'votable' :
273+ if output_file .endswith ('.vot' ):
274+ output_file_with_extension = output_file + '.gz'
275+ else :
276+ output_file_with_extension = output_file + '.vot.gz'
277+ elif output_format == 'fits' :
278+ if output_file .endswith ('.fits' ):
279+ output_file_with_extension = output_file + '.gz'
280+ else :
281+ output_file_with_extension = output_file + '.fits.gz'
282+ elif output_format == 'ecsv' :
283+ if output_file .endswith ('.ecsv' ):
284+ output_file_with_extension = output_file + '.gz'
285+ else :
286+ output_file_with_extension = output_file + '.ecsv.gz'
287+ # the output type is not compressed by default by the TAP SERVER but the users gives a .gz extension
288+ elif output_file .endswith (compressed_extension ):
289+ output_file_renamed = output_file .removesuffix ('.gz' )
290+ warnings .warn (f'The output format selected is not compatible with compression. { output_file } '
291+ f' will be renamed to { output_file_renamed } ' )
292+ return output_file_with_extension
0 commit comments