2121import glob
2222import os
2323import shutil
24+ import hashlib
2425from warnings import warn
2526
2627from enthought .traits .trait_errors import TraitError
@@ -493,9 +494,11 @@ class XNATSourceInputSpec(DynamicTraitedSpec): #InterfaceInputSpec):
493494 value = dict (outfiles = []), usedefault = True ,
494495 desc = 'Information to plug into template' )
495496
496- xnat_server = traits .Str (mandatory = True , desc = 'XNAT server URL' )
497- xnat_user = traits .Str (mandatory = True , desc = 'XNAT user' )
498- xnat_pwd = traits .Password (mandatory = True , desc = 'XNAT password' )
497+ xnat_server = traits .Str (mandatory = True , requires = ['xnat_user' , 'xnat_pwd' ], xor = ['xnat_config' ])
498+ xnat_user = traits .Str ()
499+ xnat_pwd = traits .Password ()
500+ xnat_config = File (mandatory = True , xor = ['xnat_server' ])
501+
499502 cache_dir = Directory (desc = 'Cache directory' )
500503 cache_size = traits .Str (desc = 'Optional cache max size' )
501504
@@ -582,7 +585,13 @@ def _list_outputs(self):
582585 # infields are mandatory, however I could not figure out how to set 'mandatory' flag dynamically
583586 # hence manual check
584587
585- xnat = pyxnat .Interface (self .inputs .xnat_server ,self .inputs .xnat_user , self .inputs .xnat_pwd )
588+ cache_dir = self .cache_dir or tempfile .gettempdir ()
589+
590+ if self .inputs .xnat_server :
591+ xnat = pyxnat .Interface (self .inputs .xnat_server ,self .inputs .xnat_user , self .inputs .xnat_pwd , cache_dir )
592+ else :
593+ xnat = pyxnat .Interface (self .inputs .xnat_config )
594+
586595# xnat.set_offline_mode()
587596
588597 if self ._infields :
@@ -646,17 +655,12 @@ def _list_outputs(self):
646655
647656class XNATSinkInputSpec (DynamicTraitedSpec ):
648657
649- # base_directory = Directory(
650- # desc='Path to the base directory consisting of subject data.')
651- # container = traits.Str(desc = 'Folder within basedirectory in which to store output')
652- # parameterization = traits.Bool(True, usedefault=True,
653- # desc='store output in parameterized structure')
654- # strip_dir = Directory(desc='path to strip out of filename')
655658 _outputs = traits .Dict (traits .Str , value = {}, usedefault = True )
656659
657- xnat_server = traits .Str (mandatory = True )
658- xnat_user = traits .Str (mandatory = True )
659- xnat_pwd = traits .Password (mandatory = True )
660+ xnat_server = traits .Str (mandatory = True , requires = ['xnat_user' , 'xnat_pwd' ], xor = ['xnat_config' ])
661+ xnat_user = traits .Str ()
662+ xnat_pwd = traits .Password ()
663+ xnat_config = File (mandatory = True , xor = ['xnat_server' ])
660664 cache_dir = Directory (desc = '' )
661665 cache_size = traits .Str ()
662666
@@ -669,6 +673,7 @@ def __setattr__(self, key, value):
669673 self ._outputs [key ] = value
670674 else :
671675 super (XNATSinkInputSpec , self ).__setattr__ (key , value )
676+
672677
673678class XNATSink (IOBase ):
674679 """ Generic datasink module that takes a directory containing a
@@ -681,12 +686,19 @@ def _list_outputs(self):
681686 """Execute this module.
682687 """
683688
684- xnat = pyxnat .Interface (self .inputs .xnat_server ,self .inputs .xnat_user , self .inputs .xnat_pwd )
689+ cache_dir = self .cache_dir or tempfile .gettempdir ()
690+
691+ if self .inputs .xnat_server :
692+ xnat = pyxnat .Interface (self .inputs .xnat_server ,self .inputs .xnat_user , self .inputs .xnat_pwd , cache_dir )
693+ else :
694+ xnat = pyxnat .Interface (self .inputs .xnat_config )
685695
686696 uri_template_args = {'project_id' :self .inputs .project_id ,
687697 'subject_id' :self .inputs .subject_id ,
688- 'experiment_id' :str (hash (self .inputs .subject_id )) + \
689- '_' + self .inputs .experiment_id ,
698+ 'experiment_id' : '%s_%s' % \
699+ (hashlib .md5 (self .inputs .subject_id ).hexdigest (),
700+ self .inputs .experiment_id
701+ )
690702 }
691703
692704 for key ,files in self .inputs ._outputs .items ():
@@ -714,18 +726,19 @@ def write_file_to_XNAT(xnat, name, key, uri_template_args):
714726 if str (self .inputs .subject_id ) not in val :
715727 recon_label .extend ([key , val ])
716728
729+ uri_template_args ['recon_label' ] = \
730+ hashlib .md5 (uri_template_args ['experiment_id' ]).hexdigest ()
731+
717732 if recon_label :
718- uri_template_args ['recon_label' ] = str (hash (uri_template_args ['experiment_id' ])) + \
719- '_' + '_' .join (recon_label )
720- else :
721- uri_template_args ['recon_label' ] = str (hash (uri_template_args ['experiment_id' ]))
733+ uri_template_args ['recon_label' ] += '_' .join (recon_label )
722734
723- uri_template_args ['resource_label' ] = str (hash (uri_template_args ['recon_label' ])) + \
724- '_' + key .split ('.' )[0 ]
735+ uri_template_args ['resource_label' ] = '%s_%s' % \
736+ (hashlib .md5 (uri_template_args ['recon_label' ]).hexdigest (),
737+ key .split ('.' )[0 ]
738+ )
725739
726740 uri_template_args ['file_name' ] = os .path .split (os .path .abspath (name ))[1 ]
727741
728-
729742 uri_template = ('/project/%(project_id)s/subject/%(subject_id)s'
730743 '/experiment/%(experiment_id)s/reconstruction/%(recon_label)s'
731744 '/out/resource/%(resource_label)s/file/%(file_name)s' )
0 commit comments