77from datetime import datetime
88from pathlib import Path
99from typing import Dict , Generator , List , Optional
10+ from urllib .parse import quote
1011from xml .etree import ElementTree as ET
1112
1213from defusedxml .ElementTree import parse
@@ -128,13 +129,13 @@ def post_transfer(
128129 logger .warning (f"No source found for file { transferred_file } " )
129130 return False
130131
131- # Get the Path on the DLS file system
132- file_path = _file_transferred_to (
132+ # Get the file Path at the destination
133+ destination_file = _file_transferred_to (
133134 environment = environment ,
134135 source = source ,
135136 file_path = transferred_file ,
136137 )
137- if not file_path :
138+ if not destination_file :
138139 logger .warning (
139140 f"File { transferred_file .name !r} not found on the storage system"
140141 )
@@ -167,16 +168,22 @@ def post_transfer(
167168 if len (transferred_file .stem .split ("--" )) == 3 :
168169 series_name = "/" .join (
169170 [
170- * file_path .parent .parts [- 2 :], # Upper 2 parent directories
171- file_path .stem .split ("--" )[0 ],
171+ * destination_file .parent .parts [
172+ - 2 :
173+ ], # Upper 2 parent directories
174+ destination_file .stem .split ("--" )[0 ],
172175 ]
173176 )
174177 # When this a repeated position
175178 elif len (transferred_file .stem .split ("--" )) == 4 :
176179 series_name = "/" .join (
177180 [
178- * file_path .parent .parts [- 2 :], # Upper 2 parent directories
179- "--" .join (file_path .stem .split ("--" )[i ] for i in [0 , - 1 ]),
181+ * destination_file .parent .parts [
182+ - 2 :
183+ ], # Upper 2 parent directories
184+ "--" .join (
185+ destination_file .stem .split ("--" )[i ] for i in [0 , - 1 ]
186+ ),
180187 ]
181188 )
182189 else :
@@ -196,7 +203,7 @@ def post_transfer(
196203 if series_name not in self ._tiff_timestamps .keys ():
197204 self ._tiff_timestamps [series_name ] = []
198205 # Append information to list
199- self ._tiff_series [series_name ].append (str (file_path ))
206+ self ._tiff_series [series_name ].append (str (destination_file ))
200207 self ._tiff_sizes [series_name ].append (transferred_file .stat ().st_size )
201208 self ._tiff_timestamps [series_name ].append (
202209 transferred_file .stat ().st_ctime
@@ -205,6 +212,11 @@ def post_transfer(
205212 f"Created TIFF file dictionary entries for { series_name !r} "
206213 )
207214
215+ # Register the TIFF file in the database
216+ post_result = self .register_tiff_file (destination_file , environment )
217+ if post_result is False :
218+ return False
219+
208220 # Process XLIF files
209221 if transferred_file .suffix == ".xlif" :
210222
@@ -230,7 +242,7 @@ def post_transfer(
230242 # XLIF files don't have the "--ZXX--CXX" additions in the file name
231243 # But they have "/Metadata/" as the immediate parent
232244 series_name = "/" .join (
233- [* file_path .parent .parent .parts [- 2 :], file_path .stem ]
245+ [* destination_file .parent .parent .parts [- 2 :], destination_file .stem ]
234246 ) # The previous 2 parent directories should be unique enough
235247 logger .debug (
236248 f"File { transferred_file .name !r} given the series name { series_name !r} "
@@ -262,11 +274,14 @@ def post_transfer(
262274
263275 # Update dictionary entries
264276 self ._files_in_series [series_name ] = num_files
265- self ._series_metadata [series_name ] = str (file_path )
277+ self ._series_metadata [series_name ] = str (destination_file )
266278 self ._metadata_size [series_name ] = transferred_file .stat ().st_size
267279 self ._metadata_timestamp [series_name ] = transferred_file .stat ().st_ctime
268280 logger .debug (f"Created dictionary entries for { series_name !r} metadata" )
269281
282+ # A new copy of the metadata file is created in 'processed', so no need
283+ # to register this instance of it
284+
270285 # Post message if all files for the associated series have been collected
271286 # .get(series_name, 0) returns 0 if no associated key is found
272287 if not len (self ._tiff_series .get (series_name , [])):
@@ -284,26 +299,20 @@ def post_transfer(
284299 f"Collected expected number of TIFF files for series { series_name !r} ; posting job to server"
285300 )
286301
287- # Construct URL for Murfey server to communicate with
288- url = f"{ str (environment .url .geturl ())} /sessions/{ environment .murfey_session } /tiff_to_stack"
289- if not url :
290- logger .warning ("No URL found for the environment" )
291- return True
292-
293302 # Post the message and log any errors that arise
294- capture_post (
295- url ,
296- json = {
297- "series_name " : series_name ,
298- "tiff_files " : self ._tiff_series [series_name ],
299- "tiff_sizes " : self ._tiff_sizes [series_name ],
300- "tiff_timestamps " : self ._tiff_timestamps [series_name ],
301- "series_metadata " : self ._series_metadata [series_name ],
302- "metadata_size " : self . _metadata_size [ series_name ] ,
303- "metadata_timestamp" : self . _metadata_timestamp [ series_name ],
304- "description" : "" ,
305- },
306- )
303+ tiff_dataset = {
304+ "series_name" : series_name ,
305+ "tiff_files" : self . _tiff_series [ series_name ],
306+ "tiff_sizes " : self . _tiff_sizes [ series_name ] ,
307+ "tiff_timestamps " : self ._tiff_timestamps [series_name ],
308+ "series_metadata " : self ._series_metadata [series_name ],
309+ "metadata_size " : self ._metadata_size [series_name ],
310+ "metadata_timestamp " : self ._metadata_timestamp [series_name ],
311+ "description " : "" ,
312+ }
313+ post_result = self . process_tiff_series ( tiff_dataset , environment )
314+ if post_result is False :
315+ return False
307316 return True
308317 else :
309318 logger .debug (f"TIFF series { series_name !r} is still being processed" )
@@ -323,32 +332,142 @@ def post_transfer(
323332 return True
324333
325334 logger .debug (
326- f"File { transferred_file .name !r} is a valid LIF file; posting job to server "
335+ f"File { transferred_file .name !r} is a valid LIF file; starting processing "
327336 )
328337
329- # Construct the URL for the Murfey server to communicate with
330- url = f"{ str (environment .url .geturl ())} /sessions/{ environment .murfey_session } /lif_to_stack"
331- # Type checking to satisfy MyPy
332- if not url :
333- logger .warning ("No URL found for the environment" )
334- return True
335-
336- # Get the Path on the DLS file system
337- file_path = _file_transferred_to (
338+ # Get the Path at the destination
339+ destination_file = _file_transferred_to (
338340 environment = environment ,
339341 source = source ,
340342 file_path = transferred_file ,
341343 )
344+ if not destination_file :
345+ logger .warning (
346+ f"File { transferred_file .name !r} not found on the storage system"
347+ )
348+ return False
349+
350+ # Post URL to register LIF file in database
351+ post_result = self .register_lif_file (destination_file , environment )
352+ if post_result is False :
353+ return False
354+ logger .debug (f"Registered { destination_file .name !r} in the database" )
355+
356+ # Post URL to trigger job and convert LIF file into image stacks
357+ post_result = self .process_lif_file (destination_file , environment )
358+ if post_result is False :
359+ return False
360+ logger .debug (f"Started preprocessing of { destination_file .name !r} " )
342361
343- # Post the message and logs it if there's an error
344- capture_post (
345- url ,
346- json = {
347- "name" : str (file_path ),
348- "size" : transferred_file .stat ().st_size , # File size, in bytes
349- "timestamp" : transferred_file .stat ().st_ctime , # For Unix systems, shows last metadata change
350- "description" : "" ,
351- },
352- )
353362 return True
354363 return True
364+
365+ def register_lif_file (
366+ self ,
367+ lif_file : Path ,
368+ environment : MurfeyInstanceEnvironment ,
369+ ):
370+ """
371+ Constructs the URL and dictionary to be posted to the server, which will then
372+ register the LIF file in the database correctly as part of the CLEM workflow.
373+ """
374+ try :
375+ # Construct URL to post to post the request to
376+ url = f"{ str (environment .url .geturl ())} /sessions/{ environment .murfey_session } /clem/lif_files?lif_file={ quote (str (lif_file ), safe = '' )} "
377+ # Validate
378+ if not url :
379+ logger .error (
380+ "URL could not be constructed from the environment and file path"
381+ )
382+ return ValueError
383+
384+ # Send the message
385+ capture_post (url )
386+ return True
387+
388+ except Exception :
389+ logger .error (
390+ "Error encountered when registering the LIF file in the database"
391+ )
392+ return False
393+
394+ def process_lif_file (
395+ self ,
396+ lif_file : Path ,
397+ environment : MurfeyInstanceEnvironment ,
398+ ):
399+ """
400+ Constructs the URL and dictionary to be posted to the server, which will then
401+ trigger the preprocessing of the LIF file.
402+ """
403+
404+ try :
405+ # Construct the URL to post the request to
406+ url = f"{ str (environment .url .geturl ())} /sessions/{ environment .murfey_session } /lif_to_stack?lif_file={ quote (str (lif_file ), safe = '' )} "
407+ # Validate
408+ if not url :
409+ logger .error (
410+ "URL could not be constructed from the environment and file path"
411+ )
412+ return ValueError
413+
414+ # Send the message
415+ capture_post (url )
416+ return True
417+
418+ except Exception :
419+ logger .error ("Error encountered processing LIF file" )
420+ return False
421+
422+ def register_tiff_file (
423+ self ,
424+ tiff_file : Path ,
425+ environment : MurfeyInstanceEnvironment ,
426+ ):
427+ """
428+ Constructs the URL and dictionary to be posted to the server, which will then
429+ register the TIFF file in the database correctly as part of the CLEM workflow.
430+ """
431+
432+ try :
433+ url = f"{ str (environment .url .geturl ())} /sessions/{ environment .murfey_session } /clem/tiff_files?tiff_file={ quote (str (tiff_file ), safe = '' )} "
434+ if not url :
435+ logger .error (
436+ "URL could not be constructed from the environment and file path"
437+ )
438+ return ValueError
439+
440+ # Send the message
441+ capture_post (url )
442+ return True
443+
444+ except Exception :
445+ logger .error (
446+ "Error encountered when registering the TIFF file in the database"
447+ )
448+
449+ def process_tiff_series (
450+ self ,
451+ tiff_dataset : dict ,
452+ environment : MurfeyInstanceEnvironment ,
453+ ):
454+ """
455+ Constructs the URL and dictionary to be posted to the server, which will then
456+ trigger the preprocessing of this instance of a TIFF series.
457+ """
458+
459+ try :
460+ # Construct URL for Murfey server to communicate with
461+ url = f"{ str (environment .url .geturl ())} /sessions/{ environment .murfey_session } /tiff_to_stack"
462+ if not url :
463+ logger .error (
464+ "URL could not be constructed from the environment and file path"
465+ )
466+ return ValueError
467+
468+ # Send the message
469+ capture_post (url , json = tiff_dataset )
470+ return True
471+
472+ except Exception :
473+ logger .error ("Error encountered processing the TIFF series" )
0 commit comments