Beispiel #1
0
 def __init__(self, browser, XNATCommunicator, sessionArgs):
     """ Parent class of any load workflow
     """
     self.browser = browser
     self.scenePackager = XNATScenePackager(self.browser)
     self.utils = XNATUtils()
     self.sessionArgs = sessionArgs
     self.XNATCommunicator = XNATCommunicator
Beispiel #2
0
    def __init__(self, browser):
        
        self.browser = browser

        self.utils = XNATUtils()       
        self.sessionFileName = os.path.join(self.utils.utilPath, 'SessionLog.txt')
        
        self.sessionArgs = None
        self.saveItem = None
Beispiel #3
0
 def __init__(self, browser=None):         
     self.browser = browser
     self.utils = XNATUtils()
     
     self.useCache = True
     self.useCacheMsgBox = None
     self.resetUseCacheMsgBox()
     
     self.tempLocalFileMap = None
     self.tempNewFilename = None
     self.cacheList = None
     
     self.TESTWRITE = False
Beispiel #4
0
 def __init__(self, browser, 
                    server, 
                    user, 
                    password, 
                    cachedir):
     self.browser = browser
     self.server = server
     self.user = user
     self.password = password
     self.cachedir = cachedir
     self.utils = XNATUtils()
     self.XNAT = None
     self.progDialog = None
     self.setup()
 
     self.totalDLSize = 0
     self.downloadedBytes = 0
Beispiel #5
0
class XNATSessionManager(object):
    def __init__(self, browser):
        
        self.browser = browser

        self.utils = XNATUtils()       
        self.sessionFileName = os.path.join(self.utils.utilPath, 'SessionLog.txt')
        
        self.sessionArgs = None
        self.saveItem = None
    
    def startNewSession(self, sessionArgs):
        if not sessionArgs.__class__.__name__ == "XNATSessionArgs":
            raise NameError("You can only use XNATSessionArgs to start a new session.")
        self.sessionArgs = sessionArgs
        self.writeSession()
        
    def clearCurrentSession(self):
        #print(self.utils.lf() + "CLEARING CURRENT SESSION!")
        self.sessionArgs = None


    def writeSession(self):
        
        fileLines = []
        
        for item in self.sessionArgs:
            fileLines.append("%s:\t\t%s\n"%(item, self.sessionArgs[item]))
        
        fileLines.append("\n\n")
        print(self.utils.lf() + "Session log file: %s"%(self.sessionFileName))
        f = open(self.sessionFileName, 'a')
        f.writelines(fileLines)            
        f.close()
        
        del fileLines
Beispiel #6
0
class XNATMRMLParser(object):
    """XNATMRMLParser is the class that parses and changes strings in a given .mrml file
    """
    def __init__(self, browser=None):         
        self.browser = browser
        self.utils = XNATUtils()
        
        self.useCache = True
        self.useCacheMsgBox = None
        self.resetUseCacheMsgBox()
        
        self.tempLocalFileMap = None
        self.tempNewFilename = None
        self.cacheList = None
        
        self.TESTWRITE = False
                    
    def changeValues(self, filename, newFilename, replaceValues, 
                     otherReplaceValues, removeOriginalFile = False, 
                     debug = True):
        self.browser.updateStatus(["Changing values in the mrml.", "", ""]) 
        #print (self.utils.lf() + " MRML PARSER CHANGE VALUES!")
        #=======================================================================
        # CONCATENATE ALL REPLACE VALUES
        #=======================================================================
        dicoms = []
        compLines = []
        if otherReplaceValues:
            replaceValues.update(otherReplaceValues)
          
        #=======================================================================
        # CREATE NEW MRML, BACKUP OLD
        #=======================================================================
        if filename == newFilename:
            bkpFN = filename.split(".")[0] + ".BKP"
            shutil.copy(filename,bkpFN)
            self.utils.removeFile(filename)
            slicer.app.processEvents()
            filename = bkpFN
       
        #=======================================================================
        # INIT XML PARSER
        #=======================================================================
        elementTree = ET.parse(codecs.open(filename, encoding="UTF-8"))
        root = elementTree.getroot()
        iterator = root.getiterator()
        for subelement in iterator:
            if subelement.keys():
                for name, value in subelement.items():
                    #===========================================================
                    # if no strings to be changed, at least make sure filepaths are relative
                    #===========================================================
                    if replaceValues == {}:
                        if os.path.basename(os.path.dirname(value)).lower() == "data":
                            #print self.utils.lf() + " CHANGING NAME WITH DATA FORMAT: %s\tOLD: %s\tNEW:%s"%(subelement.attrib[name], value, "./Data/" + os.path.basename(value))
                            subelement.attrib[name] = "./Data/%s"%(os.path.basename(value))
        self.browser.updateStatus(["Writing a new element tree in the mrml.", "", ""])
        #=======================================================================
        # write new mrml
        #=======================================================================
        elementTree.write(newFilename)        
        ### For testing purposes #############################################################
        #if self.TESTWRITE:
        #    z = open(filename,"r")
        #    oldlines = z.readlines()
        #    z.close()
        #    self.makeMrmlReadable(str(newFilename).split(".")[0]+"BEFORE", oldlines)
        #    self.makeMrmlReadable(str(newFilename).split(".")[0]+"AFTER", lines)      
        ######################################################################################

        #=======================================================================
        # return the dicom files, if necessary
        #=======================================================================
        self.browser.updateStatus(["Done writing new mrml!", "", ""])
        return {"dicoms": dicoms}        
                            
        
    def localizeRemoteMRMLLinks(self, filename, downloadRemoteLinks = True):   
        """Used for the 'load' workflow.  This changes remote URIs (ones with the 
           http and https perefixes) .  
        """
        #=======================================================================
        # INIT DICTIONARY
        #=======================================================================
        self.cacheList = []
        fileNameKey = "fileName"
        fileListMemberKey = "fileListMember"
        remoteLocalFileMap = {}     
        compLines = []
        
        #=======================================================================
        # BEGIN MRML PARSING
        #=======================================================================
        elementTree = ET.parse(codecs.open(filename, encoding="UTF-8"))
        root = elementTree.getroot()
        iterator = root.getiterator()
        for subelement in iterator:
            if subelement.keys():
                for name, value in subelement.items():              
                    #===========================================================
                    # if the URI has a remote prefix, begin algorithm
                    #===========================================================            
                    if ("http://" in value) or ("https://" in value):
                        print self.utils.lf() +  "\t\tName: '%s', Value: '%s'"%(name, value)  
                        #=======================================================
                        # removes the https://www.host.*** prefix
                        #=======================================================
                        _localURI =  self.utils.adjustPathSlashes("%s%s"%(self.utils.remoteFilePath,
                                                                          str(qt.QUrl(value).path()).split('archive')[1]))                 
                        print (self.utils.lf() +  "GIVEN URL: " + value + 
                               " INITIAL PATH VALUE: " + _localURI)
                        #=======================================================
                        # creates a new local URI based on the module cache paths
                        #=======================================================
                        tempFileInfo = XNATFileInfo(remoteURI = value, localURI = _localURI)
                        newValue = tempFileInfo.localURI
                        #=======================================================
                        # special case for handling .raw files
                        #=======================================================
                        if _localURI.endswith("raw"): #special case                
                            newValue = os.path.join(os.path.join(tempFileInfo.localDirName, 
                                                                 tempFileInfo.basenameNoExtension), 
                                                    tempFileInfo.basename)                      
                            print (self.utils.lf() + "FOUND RAW: " + self.utils.adjustPathSlashes(newValue))
                        #=======================================================
                        # makes sure path slashes are all forward
                        #=======================================================
                        newValue = self.utils.adjustPathSlashes(newValue)
                        if "win" in sys.platform: 
                            newValue = newValue.replace('\\', '/')                                                                           
                        #=======================================================
                        # if the value does not exist in the map...
                        #=======================================================
                        if not value in remoteLocalFileMap: 
                            #===================================================
                            # if no map value, create raw file map values
                            #===================================================
                            print (self.utils.lf() +  ("DICTIONARY: Adding new val."))
                            if tempFileInfo.localURI.endswith('raw'):
                               print self.utils.lf() +  "RAW EXTENSION"                               
                               remoteLocalFileMap[value] = "%s/%s/%s"%(tempFileInfo.localDirName,  
                                                                       os.path.basename(tempFileInfo.localURI).split(".")[0],
                                                                       os.path.basename(tempFileInfo.localURI)) 
                               remoteLocalFileMap[value + ".gz"] = "%s/%s%s"%(tempFileInfo.localDirName,  
                                                                              os.path.basename(tempFileInfo.localURI).split(".")[0], 
                                                                              ".raw.gz")
                            #===================================================
                            # for nodes other than raw files, define its map value 
                            #===================================================
                            else:
                               print self.utils.lf() +  "OTHER EXTENSION"
                               remoteLocalFileMap[value] = tempFileInfo.localURI
                               tempFN = os.path.basename(tempFileInfo.localURI).split(".")[0]
                               tempFolder = os.path.basename(os.path.dirname(tempFileInfo.localURI))
                               print self.utils.lf() +  "TEMPFN %s TEMPFOLDER %s"%(tempFN, tempFolder)
                               if tempFN == tempFolder:
                                   remoteLocalFileMap[value] = "%s%s"%(os.path.dirname(tempFileInfo.localURI), 
                                                                       os.path.basename(tempFileInfo.localURI).split(".")[1])
                            #===================================================
                            # debugging calls
                            #===================================================
                            print self.utils.lf() +  "VALUE: %s and LOCAL %s"%(value, remoteLocalFileMap[value])                      
                            compLines.append("OLDWORD - READ1: '" + value + "'")
                            compLines.append("NEWWORD - READ1: '" + remoteLocalFileMap[value]+ "'\n")
                        #=======================================================
                        # set new mrml values
                        #=======================================================
                        subelement.attrib[name] = remoteLocalFileMap[value]
                    #===========================================================
                    # If there's a local prefix to the string, and it's in the data directory
                    # of the scene...    
                    #===========================================================
                    elif os.path.basename(os.path.dirname(value)).lower() == 'data':
                        ext = os.path.basename(value).split(".")[1]                   
                        newValue = "./Data/%s"%(os.path.basename(value))                
                        compLines.append("DATAOLD - READ2: '" + value + "'")
                        compLines.append("DATANEW - READ2: '" + newValue + "'\n")
                        subelement.attrib[name] = newValue
        #=======================================================================
        # GENERATE NEW FILENAME
        #=======================================================================
        newFilename = filename.replace("-remotized.mrml", self.utils.localizedMRMLExtension + ".mrml") 
        newFilename = os.path.normpath(newFilename)
        #=======================================================================
        # CHANGES DIRECTOR CHARS FOR WINDOWS
        #=======================================================================
        if sys.platform.find("win") > -1:
            newFilename.replace('\\', '/')
        #=======================================================================
        # PRINT LINES FOR DEBUGGING
        #=======================================================================
        for line in compLines:
            print self.utils.lf() +  "COMPLINE: " + line
        #=======================================================================
        # WRITE NEW MRML
        #=======================================================================
        slicer.app.processEvents()      
        elementTree.write(newFilename) 
        slicer.app.processEvents()
        
        #=======================================================================
        # MAKE, RETURN NEW FILENAMES
        #=======================================================================
        self.currLoadManager.newMRMLFile = newFilename
        print self.utils.lf() +  "MRML PARSE FILENAME: " + filename     
        print "*****************" + self.utils.lf() + "MRML PARSER: " + str(remoteLocalFileMap)
        return newFilename, remoteLocalFileMap
                            
    
    def resetUseCacheMsgBox(self):
        """Message box workflow for using the cached files instead of redownloading."""
        self.useCacheMsgBox = qt.QMessageBox()
        self.useCacheMsgBox.setText("It appears that some of the DICOM images in this scene are locally cached.  "+
                                    "Would you like the widget to use them when possible?");
        self.useCacheMsgBox.setInformativeText("NOTE: This will potentially save you load time.");
        self.useCacheMsgBox.setStandardButtons(qt.QMessageBox.Yes | qt.QMessageBox.No)
        self.useCacheMsgBox.setDefaultButton(qt.QMessageBox.Yes)
        

    def toggleUseCache(self, button):
        """Toggles the "use cache" yes/no window."""
        newDict = {}
        if button.text.lower().find('yes') > -1: 
            self.useCache = True
        elif button.text.lower().find('no') > -1: self.useCache = False
        text = "User opted to use cache." if self.useCache else "User selected to opt out of using cache."
        print self.utils.lf() + (text)

        for item in self.cacheList:
            self.tempLocalFileMap[str(item)] = None
        self.downloadRemoteURIs(self.tempLocalFileMap, self.tempNewFilename)



    def makeMrmlReadable(self, filename, lines = None):
        """Makes MRML files more readable to humans (i.e. linebreaks).
        """
        if not lines:
            z = open(filename,"r")
            lines = z.readlines()
            z.close()
            
        f = open(filename,'w' )
        for line in lines:
            words = line.split()
            for word in words:
                word = word.rstrip()
                if len(word)>0:     
                    #word = word.strip() 
                    f.write(word + '\n')
        f.close()
Beispiel #7
0
    def __init__(self):
        self.utils = XNATUtils()
        self.wizard = qt.QWizard()
        self.os_system = ""
        self.os_release = ""
        self.os_machine = ""
        self.introDialog = qt.QMessageBox()
        self.introDialog.setStandardButtons(qt.QMessageBox.Ok | 
                                            qt.QMessageBox.Cancel)
        self.introDialog.setIcon(2)
        self.introDialog.setDefaultButton(qt.QMessageBox.Ok)
        self.introDialog.setText("Before you can browse XNAT, " + 
                                 "the module will install the necessary " + 
                                 "Python libraries. After completion, " + 
                                 "you won't see this wizard again.")            
        self.introDialog.connect('buttonClicked(QAbstractButton*)', 
                                 self.introDialog_next)
        self.checkPermissionsDialog = qt.QMessageBox()
        self.checkPermissionsDialog.setTextFormat(1)
        self.checkPermissionsDialog.setIcon(2)
        self.checkPermissionsDialog.setStandardButtons(qt.QMessageBox.Ok | 
                                                       qt.QMessageBox.Cancel)
        self.checkPermissionsDialog.setDefaultButton(qt.QMessageBox.Ok)
        self.permissionsText = ("Please make sure you have " + 
                                "FULL read/write permissions " + 
                                "for the Slicer install directory '<b>%s</b>'."%(str(slicer.app.slicerHome)) + 
                                "\n\nInstructions on how to do this " + 
                                "are here: <a href=\"https://github.com/sunilk-wustl/XNATSlicer/wiki/Win64Install\">https://github.com/sunilk-wustl/XNATSlicer/wiki/Win64Install</a>")
        self.checkPermissionsDialog.setText(self.permissionsText)
        self.checkPermissionsDialog.connect('buttonClicked(QAbstractButton*)', 
                                            self.checkPermissionsDialog_next)

        self.installStatusDialog = textStatusBar(slicer.qMRMLWidget())
        self.installStatusDialog.textField.setFixedSize(400, 600)
        self.restartDialog = qt.QMessageBox()
        self.restartDialog.setStandardButtons(qt.QMessageBox.Ok | 
                                              qt.QMessageBox.Cancel)
        
        self.restartDialog.setDefaultButton(qt.QMessageBox.Ok)
        self.restartDialog.setText("Slicer must restart in order " + 
                                   "for the new libraries to be recognized.")
        self.restartDialog.connect('buttonClicked(QAbstractButton*)', 
                                   self.restartDialog_next)
        
        self.fileDialog = qt.QFileDialog()
        self.fileDialog.setFileMode(4)
        
        self.installMessages = []
        self.installMessageLen = 30

        for i  in range(0, self.installMessageLen):
            self.installMessages.append("")
    
        self.installDir = None  
        self.isInstalled = True        
        self.installPaths = {}
        self.modPaths = {}
        
        self.copyFiles = []
        files = os.listdir(self.utils.pythonMods_Win64)
        for fileN in files:
            if fileN.find(".") > -1:
                self.copyFiles.append(os.path.join(self.utils.pythonMods_Win64, 
                                                   fileN))
Beispiel #8
0
class XNATInstallWizard(object):
    def __init__(self):
        self.utils = XNATUtils()
        self.wizard = qt.QWizard()
        self.os_system = ""
        self.os_release = ""
        self.os_machine = ""
        self.introDialog = qt.QMessageBox()
        self.introDialog.setStandardButtons(qt.QMessageBox.Ok | 
                                            qt.QMessageBox.Cancel)
        self.introDialog.setIcon(2)
        self.introDialog.setDefaultButton(qt.QMessageBox.Ok)
        self.introDialog.setText("Before you can browse XNAT, " + 
                                 "the module will install the necessary " + 
                                 "Python libraries. After completion, " + 
                                 "you won't see this wizard again.")            
        self.introDialog.connect('buttonClicked(QAbstractButton*)', 
                                 self.introDialog_next)
        self.checkPermissionsDialog = qt.QMessageBox()
        self.checkPermissionsDialog.setTextFormat(1)
        self.checkPermissionsDialog.setIcon(2)
        self.checkPermissionsDialog.setStandardButtons(qt.QMessageBox.Ok | 
                                                       qt.QMessageBox.Cancel)
        self.checkPermissionsDialog.setDefaultButton(qt.QMessageBox.Ok)
        self.permissionsText = ("Please make sure you have " + 
                                "FULL read/write permissions " + 
                                "for the Slicer install directory '<b>%s</b>'."%(str(slicer.app.slicerHome)) + 
                                "\n\nInstructions on how to do this " + 
                                "are here: <a href=\"https://github.com/sunilk-wustl/XNATSlicer/wiki/Win64Install\">https://github.com/sunilk-wustl/XNATSlicer/wiki/Win64Install</a>")
        self.checkPermissionsDialog.setText(self.permissionsText)
        self.checkPermissionsDialog.connect('buttonClicked(QAbstractButton*)', 
                                            self.checkPermissionsDialog_next)

        self.installStatusDialog = textStatusBar(slicer.qMRMLWidget())
        self.installStatusDialog.textField.setFixedSize(400, 600)
        self.restartDialog = qt.QMessageBox()
        self.restartDialog.setStandardButtons(qt.QMessageBox.Ok | 
                                              qt.QMessageBox.Cancel)
        
        self.restartDialog.setDefaultButton(qt.QMessageBox.Ok)
        self.restartDialog.setText("Slicer must restart in order " + 
                                   "for the new libraries to be recognized.")
        self.restartDialog.connect('buttonClicked(QAbstractButton*)', 
                                   self.restartDialog_next)
        
        self.fileDialog = qt.QFileDialog()
        self.fileDialog.setFileMode(4)
        
        self.installMessages = []
        self.installMessageLen = 30

        for i  in range(0, self.installMessageLen):
            self.installMessages.append("")
    
        self.installDir = None  
        self.isInstalled = True        
        self.installPaths = {}
        self.modPaths = {}
        
        self.copyFiles = []
        files = os.listdir(self.utils.pythonMods_Win64)
        for fileN in files:
            if fileN.find(".") > -1:
                self.copyFiles.append(os.path.join(self.utils.pythonMods_Win64, 
                                                   fileN))

    def pyXNATInstalled(self):
        
        slicerRoot = slicer.app.slicerHome
        if slicerRoot.lower().endswith('slicer-build'):
            pyRoot = os.path.join(os.path.dirname(slicer.app.slicerHome), 'python-build')
        else:
            pyRoot = os.path.join(slicer.app.slicerHome, 'lib/Python')
            
        pyRoot = self.utils.adjustPathSlashes(pyRoot)
        self.installPaths = {
            "pyRoot": pyRoot ,     
            "pyDLLs": os.path.join(pyRoot, 
                                   'DLLs'),
            "pylibs": os.path.join(pyRoot, 
                                   'libs'),      
            "pySitePackages": os.path.join(pyRoot, 
                                           'Lib/site-packages'),
            "pyDistUtils": os.path.join(pyRoot, 
                                        'Lib/distutils'),
            "pyDistUtils_Cmd": os.path.join(pyRoot, 
                                            'Lib/distutils/command'), 
            "pyDistUtils_Tests": os.path.join(pyRoot, 
                                              'Lib/distutils/tests'),
            "ez_setup_loc": os.path.join(pyRoot, "Lib")     
        }
        
        self.modPaths = {
                         "pyDLLs": os.path.join(self.utils.pythonMods_Win64, 
                                                "DLLs"),
                         "pylibs": os.path.join(self.utils.pythonMods_Win64, 
                                                "libs"),
                         "pyDistUtils": os.path.join(self.utils.pythonMods_Win64, 
                                                     "Lib/distutils"),
                         "pyDistUtils_Cmd": os.path.join(self.utils.pythonMods_Win64, 
                                                         "Lib/distutils/command"),
                         "pyDistUtils_Tests": os.path.join(self.utils.pythonMods_Win64, 
                                                           "Lib/distutils/tests"),
                         }
        #=======================================================================
        # STEP 1: See if directories even exist
        #=======================================================================
        for val in self.installPaths:
            if not os.path.exists(self.installPaths[val]): 
                return False
        #=======================================================================
        # STEP 2: Make sure the distutils directory has the correct files
        #=======================================================================
        dirList = os.listdir(self.modPaths["pyDistUtils"])
        for fileN in dirList:
            if not os.path.exists(os.path.join(self.installPaths["pyDistUtils"], 
                                               os.path.basename(fileN))):
                print ("DISTUTIL CHECK")
                return False   
        #=======================================================================
        # STEP 3: Make sure the libs directory has the correct files
        #=======================================================================
        dirList = os.listdir(self.modPaths["pylibs"])
        for fileN in dirList:
            if not os.path.exists(os.path.join(self.installPaths["pylibs"], 
                                               os.path.basename(fileN))):
                print ("FILE CHECK")
                return False    
        #=======================================================================
        # STEP 4: Make sure the libs directory has the correct files
        #===============================================================+=======
        dirList = os.listdir(self.modPaths["pyDLLs"])
        for fileN in dirList:
            if not os.path.exists(os.path.join(self.installPaths["pyDLLs"], 
                                               os.path.basename(fileN))):
                print ("DLL")
                return False
        return True
    
    def beginWizard(self):
        self.introDialog.show()
        
    def moveAndInstallLibs_win64(self):
        #=======================================================================
        # STEP 1: Create directories
        #=======================================================================
        for val in self.installPaths:
            if not os.path.exists(self.installPaths[val]):
                try: 
                    os.mkdir(self.utils.adjustPathSlashes(self.installPaths[val]))
                except Exception, e:
                    print ("makdDir error in XNATSlicer install: " + str(e))
                    self.installStatusDialog.textField.close()
                    s = "It looks like you didn't set your permissions correctly.  "
                    newText = "<font color=\"red\"><b>" + s + "</b></font>" + self.permissionsText
                    self.checkPermissionsDialog.setText(newText)
                    self.checkPermissionsDialog.show()
                    return
                self.installStatusDialog.showMessage("Creating directory: '%s'"%
                                                     (self.installPaths[val]))
        #=======================================================================
        # STEP 2: Move installer files to appropriate folders
        #=======================================================================
        import shutil
        for val in self.installPaths:
            try: 
                dirList = os.listdir(os.path.normpath(str(self.modPaths[val])))               
                for fileN in dirList:
                    if val == "pyDistUtils": print(fileN)
                    fileN = os.path.join(self.modPaths[val], fileN)
                    if fileN.find(".") > -1:
                        if not os.path.exists(os.path.join(self.installPaths[val], 
                                                           os.path.basename(fileN))):                        
                            shutil.copy(fileN, os.path.join(self.installPaths[val], 
                                                            os.path.basename(fileN)))
                            self.installStatusDialog.showMessage("Copying file '%s' to '%s' "%
                                                                 (fileN, os.path.join(self.installPaths[val], 
                                                                                      os.path.basename(fileN))))
                            print ("Copying file '%s' to '%s' "%
                                   (fileN, os.path.join(self.installPaths[val], 
                                                        os.path.basename(fileN))))
            except Exception, e:
                print "Warning: " + str(e) + "\n"  
Beispiel #9
0
 def __init__(self, browser = None):
     self.browser = browser
     self.viewer = self.browser.XNATView
     self.utils = XNATUtils()
     self.hostName = 'https://central.xnat.org'
Beispiel #10
0
class XNATScenePackager(object):
    """Class containing methods for packaging scenes pertinent to the 
       Slicer-XNAT workflow.  The major feature of this class is that 
       it handles any shared nodes and 1) uploads them to a "shared" 
       folder on XNAT 2) eliminates them from scene packages sent to XNAT."""
       
    def __init__(self, browser = None):
        self.browser = browser
        self.viewer = self.browser.XNATView
        self.utils = XNATUtils()
        self.hostName = 'https://central.xnat.org'
    
    def determineSceneType(self):
        scene = slicer.app.mrmlScene()
        currURL = os.path.normpath(scene.GetURL())
        if currURL == None or currURL == '': return None
        elif currURL.find(self.utils.projectPath) == 0: return "XNATSlicerScene"
        else: return "LocalScene"                    
        return None
                                       
    def bundleScene(self, args):
            #
            # STEP 1: Init variables.
            #
            XNATCommunicator = args['XNATCommunicator'] 
            XNATDir = args['saveDir']
            XNATSharedDir = args['sharedDir']
            sceneName = args['fileName'] 
            metadata = args['metadata']      
            packageName = os.path.basename(sceneName.split(".")[0])              
            #
            # STEP 2: Analyzes the scene type.
            #
            #print self.utils.lf() +  "ANALYZING SCENE TYPE"
            sceneType = self.determineSceneType() 
            #print self.utils.lf() +  "SCENE TYPE: %s"%(sceneType)                     
            #   
            # STEP 3: Create a directory for packaging.
            #            
            tempDir = os.path.join(self.utils.tempUploadPath, packageName)
            #print self.utils.lf() +  "CREATE PACKAGE DIRECTORY: %s"%(tempDir)
            try:
                #print self.utils.lf() + ("%s does not exist. Making it."%(tempDir)) 
                self.utils.removeFilesInDir(tempDir)
                os.rmdir(tempDir)
            except Exception, e: pass 
            try: os.mkdir(tempDir)
            except Exception, e: pass
            #
            # STEP 4: Write according to scene type and if there's matching metadata.
            #
            #print self.utils.lf() +  "BEGINNING THE SCENE WRITE"
            self.browser.updateStatus(["", "Write all...", ""]) 
            #print self.utils.lf() +  "WRITING ALL!"
            self.writeScene_All(tempDir)            
            slicer.app.processEvents()              
           
            self.browser.updateStatus(["", "Finding mrml...", ""]) 
            mrml = None
            for root, dirs, files in os.walk(tempDir):
                for relFileName in files:
                    if relFileName.endswith("mrml"):
                        mrml = os.path.join(root, relFileName)
                        break
                    
            slicer.app.processEvents()
            self.browser.updateStatus(["", "Bundling scene.  Please wait...", ""])            
            return {'path':self.utils.adjustPathSlashes(tempDir), 
                    'mrml': self.utils.adjustPathSlashes(mrml)}

    # SOURCE OF FOLLOWING CODE: 
    # http://stackoverflow.com/questions/296499/how-do-i-zip-the-contents-of-a-folder-using-python-version-2-5
    #
    # NOTE: To be deprecated after MRB methods are put in place.
    def zipdir(self, basedir=None, zipArchive=None):
        assert os.path.isdir(basedir)
        with closing(ZipFile(zipArchive, "w", ZIP_DEFLATED)) as z:
            for root, dirs, files in os.walk(basedir):
                #NOTE: ignore empty directories
                for fn in files:
                    absfn = os.path.join(root, fn)
                    zfn = absfn[len(basedir)+len(os.sep):] #XXX: relative path
                    z.write(absfn, zfn)
    
    def packageDir(self, packageFilePath, sceneDir):
        #logic = slicer.app.applicationLogic()
        #logic.SaveSceneToSlicerDataBundleDirectory(sceneDir, None)
        slicer.app.applicationLogic().Zip(packageFilePath,sceneDir)
        
    def writeScene_All(self, saveDir):
        #slicer.app.processEvents()       
        if os.path.exists(saveDir): 
            self.utils.removeDirsAndFiles(saveDir)
                #slicer.app.processEvents()
        try: 
            os.makedirs(saveDir + "/Data")
        except Exception, e: 
            print self.utils.lf() +  "Likely the dir already exists: " + str(e)
        slicer.app.applicationLogic().SaveSceneToSlicerDataBundleDirectory(saveDir, None)
        slicer.app.processEvents()
Beispiel #11
0
class XNATSaveWorkflow(object):
    def __init__(self, browser, XNATCommunicator, sessionArgs):
        """ Parent class of any load workflow
        """
        self.browser = browser
        self.scenePackager = XNATScenePackager(self.browser)
        self.utils = XNATUtils()
        self.sessionArgs = sessionArgs
        self.XNATCommunicator = XNATCommunicator
        
    def saveScene(self):       
        #=======================================================================
        #     PACKAGE SCENE
        #
        #     NOTE: The scene packager refers to the .metadata file.     
        #======================================================================= 
        package = self.scenePackager.bundleScene(self.sessionArgs)
        projectDir =         package['path']
        mrmlFile =           package['mrml']  
        #=======================================================================
        #     ZIP PACKAGE
        #=======================================================================           
        self.browser.updateStatus(["Compressing package. Please wait...", "", ""]) 
        packageFileName = projectDir + self.utils.defaultPackageExtension
        if os.path.exists(packageFileName): 
            self.utils.removeFile(packageFileName) 
        self.scenePackager.packageDir(packageFileName, projectDir)
        
        self.browser.updateStatus(["Deleting temporary package.", "", ""])    
        self.utils.removeDirsAndFiles(projectDir)
        #=======================================================================
        #     UPLOAD PACKAGE
        #=======================================================================          
        self.browser.updateStatus(["Sending '%s' to XNAT. Please wait..."%
                                   (os.path.basename(packageFileName)), "", ""])
        #print ("UPLOADING HERE: " + self.sessionArgs['saveDir'] + "/" + os.path.basename(packageFileName))
        self.XNATCommunicator.upload(packageFileName, self.sessionArgs['saveDir'] + "/" + os.path.basename(packageFileName))
        slicer.app.processEvents()
        if self.sessionArgs['sharable']:
            self.browser.updateStatus(["", "Finished updating '%s' in XNAT."%
                                       (os.path.basename(packageFileName)), ""])
        else: self.browser.updateStatus(["", "Finished writing '%s' to XNAT."%
                                         (os.path.basename(packageFileName)), ""])                        
        #=======================================================================
        #     UPDATE VIEWER
        #=======================================================================
        self.sessionArgs['sessionType'] = "scene upload"
        self.browser.XNATView.startNewSession(self.sessionArgs)
        self.browser.XNATView.loadButton.setEnabled(True)
        self.browser.XNATView.deleteButton.setEnabled(True) 
        self.browser.XNATView.setCurrItemToChild(item = None, 
                                                 childFileName = os.path.basename(packageFileName))
        


    def determineSaveLocation(self, itemType, selectedDir, saveLevel = None):
        """ Method goes through various steps to determine the optimal XNAT 
            location to save the current scene.
        """
        #=======================================================================
        #     SET VARIABLES
        #=======================================================================
        print self.utils.lf() + "DETERMINE SAVE DIR"
        currDir = os.path.dirname(selectedDir)
        saveDir = ""
        
              
        #=======================================================================
        #     NONE HANDLER
        #=======================================================================
        if not saveLevel:                                                                     
            # This is where another analysis step could exist to determine where
            # the scene could be saved.                                             
            saveLevel = self.utils.defaultXNATSaveLevel               
        
        #=======================================================================
        #     CHECK SAVE LEVEL VALIDITY
        #=======================================================================
        else:
            findCount = False
            for key, value in self.utils.xnatDepthDict.iteritems():
                if value == saveLevel: 
                    findCount = True
            if not findCount:
                print (self.utils.lf() + 
                       "Couldn't find save level '%s'. Resorting to default: %s"%(saveLevel, self.utils.defaultXNATSaveLevel))
                saveLevel = self.utils.defaultXNATSaveLevel 
        #         Look at the sessionManager, reconcile save dir based on that
        #         and XNATSaveLevel
        if self.browser.XNATView.sessionManager.currSessionInfo:
            saveDir = self.utils.getSlicerDirAtLevel(self.browser.XNATView.sessionManager.currSessionInfo['RemoteURI'], saveLevel)
        else:
            return None            
        print "SAVEDIR: " + saveDir 

        otherRequiredDirs = []
        baseDir = saveDir.split(self.utils.slicerDirName)[0]
        for folderName in self.utils.requiredSlicerFolders:
            otherRequiredDirs.append("%s%s/files/"%(baseDir, folderName))
            
        return {'saveDir': saveDir, 'others': otherRequiredDirs}


                    
Beispiel #12
0
class XNATCommunicator(object):
    def __init__(self, browser, 
                       server, 
                       user, 
                       password, 
                       cachedir):
        self.browser = browser
        self.server = server
        self.user = user
        self.password = password
        self.cachedir = cachedir
        self.utils = XNATUtils()
        self.XNAT = None
        self.progDialog = None
        self.setup()
    
        self.totalDLSize = 0
        self.downloadedBytes = 0
        
    def setup(self):
        pass
    
    def getFiles_URL(self, srcDstMap, withProgressBar = True, fileOrFolder = None):     
        #=======================================================================
        # GET TOTAL SIZE OF DOWNLOADS FOR ALL FILES
        #=======================================================================
        self.totalDLSize = 0
        self.downloadedBytes = 0
        downloadFolders = []
        #=======================================================================
        # REMOVE EXISTING DST FILES
        #=======================================================================
        for src, dst in srcDstMap.iteritems(): 
            if os.path.exists(dst): self.utils.removeFile(dst)
        timeStart = time.time()
        #=======================================================================
        # DOWNLOAD THE FILES
        #=======================================================================
        if fileOrFolder == "file":
            for src, dst in srcDstMap.iteritems():
                #print("FILE DOWNLOAD src:%s\tdst:%s"%(src, dst))
                self.totalDLSize = int(self.XNAT.select(self.cleanSelectString(src)).size())
                if withProgressBar: self.urllib2GetWithProgress(self.cleanSelectString(src), dst)
                else: f.get(dst)                 
        elif fileOrFolder == "folder":
            import tempfile
            xnatFileFolders = []
            #=======================================================================
            # DETERMINE SOURCE FOLDERS, CREATE NEW DICT BASED ON BASENAME
            #=======================================================================
            for src, dst in srcDstMap.iteritems():
                #print("FOLDER D/L src:%s\tdst:%s"%(src, dst))
                srcFolder = os.path.dirname(src)
                if not srcFolder in xnatFileFolders:
                    xnatFileFolders.append(srcFolder)
            #=======================================================================
            # GET THE 'FILEOBJECTS'
            #=======================================================================
            fObjs = []
            for f in xnatFileFolders:
                #print("FOLDER DOWNLOAD %s"%(f))
                fObjs = self.XNAT.select(self.cleanSelectString(os.path.dirname(f))).files().get('~/tmp/files')
                for fO in fObjs:
                    self.totalDLSize += int(fO.size())                    
            for f in xnatFileFolders:
                if withProgressBar: 
                    src = self.cleanSelectString(f + "?format=zip")                 
                    dst = tempfile.mktemp('', 'XNATDownload', self.utils.tempPath) + ".zip"
                    downloadFolders.append(self.utils.adjustPathSlashes(dst))
                    if os.path.exists(dst): self.utils.removeFile(dst)
                    #print("DOWNLOADING %s to %s"%(src, dst))
                    self.urllib2GetWithProgress(src, dst)
                   
        timeEnd = time.time()
        totalTime = (timeEnd-timeStart)
        bps = self.totalDLSize/totalTime

        #print "DOWNLOAD FOLDERS: " + str(downloadFolders)
        return downloadFolders
        #qt.QMessageBox.warning(None, "Time", "Total time: %s. Bps: %s"%(totalTime, str(bps)))
    
    def getFolderContents(self):
        pass
    
    def getItemValue(self):
        pass
    
    def makeDir(self):
        pass

    def upload(self):
        pass

    def delete(self):
        pass
    
    def getSize(self):
        pass
    
    def downloadFailed(self, windowTitle, msg):
            qt.QMessageBox.warning(None, windowTitle, msg)

    def buffer_read(self, response, fileToWrite, dialog=None, buffer_size=8192):
        try:
            itemSize = response.info().getheader('Content-Length').strip()
            itemSize = int(itemSize)
        except Exception, e:
            #print ("ITEM SIZE ERROR %s"%(e))
            pass
        while 1:
            buffer = response.read(buffer_size)
            self.downloadedBytes += len(buffer)
            fileToWrite.write(buffer)
            if not buffer:
                break 
            
            percent = (float(self.downloadedBytes) / self.totalDLSize)
            percent = round(percent*100, 2)
            if percent == 100:
                self.browser.updateStatus(["", "Loading, please wait...", ""])
                self.browser.generalProgressBar.setVisible(False)
            dialog.setValue(percent)
        
        return self.downloadedBytes