Parcourir la source

Working version that lists remote directories and reads remote dicom files

Andrej Studen il y a 7 ans
Parent
commit
8ef9febb72

+ 18 - 41
labkeySlicerPythonExtension/labkeySlicerPythonExtension.py

@@ -2,7 +2,7 @@ import os
 import unittest
 from __main__ import vtk, qt, ctk, slicer
 from slicer.ScriptedLoadableModule import *
-
+import slicerNetwork
 
 #
 # labkeySlicerPythonExtension
@@ -39,6 +39,7 @@ class labkeySlicerPythonExtensionWidget(ScriptedLoadableModuleWidget):
     ScriptedLoadableModuleWidget.setup(self)
     # Instantiate and connect widgets ...
     self.logic=labkeySlicerPythonExtensionLogic(self)
+    self.network=slicerNetwork.slicerNetwork(self)
     #
     # Parameters Area
     #
@@ -52,6 +53,7 @@ class labkeySlicerPythonExtensionWidget(ScriptedLoadableModuleWidget):
 
     connectionFormLayout.addRow("Server: ", self.serverURL)
 
+    self.startDir=os.environ['HOME']+"/temp/crt"
     self.userCertButton=qt.QPushButton("Load")
     self.userCertButton.toolTip="Load user certificate (crt)"
     self.userCertButton.connect('clicked(bool)',self.onUserCertButtonClicked)
@@ -164,9 +166,8 @@ class labkeySlicerPythonExtensionWidget(ScriptedLoadableModuleWidget):
     #logic.run(self.inputSelector.currentNode(), self.outputSelector.currentNode(), enableScreenshotsFlag,screenshotScaleFactor)
 
   def onUserCertButtonClicked(self):
-     startDir=os.environ['HOME']+"/temp"
      filename=qt.QFileDialog.getOpenFileName(None,'Open user certificate',
-           startDir, '*.crt')
+           self.startDir, '*.crt')
      #pwd=qt.QInputDialog.getText(None,'Certificate password',
      # 'Enter certificate password',qt.QLineEdit.Password)
      if not(filename) :
@@ -188,9 +189,8 @@ class labkeySlicerPythonExtensionWidget(ScriptedLoadableModuleWidget):
      self.userCertButton.setText(filename)
 
   def onPrivateKeyButtonClicked(self):
-      startDir=os.environ['HOME']+"/temp"
       filename=qt.QFileDialog.getOpenFileName(None,'Open private key',
-            startDir, '*.key')
+            self.startDir, '*.key')
       if not (filename) :
           print "No file selected"
           return
@@ -199,16 +199,16 @@ class labkeySlicerPythonExtensionWidget(ScriptedLoadableModuleWidget):
       if not (f.open(qt.QIODevice.ReadOnly)) :
           print "Could not open file"
           return
-      pwd=qt.QInputDialog.getText(None,'Private key password',
-      'Enter key password',qt.QLineEdit.Password)
+      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(pwd))
+      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):
-      startDir=os.environ['HOME']+"/temp"
       filename=qt.QFileDialog.getOpenFileName(None,'Open authority certificate',
-               startDir, '*.crt')
+               self.startDir, filter='*.crt')
       if not(filename) :
          print "No file selected"
          return
@@ -228,6 +228,13 @@ class labkeySlicerPythonExtensionWidget(ScriptedLoadableModuleWidget):
       self.caCertButton.setText(filename)
 
   def onConnectButtonClicked(self):
+      self.network.configureSSL(
+        self.userCertButton.text,
+        self.privateKeyButton.text,
+        self.pwd,
+        self.caCertButton.text
+      )
+
       uname=str(self.logic.cert.subjectInfo("emailAddress"))
       uname=qt.QInputDialog.getText(None,
         "Labkey credentials","Enter username",qt.QLineEdit.Normal,uname)
@@ -235,7 +242,7 @@ class labkeySlicerPythonExtensionWidget(ScriptedLoadableModuleWidget):
       pwd=qt.QInputDialog.getText(None,
         "Labkey credentials","Enter password",qt.QLineEdit.Password)
 
-      self.logic.connectRemote(str(self.serverURL.text),uname,pwd)
+      self.network.connectRemote(str(self.serverURL.text),uname,pwd)
 
 
 
@@ -257,36 +264,6 @@ class labkeySlicerPythonExtensionLogic(ScriptedLoadableModuleLogic):
       ScriptedLoadableModuleLogic.__init__(self, parent)
       self.qnam=qt.QNetworkAccessManager()
 
-  def connectRemote(self,serverURL,uname,pwd):
-     request=qt.QNetworkRequest()
-     request.setUrl(qt.QUrl(serverURL));
-     request.setHeader(qt.QNetworkRequest.ContentTypeHeader,
-        "application/x-www-form-urlencoded")
-
-     data="email="+uname+"&password="+pwd;
-
-     #setup the transfer
-     sConfig=qt.QSslConfiguration()
-
-     #user certificate
-     sConfig.setLocalCertificate(self.cert)
-     sConfig.setPrivateKey(self.key)
-
-     #ca certificate
-     caList=[self.caCert]
-     sConfig.setCaCertificates(caList)
-
-     request.setSslConfiguration(sConfig)
-
-     #post
-
-     r=self.qnam.post(request,data)
-     connect(qnam, qt.QNetworkAccessManager.finished, self, replyFinished);
-
-  def replyFinished(self,res):
-      print "Reply finished"
-
-
   def hasImageData(self,volumeNode):
     """This is a dummy logic method that
     returns true if the passed in volume

+ 94 - 2
labkeySlicerPythonExtension/slicerNetwork.py

@@ -1,6 +1,98 @@
 import qt
-
+import urllib2
+import ssl
+import cookielib
+import xml.etree.ElementTree as ET
+import re
+import StringIO
 
 class slicerNetwork:
     def __init__(self,parent):
-        pass
+        parent.title = "slicerNetwork"
+        self.parent=parent
+
+    def configureSSL(self,cert,key,pwd,cacert):
+        #do this first
+        self.ctx=ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+        self.ctx.load_cert_chain(cert,key,pwd)
+        self.ctx.verify_mode=ssl.CERT_REQUIRED
+        self.ctx.load_verify_locations(cacert)
+
+    def connectRemote(self,serverUrl,uname,pwd):
+        https_handler=urllib2.HTTPSHandler(context=self.ctx)
+
+        #cookie part
+        cj=cookielib.CookieJar()
+        cookie_handler=urllib2.HTTPCookieProcessor(cj)
+
+        self.opener=urllib2.build_opener(https_handler,cookie_handler)
+        loginUrl=serverUrl+"/labkey/login/login.post"
+        r=urllib2.Request(str(loginUrl))
+        print "Connecting to {0}".format(loginUrl)
+        r.add_header('ContentType','application/x-www-form-urlencoded')
+        data="email="+uname+"&password="+pwd
+        r.add_data(data)
+
+        self.opener.open(r)
+
+        #cj in opener contains the cookies
+
+    def get(self,url):
+
+        #r1=urllib2.Request('https://merlin.fmf.uni-lj.si/labkey/query/motionData/selectRows.api?schemaName=core&query.queryName=Users')
+        r=urllib2.Request(url)
+        return self.opener.open(r)
+        #f contains json as a return value
+
+    def post(self,url,data):
+
+        r=urllib2.Request(url)
+        #makes it a post
+        r.add_data(data)
+        r.add_header("content-type","application/json")
+
+        f=self.opener.open(r)
+        #f contains json as a return value
+
+    def listDir(self,serverUrl,dir):
+        dirUrl=serverUrl+"/labkey/_webdav"+"/"+dir
+        r=propfindRequest(dirUrl)
+        PROPFIND=u"""<?xml version="1.0" encoding="utf-8"?>\n
+                    <propfind xmlns="DAV:">\n
+                    <prop>\n
+                    <getetag/>\n
+                    </prop>\n
+                    </propfind>"""
+        r.add_header('content-type','text/xml; charset="utf-8"')
+        r.add_header('content-length',str(len(PROPFIND)))
+        r.add_header('Depth','1')
+        r.add_data(PROPFIND)
+        f=self.opener.open(r)
+        tree=ET.XML(f.read())
+        rps=tree.findall('{DAV:}response')
+        dirs=[]
+        for r in rps:
+            hr=r.find('{DAV:}href')
+            dirent=hr.text
+            dirent=re.sub('/labkey/_webdav/','',dirent)
+            dirs.append(dirent)
+        del dirs[0]
+        return dirs
+
+    def readFile(self, serverUrl, path):
+        dirUrl=serverUrl+"/labkey/_webdav"+"/"+path
+        f=self.get(dirUrl)
+        return StringIO.StringIO(f.read())
+        
+class propfindRequest(urllib2.Request):
+    """
+    This request subclass allows explicit specification of
+    the HTTP request method. Basic urllib2.Request class
+    chooses GET or POST depending on self.has_data()
+    """
+    def __init__(self, *args, **kwargs):
+        #self.method = 'Propfind'
+        urllib2.Request.__init__(self, *args, **kwargs)
+
+    def get_method(self):
+        return 'PROPFIND'