| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 | 
							- import os
 
- import unittest
 
- from __main__ import vtk, qt, ctk, slicer
 
- from slicer.ScriptedLoadableModule import *
 
- import slicerNetwork
 
- import loadDicom
 
- import json
 
- #
 
- # labkeySlicerPythonExtension
 
- #
 
- class labkeySlicerPythonExtension(ScriptedLoadableModule):
 
-   """Uses ScriptedLoadableModule base class, available at:
 
-   https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py
 
-   """
 
-   def __init__(self, parent):
 
-     ScriptedLoadableModule.__init__(self, parent)
 
-     self.parent.title = "labkeySlicerPythonExtension" # TODO make this more human readable by adding spaces
 
-     self.parent.categories = ["Examples"]
 
-     self.parent.dependencies = []
 
-     self.parent.contributors = ["Andrej Studen (UL/FMF)"] # replace with "Firstname Lastname (Organization)"
 
-     self.parent.helpText = """
 
-     Labkey interface to slicer
 
-     """
 
-     self.parent.acknowledgementText = """
 
-     Developed within the medical physics research programme of the Slovenian research agency.
 
-     """ # replace with organization, grant and thanks.
 
- #
 
- # labkeySlicerPythonExtensionWidget
 
- #
 
- class labkeySlicerPythonExtensionWidget(ScriptedLoadableModuleWidget):
 
-   """Uses ScriptedLoadableModuleWidget base class, available at:
 
-   https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py
 
-   """
 
-   def setup(self):
 
-     ScriptedLoadableModuleWidget.setup(self)
 
-     # Instantiate and connect widgets ...
 
-     self.logic=labkeySlicerPythonExtensionLogic(self)
 
-     self.network=slicerNetwork.labkeyURIHandler()
 
-     #
 
-     # Parameters Area
 
-     #
 
-     connectionCollapsibleButton = ctk.ctkCollapsibleButton()
 
-     connectionCollapsibleButton.text = "Connection"
 
-     self.layout.addWidget(connectionCollapsibleButton)
 
-     connectionFormLayout = qt.QFormLayout(connectionCollapsibleButton)
 
-     self.configDir='.'
 
-     self.serverURL=qt.QLineEdit("https://merlin.fmf.uni-lj.si")
 
-     self.serverURL.textChanged.connect(self.updateServerURL)
 
-     connectionFormLayout.addRow("Server: ", self.serverURL)
 
-     #copy initial setting
 
-     self.updateServerURL(self.serverURL.text);
 
-     try:
 
-       self.startDir=os.path.join(os.environ['HOME'],"temp/crt")
 
-     except:
 
-       fhome=os.environ['HOMEDRIVE']+os.environ['HOMEPATH']
 
-       self.startDir=os.path.join(fhome,"temp")
 
-     self.userCertButton=qt.QPushButton("Load")
 
-     self.userCertButton.toolTip="Load user certificate (crt)"
 
-     self.userCertButton.connect('clicked(bool)',self.onUserCertButtonClicked)
 
-     connectionFormLayout.addRow("User certificate:",self.userCertButton)
 
-     self.privateKeyButton=qt.QPushButton("Load")
 
-     self.privateKeyButton.toolTip="Load private key"
 
-     self.privateKeyButton.connect('clicked(bool)',self.onPrivateKeyButtonClicked)
 
-     connectionFormLayout.addRow("Private key:",self.privateKeyButton)
 
-     self.caCertButton=qt.QPushButton("Load")
 
-     self.caCertButton.toolTip="Load CA certificate (crt)"
 
-     self.caCertButton.connect('clicked(bool)',self.onCaCertButtonClicked)
 
-     connectionFormLayout.addRow("CA certificate:",self.caCertButton)
 
-     self.loadConfigButton=qt.QPushButton("Load configuration")
 
-     self.loadConfigButton.toolTip="Load configuration"
 
-     self.loadConfigButton.connect('clicked(bool)',self.onLoadConfigButtonClicked)
 
-     connectionFormLayout.addRow("Connection:",self.loadConfigButton)
 
-     self.initButton=qt.QPushButton("Init")
 
-     self.initButton.toolTip="Initialize connection to the server"
 
-     self.initButton.connect('clicked(bool)',self.onInitButtonClicked)
 
-     connectionFormLayout.addRow("Connection:",self.initButton)
 
-     self.authName=qt.QLineEdit("email")
 
-     self.authName.textChanged.connect(self.updateAuthName)
 
-     connectionFormLayout.addRow("Labkey username: ", self.authName)
 
-     self.authPass=qt.QLineEdit("")
 
-     self.authPass.setEchoMode(qt.QLineEdit.Password)
 
-     self.authPass.textChanged.connect(self.updateAuthPass)
 
-     connectionFormLayout.addRow("Labkey password: ", self.authPass)
 
-     fileDialogCollapsibleButton = ctk.ctkCollapsibleButton()
 
-     fileDialogCollapsibleButton.text = "Remote files"
 
-     self.layout.addWidget(fileDialogCollapsibleButton)
 
-     # Layout within the dummy collapsible button
 
-     fileDialogFormLayout = qt.QFormLayout(fileDialogCollapsibleButton)
 
-     #add item list for each found file/directory
 
-     self.fileList=qt.QListWidget()
 
-     self.fileList.toolTip="Select remote file"
 
-     self.fileList.itemDoubleClicked.connect(self.onFileListDoubleClicked)
 
-     self.currentRemoteDir=''
 
-     #add dummy entry
 
-     items=('.','..')
 
-     self.populateFileList(items)
 
-     fileDialogFormLayout.addWidget(self.fileList)
 
-     #add selected file display
 
-     self.selectedFile=qt.QLineEdit("")
 
-     self.selectedFile.toolTip="Selected file"
 
-     fileDialogFormLayout.addRow("Selected file :",self.selectedFile)
 
-     #add possible file Content
 
-     self.fileTypeSelector=qt.QComboBox()
 
-     self.fileTypeSelector.toolTip="Select file type"
 
-     items=self.network.fileTypesAvailable()
 
-     self.populateFileTypeSelector(items)
 
-     fileDialogFormLayout.addRow("File type :",self.fileTypeSelector)
 
-     self.keepCachedFileCheckBox=qt.QCheckBox("keep cached file")
 
-     self.keepCachedFileCheckBox.toolTip="Toggle local storage of labkey files"
 
-     self.keepCachedFileCheckBox.setChecked(True)
 
-     fileDialogFormLayout.addRow("Manage cache :",self.keepCachedFileCheckBox)
 
-     loadFileButton=qt.QPushButton("Load file")
 
-     loadFileButton.toolTip="Load file"
 
-     loadFileButton.clicked.connect(self.onLoadFileButtonClicked)
 
-     fileDialogFormLayout.addRow("Action :",loadFileButton)
 
-     loadDirButton=qt.QPushButton("Load directory")
 
-     loadDirButton.toolTip="Load directory"
 
-     loadDirButton.clicked.connect(self.onLoadDirButtonClicked)
 
-     fileDialogFormLayout.addRow("Action :",loadDirButton)
 
-   def populateFileList(self,items):
 
-       self.fileList.clear()
 
-       for it_text in items:
 
-             item=qt.QListWidgetItem(self.fileList)
 
-             item.setText(it_text)
 
-             item.setIcon(qt.QIcon(it_text))
 
-   def populateFileTypeSelector(self,items):
 
-       for item in items:
 
-           self.fileTypeSelector.addItem(item)
 
-   def cleanup(self):
 
-     pass
 
-   def onSelect(self):
 
-     self.applyButton.enabled = self.inputSelector.currentNode() and self.outputSelector.currentNode()
 
-   def onApplyButton(self):
 
-     #logic = labkeySlicerPythonExtensionLogic()
 
-     #enableScreenshotsFlag = self.enableScreenshotsFlagCheckBox.checked
 
-     #screenshotScaleFactor = int(self.screenshotScaleFactorSliderWidget.value)
 
-     print("Run the algorithm")
 
-     #logic.run(self.inputSelector.currentNode(), self.outputSelector.currentNode(), enableScreenshotsFlag,screenshotScaleFactor)
 
-   def onUserCertButtonClicked(self):
 
-      filename=qt.QFileDialog.getOpenFileName(None,'Open user certificate',
 
-            self.startDir, '*.crt')
 
-      #pwd=qt.QInputDialog.getText(None,'Certificate password',
 
-      # 'Enter certificate password',qt.QLineEdit.Password)
 
-      if not(filename) :
 
-          print "No file selected"
 
-          return
 
-      f=qt.QFile(filename)
 
-      if not (f.open(qt.QIODevice.ReadOnly)) :
 
-          print "Could not open file"
 
-          return
 
-      certList=qt.QSslCertificate.fromPath(filename)
 
-      if len(certList) < 1:
 
-          print "Troubles parsing {0}".format(filename)
 
-          return
 
-      self.logic.cert=qt.QSslCertificate(f)
 
-      print "cert.isNull()={0}".format(self.logic.cert.isNull())
 
-      self.userCertButton.setText(filename)
 
-      self.authName.setText(self.logic.cert.subjectInfo("emailAddress"))
 
-   def onPrivateKeyButtonClicked(self):
 
-       filename=qt.QFileDialog.getOpenFileName(None,'Open private key',
 
-             self.startDir, '*.key')
 
-       if not (filename) :
 
-           print "No file selected"
 
-           return
 
-       f=qt.QFile(filename)
 
-       if not (f.open(qt.QIODevice.ReadOnly)) :
 
-           print "Could not open file"
 
-           return
 
-       self.pwd=qt.QInputDialog.getText(None,'Private key password',
 
-         'Enter key password',qt.QLineEdit.Password)
 
-       self.logic.key=qt.QSslKey(f,qt.QSsl.Rsa,qt.QSsl.Pem,qt.QSsl.PrivateKey,
 
-          str(self.pwd))
 
-       self.privateKeyButton.setText(filename)
 
-   def onCaCertButtonClicked(self):
 
-       filename=qt.QFileDialog.getOpenFileName(None,'Open authority certificate',
 
-                self.startDir, '*.crt')
 
-       if not(filename) :
 
-          print "No file selected"
 
-          return
 
-       f=qt.QFile(filename)
 
-       if not (f.open(qt.QIODevice.ReadOnly)) :
 
-           print "Could not open file"
 
-           return
 
-       certList=qt.QSslCertificate.fromPath(filename)
 
-       if len(certList) < 1:
 
-           print "Troubles parsing {0}".format(filename)
 
-           return
 
-       self.logic.caCert=qt.QSslCertificate(f)#certList[0]
 
-       self.caCertButton.setText(filename)
 
-   def onLoadConfigButtonClicked(self):
 
-        filename=qt.QFileDialog.getOpenFileName(None,'Open configuration file (JSON)',
 
-             self.configDir, '*.json')
 
-        with open(filename,'r') as f:
 
-            dt=json.load(f)
 
-        if dt.has_key('host'):
 
-            self.serverURL.setText(dt['host'])
 
-        if dt.has_key('dataset'):
 
-            pass
 
-            #self.datasetName.setText(dt['dataset'])
 
-        if dt.has_key('project'):
 
-            pass
 
-            #self.datasetProject.setText(dt['project'])
 
-        if dt.has_key('SSL'):
 
-            if dt['SSL'].has_key('user'):
 
-                self.userCertButton.setText(dt['SSL']['user'])
 
-            if dt['SSL'].has_key('key'):
 
-                self.privateKeyButton.setText(dt['SSL']['key'])
 
-            if dt['SSL'].has_key('keyPwd'):
 
-                self.pwd=dt['SSL']['keyPwd']
 
-            if dt['SSL'].has_key('ca'):
 
-                self.caCertButton.setText(dt['SSL']['ca'])
 
-        if dt.has_key('labkey'):
 
-            if dt['labkey'].has_key('user'):
 
-                self.network.auth_name=dt['labkey']['user']
 
-                self.authName.setText(self.network.auth_name)
 
-            if dt['labkey'].has_key('password'):
 
-                self.network.auth_pass=dt['labkey']['password']
 
-                self.authPass.setText(self.network.auth_pass)
 
-        self.loadConfigButton.setText(os.path.basename(filename))
 
-   def onInitButtonClicked(self):
 
-       self.network.configureSSL(
 
-         self.userCertButton.text,
 
-         self.privateKeyButton.text,
 
-         self.pwd,
 
-         self.caCertButton.text
 
-       )
 
-       self.network.initRemote()
 
-   def updateAuthName(self,txt):
 
-       self.network.auth_name=txt
 
-       print "Setting username to {0}".format(self.network.auth_name);
 
-   def updateAuthPass(self,txt):
 
-       self.network.auth_pass=txt
 
-       print "Setting password."
 
-   def updateServerURL(self,txt):
 
-       self.network.hostname=txt
 
-       print "Setting hostname to {0}".format(self.network.hostname);
 
-   def onFileListDoubleClicked(self,item):
 
-         if item == None:
 
-             print "Selected items: None"
 
-             return
 
-         iText=item.text()
 
-         print "Selected items: {0} ".format(iText)
 
-         #this is hard -> compose path string from currentRemoteDir and selection
 
-         if item.text().find('..')==0:
 
-             #one up
 
-             idx=self.currentRemoteDir.rfind('/')
 
-             if idx<0:
 
-                 self.currentRemoteDir=''
 
-             else:
 
-                 self.currentRemoteDir=self.currentRemoteDir[:idx]
 
-         elif item.text().find('.')==0:
 
-             pass
 
-         else:
 
-             if len(self.currentRemoteDir)>0:
 
-                 self.currentRemoteDir+='/'
 
-             self.currentRemoteDir+=item.text()
 
-         print "Listing {0}".format(self.currentRemoteDir)
 
-         flist=self.network.toRelativePath(
 
-             self.network.listDir(self.currentRemoteDir))
 
-         print "Got"
 
-         print flist
 
-         flist.insert(0,'..')
 
-         flist.insert(0,'.')
 
-         self.populateFileList(flist)
 
-         self.selectedFile.setText(self.currentRemoteDir)
 
-   def onLoadFileButtonClicked(self):
 
-       properties={}
 
-       localPath=self.network.GetFile(self.selectedFile.text)
 
-       slicer.util.loadNodeFromFile(localPath,self.fileTypeSelector.currentText,
 
-         properties,returnNode=false)
 
-       if not self.keepCachedFileCheckBox.isChecked():
 
-               os.remove(localPath)
 
-   def onLoadDirButtonClicked(self):
 
-     localDir=self.network.loadDir(self.selectedFile.text)
 
-     try:
 
-         self.loadDicomLogic.load(localDir)
 
-     except:
 
-         self.loadDicom=loadDicom.loadDicomLogic(self)
 
-         self.loadDicom.load(localDir)
 
- # labkeySlicerPythonExtensionLogic
 
- #
 
- class labkeySlicerPythonExtensionLogic(ScriptedLoadableModuleLogic):
 
-   """This class should implement all the actual
 
-   computation done by your module.  The interface
 
-   should be such that other python code can import
 
-   this class and make use of the functionality without
 
-   requiring an instance of the Widget.
 
-   Uses ScriptedLoadableModuleLogic base class, available at:
 
-   https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py
 
-   """
 
-   def __init__(self,parent):
 
-       ScriptedLoadableModuleLogic.__init__(self, parent)
 
-       self.qnam=qt.QNetworkAccessManager()
 
-   def hasImageData(self,volumeNode):
 
-     """This is a dummy logic method that
 
-     returns true if the passed in volume
 
-     node has valid image data
 
-     """
 
-     if not volumeNode:
 
-       print('no volume node')
 
-       return False
 
-     if volumeNode.GetImageData() == None:
 
-       print('no image data')
 
-       return False
 
-     return True
 
-   def takeScreenshot(self,name,description,type=-1):
 
-     # show the message even if not taking a screen shot
 
-     self.delayDisplay(description)
 
-     if self.enableScreenshots == 0:
 
-       return
 
-     lm = slicer.app.layoutManager()
 
-     # switch on the type to get the requested window
 
-     widget = 0
 
-     if type == slicer.qMRMLScreenShotDialog.FullLayout:
 
-       # full layout
 
-       widget = lm.viewport()
 
-     elif type == slicer.qMRMLScreenShotDialog.ThreeD:
 
-       # just the 3D window
 
-       widget = lm.threeDWidget(0).threeDView()
 
-     elif type == slicer.qMRMLScreenShotDialog.Red:
 
-       # red slice window
 
-       widget = lm.sliceWidget("Red")
 
-     elif type == slicer.qMRMLScreenShotDialog.Yellow:
 
-       # yellow slice window
 
-       widget = lm.sliceWidget("Yellow")
 
-     elif type == slicer.qMRMLScreenShotDialog.Green:
 
-       # green slice window
 
-       widget = lm.sliceWidget("Green")
 
-     else:
 
-       # default to using the full window
 
-       widget = slicer.util.mainWindow()
 
-       # reset the type so that the node is set correctly
 
-       type = slicer.qMRMLScreenShotDialog.FullLayout
 
-     # grab and convert to vtk image data
 
-     qpixMap = qt.QPixmap().grabWidget(widget)
 
-     qimage = qpixMap.toImage()
 
-     imageData = vtk.vtkImageData()
 
-     slicer.qMRMLUtils().qImageToVtkImageData(qimage,imageData)
 
-     annotationLogic = slicer.modules.annotations.logic()
 
-     annotationLogic.CreateSnapShot(name, description, type, self.screenshotScaleFactor, imageData)
 
-   def run(self,inputVolume,outputVolume,enableScreenshots=0,screenshotScaleFactor=1):
 
-     """
 
-     Run the actual algorithm
 
-     """
 
-     self.delayDisplay('Running the aglorithm')
 
-     self.enableScreenshots = enableScreenshots
 
-     self.screenshotScaleFactor = screenshotScaleFactor
 
-     self.takeScreenshot('labkeySlicerPythonExtension-Start','Start',-1)
 
-     return True
 
- class labkeySlicerPythonExtensionTest(ScriptedLoadableModuleTest):
 
-   """
 
-   This is the test case for your scripted module.
 
-   Uses ScriptedLoadableModuleTest base class, available at:
 
-   https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py
 
-   """
 
-   def setUp(self):
 
-     """ Do whatever is needed to reset the state - typically a scene clear will be enough.
 
-     """
 
-     slicer.mrmlScene.Clear(0)
 
-   def runTest(self):
 
-     """Run as few or as many tests as needed here.
 
-     """
 
-     self.setUp()
 
-     self.test_labkeySlicerPythonExtension1()
 
-   def test_labkeySlicerPythonExtension1(self):
 
-     """ Ideally you should have several levels of tests.  At the lowest level
 
-     tests sould exercise the functionality of the logic with different inputs
 
-     (both valid and invalid).  At higher levels your tests should emulate the
 
-     way the user would interact with your code and confirm that it still works
 
-     the way you intended.
 
-     One of the most important features of the tests is that it should alert other
 
-     developers when their changes will have an impact on the behavior of your
 
-     module.  For example, if a developer removes a feature that you depend on,
 
-     your test should break so they know that the feature is needed.
 
-     """
 
-     self.delayDisplay("Starting the test")
 
-     #
 
-     # first, get some data
 
-     #
 
-     import urllib
 
-     downloads = (
 
-         ('http://slicer.kitware.com/midas3/download?items=5767', 'FA.nrrd', slicer.util.loadVolume),
 
-         )
 
-     for url,name,loader in downloads:
 
-       filePath = slicer.app.temporaryPath + '/' + name
 
-       if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
 
-         print('Requesting download %s from %s...\n' % (name, url))
 
-         urllib.urlretrieve(url, filePath)
 
-       if loader:
 
-         print('Loading %s...\n' % (name,))
 
-         loader(filePath)
 
-     self.delayDisplay('Finished with download and loading\n')
 
-     volumeNode = slicer.util.getNode(pattern="FA")
 
-     logic = labkeySlicerPythonExtensionLogic()
 
-     self.assertTrue( logic.hasImageData(volumeNode) )
 
-     self.delayDisplay('Test passed!')
 
 
  |