labkeyFileBrowser.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import urllib3
  2. import xml.etree.ElementTree as ET
  3. import shutil
  4. class labkeyFileBrowser:
  5. def __init__(self,net):
  6. self.net=net
  7. def GetRootUrl(self):
  8. return self.net.GetLabkeyUrl()+"/_webdav"
  9. def entryExists(self,url):
  10. #check if entry (file/directory) exists
  11. r=self.net.head(url)
  12. if r.status==200:
  13. return True
  14. return False
  15. def listRemoteDir(self,url):
  16. #input is remoteDir, result are remoteDirs
  17. dirs=[]
  18. #r=MethodRequest(dirUrl,method="PROPFIND")
  19. PROPFIND=u"""<?xml version="1.0" encoding="utf-8"?>\n
  20. <propfind xmlns="DAV:">\n
  21. <prop>\n
  22. <getetag/>\n
  23. </prop>\n
  24. </propfind>"""
  25. headers=urllib3.util.make_headers(basic_auth=self.net.getBasicAuth())
  26. headers["Content-Type"]='text/xml; charset="utf-8"'
  27. headers['content-length']=str(len(PROPFIND))
  28. headers['Depth']='1'
  29. #add csrf
  30. headers["X-LABKEY-CSRF"]=self.net.getCSRF()
  31. try:
  32. f=self.net.http.request('PROPFIND',url,headers=headers,body=PROPFIND)
  33. #f contains json as a return value
  34. except urllib3.exceptions.HTTPError as e:
  35. print(e)
  36. return False,dirs
  37. try:
  38. tree=ET.XML(f.data)
  39. except ET.ParseError:
  40. #print(f.data.decode('utf-8'))
  41. #if directory is not there, a 404 response will be made by HTTP, which is not an xml file
  42. #we are safe to assume the directory is not there
  43. return False,dirs
  44. rps=tree.findall('{DAV:}response')
  45. for r in rps:
  46. hr=r.find('{DAV:}href')
  47. dirent=hr.text
  48. #dirent=re.sub('/labkey/_webdav/','',dirent)
  49. dirent=self.net.connectionConfig['host']+dirent
  50. dirs.append(dirent)
  51. del dirs[0]
  52. return True,dirs
  53. def buildPathURL(self,project,pathList):
  54. #build/check remote directory structure
  55. remoteDir=self.formatPathURL(project,'')
  56. for p in pathList:
  57. remoteDir+='/'+p
  58. if not self.entryExists(remoteDir):
  59. self.mkdir(remoteDir)
  60. return remoteDir
  61. def readFileToBuffer(self, url):
  62. return self.net.get(url,binary=True)
  63. def readFileToFile(self,url,path):
  64. response=self.readFileToBuffer(url)
  65. with open(path,'wb') as out_file:
  66. shutil.copyfileobj(response,out_file)
  67. response.release_conn()
  68. def writeFileToFile(self,path,url):
  69. with open(path,'rb') as f:
  70. data=f.read()
  71. self.net.put(url,data)
  72. def formatPathURL(self,project,path):
  73. url=self.GetRootUrl()+'/'+project+'/@files'
  74. if len(path)==0:
  75. return url
  76. return url+'/'+path
  77. def mkdir(self,url):
  78. self.net.mkcol(url)