fileIO.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. import slicerNetwork
  2. import slicer
  3. import qt
  4. import ctk
  5. import json
  6. import os
  7. class fileIO(slicer.ScriptedLoadableModule.ScriptedLoadableModule):
  8. def __init__(self,parent):
  9. slicer.ScriptedLoadableModule.ScriptedLoadableModule.__init__(self, parent)
  10. self.className="fileIO"
  11. self.parent.title="fileIO"
  12. self.parent.categories = ["Examples"]
  13. self.parent.dependencies = []
  14. self.parent.contributors = ["Andrej Studen (UL/FMF)"] # replace with "Firstname Lastname (Organization)"
  15. self.parent.helpText = """
  16. File IO for Labkey interface to slicer
  17. """
  18. self.parent.acknowledgementText = """
  19. Developed within the medical physics research programme of the Slovenian research agency.
  20. """ # replace with organization, grant and thanks.
  21. class remoteFileSelector(qt.QMainWindow):
  22. def __init__(self, parent=None):
  23. super(remoteFileSelector, self).__init__(parent)
  24. self.setup()
  25. def setMaster(self,master):
  26. self.master=master
  27. def setup(self):
  28. centralWidget=qt.QWidget(self)
  29. fileDialogFormLayout = qt.QFormLayout(centralWidget)
  30. #self.layout.addWidget(fileDialogFormLayout)
  31. #add item list for each found file/directory
  32. self.fileList=qt.QListWidget()
  33. self.fileList.toolTip="Select remote file"
  34. self.fileList.itemDoubleClicked.connect(self.onFileListDoubleClicked)
  35. self.currentRemoteDir=''
  36. #add dummy entry
  37. items=('.','..')
  38. self.populateFileList(items)
  39. fileDialogFormLayout.addWidget(self.fileList)
  40. self.selectedPath=qt.QLineEdit("")
  41. self.selectedPath.toolTip="Selected path"
  42. fileDialogFormLayout.addRow("Selected path :",self.selectedPath)
  43. self.closeButton=qt.QPushButton("Close")
  44. self.closeButton.toolTip="Close"
  45. self.closeButton.connect('clicked(bool)',self.onCloseButtonClicked)
  46. fileDialogFormLayout.addRow(self.closeButton)
  47. self.setCentralWidget(centralWidget);
  48. def onFileListDoubleClicked(self,item):
  49. if item == None:
  50. print("Selected items: None")
  51. return
  52. iText=item.text()
  53. print ("Selected items: {0} ").format(iText)
  54. #this is hard -> compose path string from currentRemoteDir and selection
  55. if item.text().find('..')==0:
  56. #one up
  57. idx=self.currentRemoteDir.rfind('/')
  58. if idx<0:
  59. self.currentRemoteDir=''
  60. else:
  61. self.currentRemoteDir=self.currentRemoteDir[:idx]
  62. elif item.text().find('.')==0:
  63. pass
  64. else:
  65. if len(self.currentRemoteDir)>0:
  66. self.currentRemoteDir+='/'
  67. self.currentRemoteDir+=item.text()
  68. print ("Listing {0}").format(self.currentRemoteDir)
  69. flist=self.master.network.toRelativePath(
  70. self.master.network.listDir(self.currentRemoteDir))
  71. print ("Got")
  72. print (flist)
  73. flist.insert(0,'..')
  74. flist.insert(0,'.')
  75. self.populateFileList(flist)
  76. self.selectedPath.setText(self.currentRemoteDir)
  77. self.master.remotePath.setText(self.master.network.GetLabkeyWebdavUrl()+"/"+self.currentRemoteDir)
  78. def populateFileList(self,items):
  79. self.fileList.clear()
  80. for it_text in items:
  81. item=qt.QListWidgetItem(self.fileList)
  82. item.setText(it_text)
  83. item.setIcon(qt.QIcon(it_text))
  84. def onCloseButtonClicked(self):
  85. self.hide()
  86. class fileIOWidget(slicer.ScriptedLoadableModule.ScriptedLoadableModuleWidget):
  87. def __init__(self,parent):
  88. slicer.ScriptedLoadableModule.ScriptedLoadableModuleWidget.__init__(self, parent)
  89. self.selectRemote=remoteFileSelector()
  90. #self.selectLocal=qt.QFileDialog()
  91. #self.selectLocal.connect('fileSelected(QString)',self.onLocalFileSelected)
  92. self.selectRemote.setMaster(self)
  93. self.network=slicerNetwork.labkeyURIHandler()
  94. def setup(self):
  95. connectionCollapsibleButton = ctk.ctkCollapsibleButton()
  96. connectionCollapsibleButton.text = "Connection"
  97. self.layout.addWidget(connectionCollapsibleButton)
  98. connectionFormLayout = qt.QFormLayout(connectionCollapsibleButton)
  99. self.loadConfigButton=qt.QPushButton("Load configuration")
  100. self.loadConfigButton.toolTip="Load configuration"
  101. self.loadConfigButton.connect('clicked(bool)',self.onLoadConfigButtonClicked)
  102. connectionFormLayout.addRow("Connection:",self.loadConfigButton)
  103. fileDialogCollapsibleButton = ctk.ctkCollapsibleButton()
  104. fileDialogCollapsibleButton.text = "Paths"
  105. self.layout.addWidget(fileDialogCollapsibleButton)
  106. fileDialogFormLayout = qt.QFormLayout(fileDialogCollapsibleButton)
  107. self.listRemoteButton=qt.QPushButton("List Remote")
  108. self.listRemoteButton.toolTip="List Remote"
  109. self.listRemoteButton.connect('clicked(bool)',self.onListRemoteButtonClicked)
  110. fileDialogFormLayout.addRow(self.listRemoteButton)
  111. self.listLocalButton=qt.QPushButton("List Local")
  112. self.listLocalButton.toolTip="List Local"
  113. self.listLocalButton.connect('clicked(bool)',self.onListLocalButtonClicked)
  114. fileDialogFormLayout.addRow(self.listLocalButton)
  115. #add selected file display
  116. self.remotePath=qt.QLineEdit("")
  117. self.remotePath.toolTip="Remote path"
  118. fileDialogFormLayout.addRow("RemotePath :",self.remotePath)
  119. self.localPath=qt.QLineEdit("")
  120. self.localPath.toolTip="Local path"
  121. fileDialogFormLayout.addRow("LocalPath :",self.localPath)
  122. copyToRemoteButton=qt.QPushButton("Local->Remote")
  123. copyToRemoteButton.toolTip="Local -> Remote"
  124. copyToRemoteButton.connect('clicked(bool)',self.onCopyToRemoteButtonClicked)
  125. fileDialogFormLayout.addRow(copyToRemoteButton)
  126. removeRemoteButton=qt.QPushButton("Remove remote")
  127. removeRemoteButton.toolTip="Remove Remote"
  128. removeRemoteButton.connect('clicked(bool)',self.onRemoveRemoteButtonClicked)
  129. fileDialogFormLayout.addRow(removeRemoteButton)
  130. mkdirRemoteButton=qt.QPushButton("Mkdir remote")
  131. mkdirRemoteButton.toolTip="Mkdir Remote"
  132. mkdirRemoteButton.connect('clicked(bool)',self.onMkdirRemoteButtonClicked)
  133. fileDialogFormLayout.addRow(mkdirRemoteButton)
  134. def onListLocalButtonClicked(self):
  135. self.localPath.setText(qt.QFileDialog.getOpenFileName(None,"Select local"))
  136. def onListRemoteButtonClicked(self):
  137. self.selectRemote.show()
  138. def onLoadConfigButtonClicked(self):
  139. filename=qt.QFileDialog.getOpenFileName(None,'Open configuration file (JSON)',
  140. '.', '*.json')
  141. with open(filename,'r') as f:
  142. dt=json.load(f)
  143. if dt.has_key('host'):
  144. self.network.hostname=dt['host']
  145. if dt.has_key('SSL'):
  146. self.network.configureSSL(dt['SSL']['user'],dt['SSL']['key'],
  147. dt['SSL']['keyPwd'],dt['SSL']['ca'])
  148. if dt.has_key('labkey'):
  149. if dt['labkey'].has_key('user'):
  150. self.network.auth_name=dt['labkey']['user']
  151. if dt['labkey'].has_key('password'):
  152. self.network.auth_pass=dt['labkey']['password']
  153. self.loadConfigButton.setText(os.path.basename(filename))
  154. self.network.initRemote()
  155. def copyLocalToRemote(self,localPath,remotePath):
  156. if os.path.isfile(localPath):
  157. #end recursion
  158. print ("Copy {} to {}").format(localPath,remotePath)
  159. self.network.copyFileToRemote(localPath,remotePath)
  160. return
  161. dirName=os.path.basename(os.path.normpath(localPath))
  162. remotePath+='/'+dirName
  163. if not self.network.isDir(remotePath):
  164. self.network.mkdir(remotePath+'/')
  165. for f in os.listdir(localPath):
  166. #enter recursion
  167. localfile=os.path.join(localPath,f)
  168. self.copyLocalToRemote(localfile,remotePath)
  169. def onCopyToRemoteButtonClicked(self):
  170. self.copyLocalToRemote(self.localPath.text,self.remotePath.text)
  171. def onRemoveRemoteButtonClicked(self):
  172. remotePath=self.remotePath.text
  173. if self.network.isDir(remotePath):
  174. resp=qt.QMessageBox.question(None,'Delete directory',
  175. 'Do you want to delete directory {}'.format(remotePath))
  176. if resp == qt.QMessageBox.No:
  177. return
  178. self.network.rmdir(remotePath)
  179. def onMkdirRemoteButtonClicked(self):
  180. remotePath=self.remotePath.text
  181. self.network.mkdir(remotePath)
  182. class fileIOLogic(slicer.ScriptedLoadableModule.ScriptedLoadableModuleLogic):
  183. def __init__(self,parent):
  184. slicer.ScriptedLoadableModule.ScriptedLoadableModuleLogic.__init__(self, parent)
  185. class fileIOTest(slicer.ScriptedLoadableModule.ScriptedLoadableModuleTest):
  186. """
  187. This is the test case for your scripted module.
  188. Uses ScriptedLoadableModuleTest base class, available at:
  189. https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py
  190. """
  191. def setUp(self):
  192. """ Do whatever is needed to reset the state - typically a scene clear will be enough.
  193. """
  194. slicer.mrmlScene.Clear(0)
  195. def runTest(self):
  196. """Run as few or as many tests as needed here.
  197. """
  198. self.setUp()
  199. self.test_fileIO()
  200. def test_fileIO(self):
  201. """ Ideally you should have several levels of tests. At the lowest level
  202. tests should exercise the functionality of the logic with different inputs
  203. (both valid andclass dataExplorerTest(ScriptedLoadableModuleTest):
  204. """
  205. pass