|
@@ -1,32 +1,16 @@
|
|
|
import qt
|
|
|
-import urllib2
|
|
|
-import ssl
|
|
|
-import cookielib
|
|
|
+import urllib3
|
|
|
import xml.etree.ElementTree as ET
|
|
|
import re
|
|
|
-import StringIO
|
|
|
import slicer
|
|
|
import shutil
|
|
|
import distutils
|
|
|
import os
|
|
|
-import base64
|
|
|
import json
|
|
|
+import chardet
|
|
|
+import io
|
|
|
|
|
|
-#see https://gist.github.com/logic/2715756, allow requests to do Put
|
|
|
-class MethodRequest(urllib2.Request):
|
|
|
- def __init__(self, *args, **kwargs):
|
|
|
- if 'method' in kwargs:
|
|
|
- self._method = kwargs['method']
|
|
|
- del kwargs['method']
|
|
|
- else:
|
|
|
- self._method = None
|
|
|
- return urllib2.Request.__init__(self, *args, **kwargs)
|
|
|
-
|
|
|
- def get_method(self, *args, **kwargs):
|
|
|
- if self._method is not None:
|
|
|
- return self._method
|
|
|
- return urllib2.Request.get_method(self, *args, **kwargs)
|
|
|
-
|
|
|
+#mimics labkeyInterface
|
|
|
class slicerNetwork(slicer.ScriptedLoadableModule.ScriptedLoadableModule):
|
|
|
def __init__(self, parent):
|
|
|
slicer.ScriptedLoadableModule.ScriptedLoadableModule.__init__(self,parent)
|
|
@@ -38,21 +22,16 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
slicer.vtkURIHandler.__init__(self)
|
|
|
self.className="labkeyURIHandler"
|
|
|
slicer.mrmlScene.AddURIHandler(self)
|
|
|
- try:
|
|
|
- fhome=os.environ["HOME"]
|
|
|
- except:
|
|
|
- #in windows, the variable is called HOMEPATH
|
|
|
- fhome=os.environ['HOMEDRIVE']+os.environ['HOMEPATH']
|
|
|
|
|
|
+ fhome=os.path.expanduser('~')
|
|
|
self.localCacheDirectory=os.path.join(fhome,"labkeyCache")
|
|
|
self.configDir=os.path.join(fhome,".labkey")
|
|
|
- self.mode="http"
|
|
|
#try initializing network from default config file, if found
|
|
|
self.initFromConfig()
|
|
|
|
|
|
|
|
|
def CanHandleURI(self,uri):
|
|
|
- print("labkeyURIHandler::CanHandleURI({0})").format(uri)
|
|
|
+ print("labkeyURIHandler::CanHandleURI({0})".format(uri))
|
|
|
if uri.find('labkey://')==0:
|
|
|
return 1
|
|
|
return 0
|
|
@@ -62,9 +41,17 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
|
|
|
|
|
|
def GetHostName(self):
|
|
|
+ self.hostname=self.connectionConfig['host']
|
|
|
+ print("Host name:{}".format(self.hostname))
|
|
|
return self.hostname
|
|
|
|
|
|
def SetHostName(self,host):
|
|
|
+ try:
|
|
|
+ self.connectionConfig['host']=host
|
|
|
+ except AttributeError:
|
|
|
+ self.connectionConfig={}
|
|
|
+ self.connectionConfig['host']=host
|
|
|
+
|
|
|
self.hostname=host
|
|
|
|
|
|
def SetLocalCahceDirectory(self,dir):
|
|
@@ -74,36 +61,59 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
return self.localCacheDirectory
|
|
|
|
|
|
def GetLabkeyUrl(self):
|
|
|
- return self.hostname+"/labkey"
|
|
|
+ return self.GetHostName()+"/labkey"
|
|
|
|
|
|
def GetLabkeyWebdavUrl(self):
|
|
|
return self.GetLabkeyUrl()+"/_webdav"
|
|
|
|
|
|
#configuration part
|
|
|
|
|
|
- def configureSSL(self,cert,key,pwd,cacert):
|
|
|
- #do this first
|
|
|
- try:
|
|
|
- self.ctx=ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
|
|
- self.ctx.load_cert_chain(cert,keyfile=key,password=pwd)
|
|
|
- self.ctx.verify_mode=ssl.CERT_REQUIRED
|
|
|
- self.ctx.load_verify_locations(cacert)
|
|
|
- except ssl.SSLError as err:
|
|
|
- print(" Failed to configure SSL: {0}").format(str(err))
|
|
|
- self.mode="https"
|
|
|
+ def configureSSL(self,cert=None,key=None,pwd=None,cacert=None):
|
|
|
+ print("configure SSL: {}".format(cert))
|
|
|
|
|
|
+ if not cert==None:
|
|
|
+ self.http = urllib3.PoolManager(\
|
|
|
+ cert_file=cert,\
|
|
|
+ cert_reqs='CERT_REQUIRED',\
|
|
|
+ key_file=key,\
|
|
|
+ ca_certs=cacert)
|
|
|
+ else:
|
|
|
+ self.http = urllib3.PoolManager(\
|
|
|
+ cert_reqs='CERT_REQUIRED',\
|
|
|
+ ca_certs=cacert)
|
|
|
|
|
|
def initRemote(self):
|
|
|
- if self.mode=="https":
|
|
|
- http_handler=urllib2.HTTPSHandler(context=self.ctx)
|
|
|
- if self.mode=="http":
|
|
|
- http_handler=urllib2.HTTPHandler()
|
|
|
- #cookie part
|
|
|
- cj=cookielib.CookieJar()
|
|
|
- cookie_handler=urllib2.HTTPCookieProcessor(cj)
|
|
|
- self.opener=urllib2.build_opener(http_handler,cookie_handler)
|
|
|
+ #assume self.connectionConfig is set
|
|
|
+ self.http=urllib3.PoolManager()
|
|
|
+ try:
|
|
|
+ config=self.connectionConfig
|
|
|
+ except AttributeError:
|
|
|
+ print("ConnectionConfig not initialized")
|
|
|
+ return
|
|
|
+
|
|
|
+ if 'SSL' in self.connectionConfig:
|
|
|
+ print("Setting up SSL")
|
|
|
+ try:
|
|
|
+ cert=self.connectionConfig['SSL']['user']
|
|
|
+ except KeyError:
|
|
|
+ print("No user cert supplied")
|
|
|
+ return
|
|
|
+ try:
|
|
|
+ key=self.connectionConfig['SSL']['key']
|
|
|
+ except KeyError:
|
|
|
+ print("No user key supplied")
|
|
|
+ return
|
|
|
+ try:
|
|
|
+ ca=self.connectionConfig['SSL']['ca']
|
|
|
+ except KeyError:
|
|
|
+ print("No CA cert supplied")
|
|
|
+ return
|
|
|
+
|
|
|
+ self.configureSSL(cert,key,None,ca)
|
|
|
+
|
|
|
|
|
|
def initFromConfig(self):
|
|
|
+ print("slicerNetwork: initFromConfig")
|
|
|
path=os.path.join(self.configDir,"Remote.json")
|
|
|
try:
|
|
|
self.parseConfig(path)
|
|
@@ -112,35 +122,30 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
self.initRemote()
|
|
|
|
|
|
def parseConfig(self,fname,parent=None):
|
|
|
+ print("slicerNetwork: parseConfig")
|
|
|
try:
|
|
|
- f=open(fname)
|
|
|
+ with open(fname) as f:
|
|
|
+ self.connectionConfig=json.load(f)
|
|
|
except OSError as e:
|
|
|
- print("Confgiuration error: OS error({0}): {1}").format(e.errno, e.strerror)
|
|
|
+ print("Confgiuration error: OS error({0}): {1}".format(e.errno, e.strerror))
|
|
|
raise
|
|
|
+ except AttributeError:
|
|
|
+ print("Troubles parsing json at {}".format(fname))
|
|
|
+
|
|
|
+ if not parent==None:
|
|
|
+ parent.userCertButton.setText(self.connectionConfig['SSL']['user'])
|
|
|
+ parent.caCertButton.setText(self.connectionConfig['SSL']['ca'])
|
|
|
+ parent.privateKeyButton.setText(self.connectionConfig['SSL']['key'])
|
|
|
+ parent.pwd=self.connectionConfig['SSL']['keyPwd']
|
|
|
|
|
|
- dt=json.load(f)
|
|
|
- self.mode="http"
|
|
|
- if dt.has_key('SSL'):
|
|
|
- self.configureSSL(
|
|
|
- dt['SSL']['user'],
|
|
|
- dt['SSL']['key'],
|
|
|
- dt['SSL']['keyPwd'],
|
|
|
- dt['SSL']['ca']
|
|
|
- )
|
|
|
- if not parent==None:
|
|
|
- parent.userCertButton.setText(dt['SSL']['user'])
|
|
|
- parent.caCertButton.setText(dt['SSL']['ca'])
|
|
|
- parent.privateKeyButton.setText(dt['SSL']['key'])
|
|
|
- parent.pwd=dt['SSL']['keyPwd']
|
|
|
-
|
|
|
-
|
|
|
- self.hostname=dt['host']
|
|
|
- self.auth_name=dt['labkey']['user']
|
|
|
- self.auth_pass=dt['labkey']['password']
|
|
|
+
|
|
|
+ self.hostname=self.connectionConfig['host']
|
|
|
+ self.auth_name=self.connectionConfig['labkey']['user']
|
|
|
+ self.auth_pass=self.connectionConfig['labkey']['password']
|
|
|
if not parent==None:
|
|
|
- parent.serverURL.setText(dt['host'])
|
|
|
- parent.authName.setText(dt['labkey']['user'])
|
|
|
- parent.authPass.setText(dt['labkey']['password'])
|
|
|
+ parent.serverURL.setText(self.connectionConfig['host'])
|
|
|
+ parent.authName.setText(self.connectionConfig['labkey']['user'])
|
|
|
+ parent.authPass.setText(self.connectionConfig['labkey']['password'])
|
|
|
|
|
|
|
|
|
#path convention
|
|
@@ -161,9 +166,9 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
def GetLocalPathFromRelativePath(self,relativePath):
|
|
|
debug=False
|
|
|
relativePath=re.sub('labkey://','',relativePath)
|
|
|
- sp=os.sep.encode('string-escape')
|
|
|
+ sp=os.sep.encode('unicode_escape').decode('utf-8')
|
|
|
if debug:
|
|
|
- print("Substituting / with {0} in {1}").format(sp,relativePath)
|
|
|
+ print("Substituting / with {0} in {1}".format(sp,relativePath))
|
|
|
relativePath=re.sub('/',sp,relativePath)
|
|
|
return os.path.join(self.GetLocalCacheDirectory(),relativePath)
|
|
|
|
|
@@ -181,7 +186,7 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
f0=re.sub('\\\\','\\\\\\\\',self.localCacheDirectory)
|
|
|
relativePath=re.sub(re.compile(f0),'',f)
|
|
|
if debug:
|
|
|
- print("[SEP] Relative path {}").format(relativePath)
|
|
|
+ print("[SEP] Relative path {}".format(relativePath))
|
|
|
#leaves /ContextPath/%40files/subdirectory_list/files
|
|
|
#remove first separator
|
|
|
sp=os.path.sep
|
|
@@ -190,7 +195,7 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
relativePath=relativePath[1:len(relativePath)]
|
|
|
|
|
|
if debug:
|
|
|
- print("[SLASH] Relative path {}").format(relativePath)
|
|
|
+ print("[SLASH] Relative path {}".format(relativePath))
|
|
|
|
|
|
return re.sub(f1,'/',relativePath)
|
|
|
|
|
@@ -205,99 +210,150 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
if f[0]=='/':
|
|
|
f=f[1:len(f)]
|
|
|
return f;
|
|
|
+
|
|
|
+ def getBasicAuth(self):
|
|
|
|
|
|
+ user=self.connectionConfig['labkey']['user']
|
|
|
+ pwd=self.connectionConfig['labkey']['password']
|
|
|
+ #debug
|
|
|
+ return user+":"+pwd
|
|
|
+
|
|
|
|
|
|
#standard HTTP
|
|
|
- def get(self,url):
|
|
|
+ def get(self,url,binary=False):
|
|
|
|
|
|
- debug=False
|
|
|
+ debug=True
|
|
|
if debug:
|
|
|
- print("GET: {0}").format(url)
|
|
|
- print("as {0}").format(self.auth_name)
|
|
|
- r=urllib2.Request(url)
|
|
|
- base64string = base64.b64encode('%s:%s' % (self.auth_name, self.auth_pass))
|
|
|
- r.add_header("Authorization", "Basic %s" % base64string)
|
|
|
+ print("GET: {0}".format(url))
|
|
|
+ print("as {0}".format(self.auth_name))
|
|
|
+ headers=urllib3.util.make_headers(basic_auth=self.getBasicAuth())
|
|
|
try:
|
|
|
- return self.opener.open(r)
|
|
|
+ if not binary:
|
|
|
+ return self.http.request('GET',url,headers=headers)
|
|
|
+ else:
|
|
|
+ return self.http.request('GET',url,headers=headers,preload_content=False)
|
|
|
+ #f contains json as a return value
|
|
|
#f contains json as a return value
|
|
|
- except urllib2.HTTPError as e:
|
|
|
- print e.code
|
|
|
- print e.read()
|
|
|
+ except urllib3.exceptions.HTTPError as e:
|
|
|
+ print(e)
|
|
|
return e
|
|
|
- except urllib2.URLError as e:
|
|
|
- print("Handling URLError")
|
|
|
- print e
|
|
|
- return None
|
|
|
-
|
|
|
+
|
|
|
#a HEAD request
|
|
|
def head(self,url):
|
|
|
|
|
|
debug=False
|
|
|
if debug:
|
|
|
- print("HEAD: {0}").format(url)
|
|
|
- print("as {0}").format(self.auth_name)
|
|
|
- r=MethodRequest(url.encode('utf-8'),method="HEAD")
|
|
|
- base64string = base64.b64encode('%s:%s' % (self.auth_name, self.auth_pass))
|
|
|
- r.add_header("Authorization", "Basic %s" % base64string)
|
|
|
+ print("HEAD: {0}".format(url))
|
|
|
+ print("as {0}".format(self.auth_name))
|
|
|
+ headers=urllib3.util.make_headers(basic_auth=self.getBasicAuth())
|
|
|
+
|
|
|
try:
|
|
|
- return self.opener.open(r)
|
|
|
- #f contains json as a return value
|
|
|
- except urllib2.HTTPError as e:
|
|
|
- print e.code
|
|
|
- print e.read()
|
|
|
+ return self.http.request('HEAD',url,headers=headers)
|
|
|
+ except urllib3.exceptions.HTTPError as e:
|
|
|
+ print(e)
|
|
|
return e
|
|
|
|
|
|
|
|
|
+
|
|
|
def post(self,url,data):
|
|
|
|
|
|
debug=False
|
|
|
- r=urllib2.Request(url)
|
|
|
- #makes it a post
|
|
|
- r.add_data(data)
|
|
|
- r.add_header("Content-Type","application/json")
|
|
|
- #add csrf
|
|
|
- csrf=self.getCSRF()
|
|
|
- r.add_header("X-LABKEY-CSRF",csrf)
|
|
|
+ headers=urllib3.util.make_headers(basic_auth=self.getBasicAuth())
|
|
|
+ headers["Content-Type"]="application/json"
|
|
|
+ #add csrf;also sets self.cookie
|
|
|
+ headers["X-LABKEY-CSRF"]=self.getCSRF()
|
|
|
+ headers["Cookie"]=self.cookie
|
|
|
|
|
|
- base64string = base64.b64encode('%s:%s' % (self.auth_name, self.auth_pass))
|
|
|
- r.add_header("Authorization", "Basic %s" % base64string)
|
|
|
- if debug:
|
|
|
- print("{}: {}").format(r.get_method(),r.get_full_url())
|
|
|
- print("data: {}").format(r.get_data())
|
|
|
- print("Content-Type: {}").format(r.get_header('Content-Type'))
|
|
|
try:
|
|
|
- return self.opener.open(r)
|
|
|
- except urllib2.HTTPError as e:
|
|
|
- print e.code
|
|
|
- print e.read()
|
|
|
- return e
|
|
|
+ return self.http.request('POST',url,headers=headers,body=data)
|
|
|
#f contains json as a return value
|
|
|
+ except urllib3.exceptions.HTTPError as e:
|
|
|
+ print(e)
|
|
|
+ return e
|
|
|
+
|
|
|
|
|
|
def put(self,url,data):
|
|
|
+
|
|
|
+ debug=False
|
|
|
+
|
|
|
+ if debug:
|
|
|
+ print("PUT: {}".format(url))
|
|
|
+
|
|
|
+ headers=urllib3.util.make_headers(basic_auth=self.getBasicAuth())
|
|
|
+ headers["Content-Type"]="application/octet-stream"
|
|
|
+ #add csrf
|
|
|
+ headers["X-LABKEY-CSRF"]=self.getCSRF()
|
|
|
+ headers["Cookie"]=self.cookie
|
|
|
+
|
|
|
+ try:
|
|
|
+ return self.http.request('PUT',url,headers=headers,body=data)
|
|
|
+ #f contains json as a return value
|
|
|
+ except urllib3.exceptions.HTTPError as e:
|
|
|
+ print(e)
|
|
|
+ return e
|
|
|
+
|
|
|
+ def sendRequest(self,url,requestCode):
|
|
|
|
|
|
debug=False
|
|
|
+ headers=urllib3.util.make_headers(basic_auth=self.getBasicAuth())
|
|
|
+ #add csrf;also sets self.cookie
|
|
|
+ headers["X-LABKEY-CSRF"]=self.getCSRF()
|
|
|
+ headers["Cookie"]=self.cookie
|
|
|
|
|
|
- if debug:
|
|
|
- print("PUT: {}").format(url)
|
|
|
- r=MethodRequest(url.encode('utf-8'),method="PUT")
|
|
|
- #makes it a post
|
|
|
- r.add_data(data)
|
|
|
- print("PUT: data size: {}").format(len(data))
|
|
|
- r.add_header("content-type","application/octet-stream")
|
|
|
- base64string = base64.b64encode('%s:%s' % (self.auth_name, self.auth_pass))
|
|
|
- r.add_header("Authorization", "Basic %s" % base64string)
|
|
|
-
|
|
|
- return self.opener.open(r)
|
|
|
+ try:
|
|
|
+ return self.http.request(requestCode,url,headers=headers)
|
|
|
#f contains json as a return value
|
|
|
+ except urllib3.exceptions.HTTPError as e:
|
|
|
+ print(e)
|
|
|
+ return e
|
|
|
+
|
|
|
+ def mkcol(self,url):
|
|
|
+ return self.sendRequest(url,'MKCOL')
|
|
|
+
|
|
|
+ def delete(self,url):
|
|
|
+ return self.sendRequest(url,'DELETE')
|
|
|
+
|
|
|
+ def propfind(self,url,PROPFIND):
|
|
|
+ headers=urllib3.util.make_headers(basic_auth=self.getBasicAuth())
|
|
|
+ headers["Content-Type"]='text/xml; charset="utf-8"'
|
|
|
+ headers['content-length']=str(len(PROPFIND))
|
|
|
+ headers['Depth']='1'
|
|
|
+ #add csrf
|
|
|
+ headers["X-LABKEY-CSRF"]=self.getCSRF()
|
|
|
+ headers["Cookie"]=self.cookie
|
|
|
|
|
|
+ try:
|
|
|
+ return self.http.request('PROPFIND',url,headers=headers,body=PROPFIND)
|
|
|
+ #f contains json as a return value
|
|
|
+ except urllib3.exceptions.HTTPError as e:
|
|
|
+ print(e)
|
|
|
+ return e
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def HTTPStatus(response,method=None):
|
|
|
+ if response.status==200:
|
|
|
+ return True
|
|
|
+ if method=='propfind':
|
|
|
+ if response.status==207:
|
|
|
+ return True
|
|
|
+
|
|
|
+ print("Status: {}".format(response.status))
|
|
|
+ print("Data: {}".format(response.data))
|
|
|
+ return False
|
|
|
+
|
|
|
+ #a good testing routine; CSRF is required for content modifying requests
|
|
|
def getCSRF(self):
|
|
|
url=self.GetLabkeyUrl()+'/login/whoAmI.view'
|
|
|
try:
|
|
|
- jsonData=json.load(self.get(url))
|
|
|
+ response=self.get(url)
|
|
|
+ encoding=chardet.detect(response.data)['encoding']
|
|
|
+ jsonData=json.loads(response.data.decode(encoding))
|
|
|
except AttributeError:
|
|
|
print("Failed")
|
|
|
return None
|
|
|
-
|
|
|
+ #local cookie jar
|
|
|
+ self.cookie=response.getheader('Set-Cookie')
|
|
|
+ print("CSRF: {}".format(jsonData["CSRF"]))
|
|
|
return jsonData["CSRF"]
|
|
|
|
|
|
|
|
@@ -305,7 +361,7 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
|
|
|
#was GetFile
|
|
|
def DownloadFileToCache(self,relativePath):
|
|
|
- debug=False
|
|
|
+ debug=True
|
|
|
# check for file in cache. If available, use, if not, download
|
|
|
localPath=self.GetLocalPathFromRelativePath(relativePath)
|
|
|
if os.path.isfile(localPath):
|
|
@@ -314,7 +370,7 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
return localPath
|
|
|
|
|
|
if debug:
|
|
|
- print("labkeyURIHandler::DownloadFileToCache({0}->{1})").format(relativePath,localPath)
|
|
|
+ print("labkeyURIHandler::DownloadFileToCache({0}->{1})".format(relativePath,localPath))
|
|
|
|
|
|
#make all necessary directories LOCALLY
|
|
|
path=os.path.dirname(localPath)
|
|
@@ -323,7 +379,6 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
if not os.path.isdir(path):
|
|
|
os.makedirs(path)
|
|
|
|
|
|
- localBuffer=open(localPath,'wb')
|
|
|
#make sure we are at the begining of the file
|
|
|
|
|
|
|
|
@@ -332,17 +387,15 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
|
|
|
#check file size
|
|
|
if debug:
|
|
|
- remoteBuffer.seek(0,2)
|
|
|
- sz=remoteBuffer.tell()
|
|
|
- print("Remote size: {0}").format(sz)
|
|
|
+ print("Remote size: {}".format(remoteBuffer.seek(0,2)))
|
|
|
+ remoteBuffer.seek(0)
|
|
|
|
|
|
+ with open(localPath,'wb') as localBuffer:
|
|
|
+ shutil.copyfileobj(remoteBuffer,localBuffer)
|
|
|
|
|
|
- remoteBuffer.seek(0)
|
|
|
|
|
|
- shutil.copyfileobj(remoteBuffer,localBuffer)
|
|
|
- if debug:
|
|
|
- print("Local size: {0}").format(localBuffer.tell())
|
|
|
- localBuffer.close()
|
|
|
+ print("Local size: {}".format(os.path.getsize(localPath)))
|
|
|
+
|
|
|
return localPath
|
|
|
|
|
|
def fileTypesAvailable(self):
|
|
@@ -379,7 +432,7 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
if not dir==None:
|
|
|
relativePath+='/'+dir
|
|
|
labkeyPath=self.GetLabkeyPathFromRelativePath(relativePath)
|
|
|
- print ("Remote: {}").format(labkeyPath)
|
|
|
+ print ("Remote: {}".format(labkeyPath))
|
|
|
|
|
|
#checks if exists
|
|
|
self.mkdir(labkeyPath)
|
|
@@ -397,41 +450,40 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
fileName=nodeName+suffix
|
|
|
file=os.path.join(localPath,fileName)
|
|
|
slicer.util.saveNode(node,file)
|
|
|
- print("Stored to: {}").format(file)
|
|
|
+ print("Stored to: {}".format(file))
|
|
|
f=open(file,"rb")
|
|
|
|
|
|
f.seek(0,2)
|
|
|
sz=f.tell()
|
|
|
- print("File size in memory: {0}").format(sz)
|
|
|
+ print("File size in memory: {0}".format(sz))
|
|
|
f.seek(0)
|
|
|
|
|
|
localBuffer=f.read()
|
|
|
- print("Local buffer size: {}").format(len(localBuffer))
|
|
|
+ print("Local buffer size: {}".format(len(localBuffer)))
|
|
|
remoteFile=labkeyPath+'/'+fileName
|
|
|
resp=self.put(remoteFile,localBuffer)
|
|
|
print(resp.read())
|
|
|
f.close()
|
|
|
if removeFile:
|
|
|
os.remove(file)
|
|
|
+
|
|
|
+ def entryExists(self,url):
|
|
|
|
|
|
-
|
|
|
+ #use head
|
|
|
+ response=self.head(url)
|
|
|
+ return labkeyURIHandler.HTTPStatus(response)
|
|
|
|
|
|
def remoteDirExists(self,url):
|
|
|
- status,dirs=self.listRemoteDir(url);
|
|
|
- return status
|
|
|
+ #weaker, just checks if there is an entry at url, does not check wheter it is a dir
|
|
|
+ return self.entryEists(url)
|
|
|
+ #stronger, but more complicated
|
|
|
+ return self.isRemoteDir(url)
|
|
|
|
|
|
def mkdir(self,remoteDir):
|
|
|
if self.remoteDirExists(remoteDir):
|
|
|
return False
|
|
|
- r=MethodRequest(remoteDir,method="MKCOL")
|
|
|
- base64string = base64.b64encode('%s:%s' % (self.auth_name, self.auth_pass))
|
|
|
- r.add_header("Authorization", "Basic %s" % base64string)
|
|
|
- try:
|
|
|
- f=self.opener.open(r)
|
|
|
- except:
|
|
|
- print("Error: Failed MKCOL {}").format(remoteDir)
|
|
|
- return False
|
|
|
- return True
|
|
|
+ response=self.mkcol(remoteDir)
|
|
|
+ return labkeyURIHandler.HTTPStatus(response)
|
|
|
|
|
|
def mkdirs(self,remoteDir):
|
|
|
relativePath=self.GetRelativePathFromLabkeyPath(remoteDir)
|
|
@@ -452,20 +504,13 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
def rmdir(self,remoteDir):
|
|
|
if not self.remoteDirExists(remoteDir):
|
|
|
return True
|
|
|
- r=MethodRequest(remoteDir,method="DELETE")
|
|
|
- base64string = base64.b64encode('%s:%s' % (self.auth_name, self.auth_pass))
|
|
|
- r.add_header("Authorization", "Basic %s" % base64string)
|
|
|
- try:
|
|
|
- f=self.opener.open(r)
|
|
|
- except:
|
|
|
- print("Error: Failed DELETE {}").format(remoteDir)
|
|
|
- return False
|
|
|
- return True
|
|
|
+ return labkeyURIHandler.HTTPStatus(self.delete(remoteDir))
|
|
|
|
|
|
#was listDir
|
|
|
def listRelativeDir(self,relativeDir):
|
|
|
- print("Listing for {0}").format(relativeDir)
|
|
|
+ print("Listing for {0}".format(relativeDir))
|
|
|
dirUrl=self.GetLabkeyPathFromRelativePath(relativeDir)
|
|
|
+ print("Setting url: {}".format(dirUrl))
|
|
|
status,dirs=self.listRemoteDir(dirUrl)
|
|
|
dirs=[self.GetRelativePathFromLabkeyPath(d) for d in dirs];
|
|
|
return dirs
|
|
@@ -473,25 +518,24 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
#was isDir
|
|
|
def isRemoteDir(self, remotePath):
|
|
|
#print "isDir: {}".format(remotePath)
|
|
|
- r=MethodRequest(remotePath,method="PROPFIND")
|
|
|
PROPFIND=u"""<?xml version="1.0" encoding="utf-8"?>\n
|
|
|
<a:propfind xmlns:a="DAV:">\n
|
|
|
<a:prop>\n
|
|
|
<a:resourcetype/>\n
|
|
|
</a:prop>\n
|
|
|
</a:propfind>"""
|
|
|
- r.add_header('content-type','text/xml; charset="utf-8"')
|
|
|
- r.add_header('content-length',str(len(PROPFIND)))
|
|
|
- r.add_header('Depth','0')
|
|
|
- r.add_data(PROPFIND)
|
|
|
- base64string = base64.b64encode('%s:%s' % (self.auth_name, self.auth_pass))
|
|
|
- r.add_header("Authorization", "Basic %s" % base64string)
|
|
|
- print("PROPFIND: {0}").format(remotePath)
|
|
|
+ if not labkeyURIHandler.HTTPStatus(self.propfind(remotePath,PROPFIND),method='propfind'):
|
|
|
+ print("Bad status")
|
|
|
+ return False
|
|
|
+
|
|
|
try:
|
|
|
- f=self.opener.open(r)
|
|
|
- except:
|
|
|
+ tree=ET.XML(f.data)
|
|
|
+ except ET.ParseError:
|
|
|
+ #print(f.data.decode('utf-8'))
|
|
|
+ #if directory is not there, a 404 response will be made by HTTP, which is not an xml file
|
|
|
+ #we are safe to assume the directory is not there
|
|
|
return False
|
|
|
- tree=ET.XML(f.read())
|
|
|
+
|
|
|
try:
|
|
|
rps=tree.find('{DAV:}response').find('{DAV:}propstat')
|
|
|
rps=rps.find('{DAV:}prop')
|
|
@@ -506,27 +550,25 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
def listRemoteDir(self,dirUrl):
|
|
|
#input is remoteDir, result are remoteDirs
|
|
|
|
|
|
- r=MethodRequest(dirUrl,method="PROPFIND")
|
|
|
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)
|
|
|
- base64string = base64.b64encode('%s:%s' % (self.auth_name, self.auth_pass))
|
|
|
- r.add_header("Authorization", "Basic %s" % base64string)
|
|
|
- print("PROPFIND: {0}").format(dirUrl)
|
|
|
- dirs=[]
|
|
|
+ response=self.propfind(dirUrl,PROPFIND)
|
|
|
+ if not labkeyURIHandler.HTTPStatus(response,method='propfind'):
|
|
|
+ print("Bad status")
|
|
|
+ return False,[]
|
|
|
+
|
|
|
try:
|
|
|
- f=self.opener.open(r)
|
|
|
- except:
|
|
|
- return False,dirs
|
|
|
- tree=ET.XML(f.read())
|
|
|
+ tree=ET.XML(response.data)
|
|
|
+ except ET.ParseError:
|
|
|
+ print("Fail to parse XML")
|
|
|
+ return False,[]
|
|
|
+
|
|
|
rps=tree.findall('{DAV:}response')
|
|
|
+ dirs=[]
|
|
|
for r in rps:
|
|
|
hr=r.find('{DAV:}href')
|
|
|
dirent=hr.text
|
|
@@ -548,8 +590,13 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
|
|
|
def readFileToBuffer(self, relativePath):
|
|
|
dirUrl=self.GetLabkeyPathFromRelativePath(relativePath)
|
|
|
- f=self.get(dirUrl)
|
|
|
- return StringIO.StringIO(f.read())
|
|
|
+ response=self.get(dirUrl,binary=True)
|
|
|
+ if not labkeyURIHandler.HTTPStatus(response):
|
|
|
+ return io.BytesIO()
|
|
|
+ #this will collect for all data
|
|
|
+ remoteBuffer=io.BytesIO(response.data)
|
|
|
+ response.release_conn()
|
|
|
+ return remoteBuffer
|
|
|
|
|
|
def uploadFile(self,localPath):
|
|
|
#get upstream directories sorted out
|
|
@@ -607,11 +654,16 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
return localDir
|
|
|
|
|
|
#database routines
|
|
|
+ @staticmethod
|
|
|
+ def getJSON(response):
|
|
|
+ encoding=chardet.detect(response.data)['encoding']
|
|
|
+ return json.loads(response.data.decode(encoding))
|
|
|
+
|
|
|
|
|
|
def loadDataset(self,project,dataset):
|
|
|
url=self.GetLabkeyUrl()+'/'+project
|
|
|
url+='/query-selectRows.api?schemaName=study&query.queryName='+dataset
|
|
|
- return json.load(self.get(url))
|
|
|
+ return labkeyURIHandler.getJSON(self.get(url))
|
|
|
|
|
|
def filterDataset(self,project,dataset,filter):
|
|
|
debug=False
|
|
@@ -620,8 +672,8 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
for f in filter:
|
|
|
url+="&query."+f['variable']+"~"+f['oper']+"="+f['value']
|
|
|
if debug:
|
|
|
- print("Sending {}").format(url)
|
|
|
- return json.load(self.get(url))
|
|
|
+ print("Sending {}".format(url))
|
|
|
+ return labkeyURIHandler.getJSON(self.get(url))
|
|
|
|
|
|
|
|
|
def modifyDataset(self,method,project,dataset,rows):
|
|
@@ -632,7 +684,7 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
data['rows']=rows
|
|
|
url=self.GetLabkeyUrl()+'/'+project
|
|
|
url+='/query-'+method+'Rows.api?'
|
|
|
- return self.post(url,json.dumps(data))
|
|
|
+ return self.post(url,json.dumps(data)).data
|
|
|
|
|
|
def filterList(self,project,dataset,filter):
|
|
|
schemaName='lists'
|
|
@@ -642,8 +694,8 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
for f in filter:
|
|
|
url+="&query."+f['variable']+"~"+f['oper']+"="+f['value']
|
|
|
if debug:
|
|
|
- print("Sending {}").format(url)
|
|
|
- return json.load(self.get(url))
|
|
|
+ print("Sending {}".format(url))
|
|
|
+ return labkeyURIHandler.getJSON(self.get(url))
|
|
|
|
|
|
|
|
|
def modifyList(self,method,project,dataset,rows):
|
|
@@ -655,4 +707,4 @@ class labkeyURIHandler(slicer.vtkURIHandler):
|
|
|
data['rows']=rows
|
|
|
url=self.GetLabkeyUrl()+'/'+project
|
|
|
url+='/query-'+method+'Rows.api?'
|
|
|
- return self.post(url,json.dumps(data))
|
|
|
+ return self.post(url,json.dumps(data)).data
|