123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- import qt
- import urllib2
- import ssl
- import cookielib
- import xml.etree.ElementTree as ET
- import re
- import StringIO
- import slicer
- import shutil
- import distutils
- import os
- class slicerNetwork:
- def __init__(self,parent):
- parent.title = "slicerNetwork"
- self.parent=parent
- class labkeyURIHandler(slicer.vtkURIHandler):
- def __init__(self):
- slicer.vtkURIHandler.__init__(self)
- self.className="labkeyURIHandler"
- slicer.mrmlScene.AddURIHandler(self)
- try:
- self.localCacheDirectory=os.path.join(
- os.environ["HOME"],"labkeyCache")
- except:
- #in windows, the variable is called HOMEPATH
- fhome=os.environ['HOMEDRIVE']+os.environ['HOMEPATH']
- self.localCacheDirectory=os.path.join(fhome,"labkeyCache")
- def CanHandleURI(self,uri):
- print "labkeyURIHandler::CanHandleURI({0})".format(uri)
- if uri.find('labkey://')==0:
- return 1
- return 0
- def GetClassName(self):
- return self.className
- def GetHostName(self):
- return self.hostname
- def SetHostName(self,host):
- self.hostname=host
- def SetLocalCahceDirectory(self,dir):
- self.localCacheDirectory=dir
- def GetLocalCacheDirectory(self):
- return self.localCacheDirectory
- def GetLocalPath(self,source):
- relativePath=re.sub('labkey://','',source)
- sp=os.sep.encode('string-escape')
- print "Substituting / with {0} in {1}".format(sp,relativePath)
- relativePath=re.sub('/',sp,relativePath)
- return os.path.join(self.localCacheDirectory,relativePath)
- def GetFile(self,source):
- # check for file in cache. If available, use, if not, download
- localPath=self.GetLocalPath(source)
- if os.path.isfile(localPath):
- return localPath
- self.StageFileRead(source,localPath)
- return localPath
- def StageFileRead(self,source,dest):
- print "labkeyURIHandler::StageFileRead({0},{1})".format(
- source,dest)
- labkeyPath=re.sub('labkey://','',source)
- remote=self.readFile(self.hostname,labkeyPath)
- #make all necessary directories
- path=os.path.dirname(dest)
- try:
- os.makedirs(path)
- except:
- if not os.path.isdir(path):
- raise
- local=open(dest,'wb')
- #make sure we are at the begining of the file
-
- #check file size
- remote.seek(0,2)
- sz=remote.tell()
- print "Remote size: {0}".format(sz)
-
- remote.seek(0)
- shutil.copyfileobj(remote,local)
- print "Local size: {0}".format(local.tell())
- local.close()
- def StageFileWrite(self,source,dest):
- print "labkeyURIHandler::StageFileWrite({0},{1}) not implemented yet".format(
- source,dest)
- def fileTypesAvailable(self):
- return ('VolumeFile','SegmentationFile','TransformFile')
- #mimic slicer.util.loadNodeFromFile
- def loadNodeFromFile(self, filename, filetype, properties={}, returnNode=False):
- #this is the only relevant part - file must be downloaded to cache
- localPath=self.GetFile(filename)
- slicer.util.loadNodeFromFile(localPath,filetype,properties,returnNode)
- #remove retrieved file
- try:
- if not(properties['keepCachedFile']) :
- os.remove(localPath)
- except:
- pass
- def loadVolume(self,filename, properties={}, returnNode=False):
- filetype = 'VolumeFile'
- #redirect to self.loadNodeFromFile first to get the cached file
- return self.loadNodeFromFile(filename,filetype, properties,returnNode)
- def loadSegmentation(self,filename,properties={},returnNode=False):
- filetype='SegmentationFile'
- #redirect to self.loadNodeFromFile first to get the cached file
- return self.loadNodeFromFile(filename,filetype, properties,returnNode)
- #add others if needed
- 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)
- self.SetHostName(serverUrl)
- #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,dir):
- print "Listing for {0}".format(dir)
- dirUrl=self.hostname+"/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 toRelativePath(self,dirs):
- flist1=[]
- for d in dirs:
- if d[-1]=='/':
- d=d[:-1]
- if d.rfind('/')>-1:
- d=d[d.rfind('/')+1:]
- flist1.append(d)
- return flist1
- def readFile(self, serverUrl, path):
- dirUrl=serverUrl+"/labkey/_webdav"+"/"+path
- f=self.get(dirUrl)
- return StringIO.StringIO(f.read())
- def loadDir(self, path):
- #dirURL=serverUrl+"/labkey/_webdav/"+path
- files=self.listDir(path)
- for f in files:
- #returns local path
- try:
- self.GetFile(f)
- except:
- #fails if there is a subdirectory; go recursively
- self.readDir(f)
- 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'
|