Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
RDM Infrastructure
irods-clients
Commits
006a8351
Commit
006a8351
authored
Jan 20, 2022
by
Staiger, Christine
Browse files
Merge branch 'acceptance' into 'master'
GUI executable first version See merge request rdm-infrastructure/irods-clients!14
parents
375a2580
62a20e56
Changes
57
Expand all
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
006a8351
__pycache__
irods-basicGUI/logs/*
\ No newline at end of file
irods-basicGUI/logs/*
# Build pipeline
venv
build
dist
irods-iBridgesGui.spec
\ No newline at end of file
README.md
View file @
006a8351
...
...
@@ -73,7 +73,7 @@ The client works on Mac, Windows and Linux distributions. On Mac and Windows it
-
Install the iBridges GUI on a linux (sub)system
-
[
Install the icommands
](
https://git.wur.nl/rdm-infrastructure/irods-training/-/blob/master/04-Training-Setup.md#icommands
)
.
-
Start the iBridges GUI in the mode (icommands) on the Login screen.
<img
src=
"
gui/
icons/irods-basicGUI_Login.png"
width=
"500"
>
<img
src=
"icons/irods-basicGUI_Login.png"
width=
"500"
>
## Configuration
### iRODS environment.json
...
...
@@ -108,6 +108,33 @@ The client works on Mac, Windows and Linux distributions. On Mac and Windows it
./irods-iBridgesGui.py
```
### Executable
If you want to compile an executable of the GUI do:
```
python3 pyinstaller_script.py
```
This will create the following folder tree:
```
dist
├── icons
│ ├── arrow-left.png
│ ├── arrow-right.png
│ ├── home.png
│ ├── irods-basicGUI_Login.png
│ ├── loading_circle.gif
│ ├── nosync.png
│ └── syncing.png
├── irods-iBridgesGui
│ ├── ...
│ ├── irods-iBridgesGui
```
Place the complete dist folder to the server or the subtree where you need the application.
Start the application by double-clicking on
`irods-iBridgesGui`
.
## Remarks
### Performance
...
...
gui/dataTransfer.py
View file @
006a8351
...
...
@@ -11,17 +11,19 @@ from irods.keywords import NO_PARA_OP_KW
from
utils.utils
import
getSize
import
os
from
gui.ui_files.dataTransferState
import
Ui_dataTransferState
# Loading symbol generator
# http://www.ajaxload.info/#preview
class
dataTransfer
(
QDialog
):
class
dataTransfer
(
QDialog
,
Ui_dataTransferState
):
finished
=
pyqtSignal
(
bool
,
object
)
def
__init__
(
self
,
ic
,
upload
,
localFsPath
,
irodsColl
,
irodsTreeIdx
=
None
,
resource
=
None
):
super
(
dataTransfer
,
self
).
__init__
()
loadUi
(
"gui/ui-files/dataTransferState.ui"
,
self
)
super
(
dataTransfer
,
self
).
setupUi
(
self
)
#loadUi("gui/ui-files/dataTransferState.ui", self)
self
.
ic
=
ic
self
.
localFsPath
=
localFsPath
...
...
@@ -43,7 +45,7 @@ class dataTransfer(QDialog):
self
.
confirmBtn
.
setText
(
"Download"
)
self
.
confirmBtn
.
setEnabled
(
False
)
self
.
loading_movie
=
QMovie
(
"
gui/
icons/loading_circle.gif"
)
self
.
loading_movie
=
QMovie
(
"icons/loading_circle.gif"
)
self
.
loadingLbl
.
setMovie
(
self
.
loading_movie
)
self
.
loading_movie
.
start
()
...
...
@@ -62,10 +64,10 @@ class dataTransfer(QDialog):
def
cancel
(
self
):
print
(
"Thread stopped"
)
print
(
"
DataTransfer:
Thread stopped"
)
self
.
finished
.
emit
(
False
,
None
)
try
:
# if thread is still running
self
.
thread
.
exit
(
1
)
self
.
thread
.
exit
(
1
)
except
:
pass
self
.
close
()
...
...
@@ -115,15 +117,12 @@ class dataTransfer(QDialog):
# Callback for the getDataSize worker
def
updateUiWithDataState
(
self
,
addFiles
,
diff
,
addSize
,
updateSize
):
self
.
updateSize
=
updateSize
print
(
int
(
addSize
),
int
(
updateSize
))
#checksumSizeStr = self.bytesToStr(updateSize)
self
.
ChecksumSizeLbl
.
setText
(
self
.
bytesToStr
(
int
(
updateSize
)))
self
.
updateSize
=
int
(
updateSize
)
self
.
addSize
=
int
(
addSize
)
self
.
ChecksumSizeLbl
.
setText
(
self
.
bytesToStr
(
self
.
updateSize
))
self
.
diff
=
diff
self
.
addSize
=
addSize
#newSizeStr = self.bytesToStr(addSize)
self
.
newFSizeLbl
.
setText
(
self
.
bytesToStr
(
int
(
addSize
)))
self
.
newFSizeLbl
.
setText
(
self
.
bytesToStr
(
self
.
addSize
))
self
.
addFiles
=
addFiles
self
.
loading_movie
.
stop
()
...
...
@@ -214,8 +213,6 @@ class getDataState(QObject):
fullOnlyFsPaths
.
extend
([
d
for
d
in
onlyFS
if
d
.
startswith
(
'/'
)
or
':'
in
d
])
addSize
=
getSize
(
fullOnlyFsPaths
)
print
(
str
(
fsDiffFiles
)
+
" "
+
str
(
updateSize
))
print
(
str
(
onlyFS
)
+
" "
+
str
(
addSize
))
self
.
finished
.
emit
(
onlyFS
,
diff
,
str
(
addSize
),
str
(
updateSize
))
else
:
irodsDiffFiles
=
[
d
[
0
]
for
d
in
diff
]
...
...
gui/elabUpload.py
View file @
006a8351
from
utils.elabConnector
import
elabConnector
from
PyQt5
import
QtCore
,
QtGui
,
QtWidgets
from
PyQt5.QtWidgets
import
QMessageBox
,
QTableWidgetItem
,
QFileSystemModel
from
PyQt5.QtWidgets
import
QMessageBox
,
QTableWidgetItem
,
QFileSystemModel
,
QWidget
from
PyQt5.QtCore
import
QObject
,
QThread
,
pyqtSignal
from
gui.checkableFsTree
import
checkableFsTreeModel
...
...
@@ -9,30 +9,34 @@ from utils.utils import getSize, walkToDict
from
irods.exception
import
CATALOG_ALREADY_HAS_ITEM_BY_THAT_NAME
import
logging
class
elabUpload
():
def
__init__
(
self
,
widget
,
ic
):
self
.
widget
=
widget
from
gui.ui_files.tabELNData
import
Ui_tabELNData
class
elabUpload
(
QWidget
,
Ui_tabELNData
):
def
__init__
(
self
,
ic
):
super
(
elabUpload
,
self
).
__init__
()
super
(
elabUpload
,
self
).
setupUi
(
self
)
self
.
elab
=
None
self
.
coll
=
None
self
.
ic
=
ic
# Return errors to:
self
.
errorLabel
=
widget
.
errorLabel
self
.
errorLabel
=
self
.
errorLabel
#Gathering Eln configuration
self
.
elnTokenInput
=
widget
.
elnTokenInput
self
.
elnGroupTable
=
widget
.
elnGroupTable
self
.
elnExperimentTable
=
widget
.
elnExperimentTable
self
.
elnTokenInput
=
self
.
elnTokenInput
self
.
elnGroupTable
=
self
.
elnGroupTable
self
.
elnExperimentTable
=
self
.
elnExperimentTable
#Config ok check
self
.
groupIdLabel
=
widget
.
groupIdLabel
self
.
experimentIdLabel
=
widget
.
experimentIdLabel
self
.
groupIdLabel
=
self
.
groupIdLabel
self
.
experimentIdLabel
=
self
.
experimentIdLabel
#Selecting and uploading local files and folders
self
.
dirmodel
=
checkableFsTreeModel
(
widget
.
localFsTable
)
widget
.
localFsTable
.
setModel
(
self
.
dirmodel
)
self
.
localFsTable
=
widget
.
localFsTable
self
.
dirmodel
=
checkableFsTreeModel
(
self
.
localFsTable
)
self
.
localFsTable
.
setModel
(
self
.
dirmodel
)
self
.
localFsTable
=
self
.
localFsTable
self
.
elnUploadButton
=
widget
.
elnUploadButton
self
.
elnUploadButton
=
self
.
elnUploadButton
#Showing result
self
.
elnPreviewBrowser
=
widget
.
elnPreviewBrowser
self
.
elnIrodsPath
=
widget
.
elnIrodsPath
self
.
elnPreviewBrowser
=
self
.
elnPreviewBrowser
self
.
elnIrodsPath
=
self
.
elnIrodsPath
#defining events and listeners
self
.
elnTokenInput
.
returnPressed
.
connect
(
self
.
connectElab
)
...
...
@@ -57,12 +61,12 @@ class elabUpload():
row
=
row
+
1
self
.
elnGroupTable
.
resizeColumnsToContents
()
self
.
loadLocalFileView
()
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
except
Exception
as
e
:
logging
.
info
(
"elabUpload: "
+
repr
(
e
))
self
.
errorLabel
.
setText
(
"ELN ERROR: "
+
repr
(
e
)
+
"
\n
Your permissions for your current active group might be blocked."
)
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
return
def
selectExperiment
(
self
,
expId
):
...
...
@@ -77,7 +81,7 @@ class elabUpload():
def
loadExperiments
(
self
):
self
.
errorLabel
.
clear
()
self
.
elnExperimentTable
.
setRowCount
(
0
)
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
WaitCursor
))
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
WaitCursor
))
row
=
self
.
elnGroupTable
.
currentRow
()
if
row
>
-
1
:
groupId
=
self
.
elnGroupTable
.
item
(
row
,
0
).
text
()
...
...
@@ -104,11 +108,11 @@ class elabUpload():
logging
.
info
(
"ElabUpload groupId "
+
str
(
groupId
)
+
": "
+
repr
(
error
))
self
.
errorLabel
.
setText
(
"ELN ERROR: "
+
repr
(
e
)
+
"
\n
You might not have permissions for that group."
)
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
return
self
.
elnExperimentTable
.
resizeColumnsToContents
()
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
def
loadLocalFileView
(
self
):
...
...
@@ -183,7 +187,7 @@ class elabUpload():
print
(
"ELN DATA UPLOAD experiment:
\n
"
+
expUrl
)
#get upload total size to inform user
size
=
round
(
getSize
([
path
])
/
1024
**
2
)
size
=
getSize
([
path
])
#if user specifies a different path than standard home
if
self
.
elnIrodsPath
.
text
()
==
'/zone/home/user'
:
collPath
=
'/'
+
self
.
ic
.
session
.
zone
+
'/home/'
+
self
.
ic
.
session
.
username
+
'/'
+
subcoll
...
...
@@ -194,7 +198,7 @@ class elabUpload():
buttonReply
=
QMessageBox
.
question
(
self
.
elnUploadButton
,
'Message Box'
,
"Upload
\n
"
+
path
+
'
\n
'
+
str
(
size
)
+
'
MB
'
,
'Message Box'
,
"Upload
\n
"
+
path
+
'
\n
'
+
str
(
size
)
+
'
Bytes
'
,
QMessageBox
.
Yes
|
QMessageBox
.
No
,
QMessageBox
.
No
)
upload
=
buttonReply
==
QMessageBox
.
Yes
if
upload
:
...
...
@@ -264,28 +268,35 @@ class Worker(QObject):
logging
.
info
(
"ElabUpload data upload and annotation worker: "
+
repr
(
e
))
print
(
repr
(
e
))
self
.
annotateElab
()
self
.
annotateElab
({
"Data size"
:
str
(
self
.
size
)
+
"Bytes"
,
"iRODS path"
:
self
.
coll
.
path
,
"iRODS server"
:
self
.
ic
.
session
.
host
,
"iRODS user"
:
self
.
ic
.
session
.
username
})
def
annotateElab
(
self
):
def
annotateElab
(
self
,
metadata
):
self
.
errorLabel
.
setText
(
"Linking data to Elabjournal experiment."
)
if
self
.
ic
.
davrods
and
"yoda"
in
self
.
ic
.
session
.
host
:
self
.
elab
.
addMetadata
(
self
.
ic
.
davrods
+
'/'
+
self
.
coll
.
path
.
split
(
'home/'
)[
1
].
strip
(),
meta
=
metadata
,
title
=
'Data in iRODS'
)
elif
self
.
ic
.
davrods
and
"surfsara.nl"
in
self
.
ic
.
session
.
host
:
self
.
elab
.
addMetadata
(
self
.
ic
.
davrods
+
'/'
+
self
.
coll
.
path
.
split
(
self
.
ic
.
session
.
zone
)[
1
].
strip
(
'/'
),
meta
=
metadata
,
title
=
'Data in iRODS'
)
elif
self
.
ic
.
davrods
:
self
.
elab
.
addMetadata
(
self
.
ic
.
davrods
+
'/'
+
self
.
coll
.
path
.
strip
(
'/'
),
meta
=
metadata
,
title
=
'Data in iRODS'
)
else
:
self
.
elab
.
addMetadata
(
'{'
+
self
.
ic
.
session
.
host
+
',
\n
'
\
+
self
.
ic
.
session
.
zone
+
',
\n
'
\
+
self
.
ic
.
session
.
username
+
',
\n
'
\
+
str
(
self
.
ic
.
session
.
port
)
+
'}
\n
'
+
self
.
coll
.
path
,
title
=
'Data in iRODS'
)
self
.
coll
.
path
,
meta
=
metadata
,
title
=
'Data in iRODS'
)
gui/irodsBrowser.py
View file @
006a8351
This diff is collapsed.
Click to expand it.
gui/irodsCreateTicket.py
View file @
006a8351
from
PyQt5
import
QtGui
,
QtCore
from
PyQt5.QtWidgets
import
QWidget
from
gui.irodsTreeView
import
IrodsModel
from
gui.ui_files.tabTicketCreate
import
Ui_tabticketCreate
class
irodsCreateTicket
():
def
__init__
(
self
,
widget
,
ic
,
ienv
):
self
.
ic
=
ic
self
.
widget
=
widget
class
irodsCreateTicket
(
QWidget
,
Ui_tabticketCreate
):
def
__init__
(
self
,
ic
,
ienv
):
super
(
irodsCreateTicket
,
self
).
__init__
()
super
(
irodsCreateTicket
,
self
).
setupUi
(
self
)
self
.
irodsmodel
=
IrodsModel
(
ic
,
self
.
widget
.
irodsFsTreeView
)
self
.
widget
.
irodsFsTreeView
.
setModel
(
self
.
irodsmodel
)
self
.
ic
=
ic
self
.
irodsmodel
=
IrodsModel
(
ic
,
self
.
irodsFsTreeView
)
self
.
irodsFsTreeView
.
setModel
(
self
.
irodsmodel
)
self
.
irodsRootColl
=
'/'
+
ic
.
session
.
zone
self
.
irodsmodel
.
setHorizontalHeaderLabels
([
self
.
irodsRootColl
,
'Level'
,
'iRODS ID'
,
'parent ID'
,
'type'
])
self
.
widget
.
irodsFsTreeView
.
expanded
.
connect
(
self
.
irodsmodel
.
refreshSubTree
)
self
.
widget
.
irodsFsTreeView
.
clicked
.
connect
(
self
.
irodsmodel
.
refreshSubTree
)
self
.
irodsFsTreeView
.
expanded
.
connect
(
self
.
irodsmodel
.
refreshSubTree
)
self
.
irodsFsTreeView
.
clicked
.
connect
(
self
.
irodsmodel
.
refreshSubTree
)
self
.
irodsmodel
.
initTree
()
self
.
widget
.
irodsFsTreeView
.
setHeaderHidden
(
True
)
self
.
widget
.
irodsFsTreeView
.
header
().
setDefaultSectionSize
(
180
)
self
.
widget
.
irodsFsTreeView
.
setColumnHidden
(
1
,
True
)
self
.
widget
.
irodsFsTreeView
.
setColumnHidden
(
2
,
True
)
self
.
widget
.
irodsFsTreeView
.
setColumnHidden
(
3
,
True
)
self
.
widget
.
irodsFsTreeView
.
setColumnHidden
(
4
,
True
)
self
.
irodsFsTreeView
.
setHeaderHidden
(
True
)
self
.
irodsFsTreeView
.
header
().
setDefaultSectionSize
(
180
)
self
.
irodsFsTreeView
.
setColumnHidden
(
1
,
True
)
self
.
irodsFsTreeView
.
setColumnHidden
(
2
,
True
)
self
.
irodsFsTreeView
.
setColumnHidden
(
3
,
True
)
self
.
irodsFsTreeView
.
setColumnHidden
(
4
,
True
)
self
.
widget
.
createTicketButton
.
clicked
.
connect
(
self
.
createTicket
)
self
.
createTicketButton
.
clicked
.
connect
(
self
.
createTicket
)
def
createTicket
(
self
):
self
.
widget
.
infoLabel
.
clear
()
self
.
widget
.
ticketInfoBrowser
.
clear
()
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
WaitCursor
))
self
.
widget
.
createTicketButton
.
setEnabled
(
False
)
self
.
infoLabel
.
clear
()
self
.
ticketInfoBrowser
.
clear
()
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
WaitCursor
))
self
.
createTicketButton
.
setEnabled
(
False
)
#gather info
idx
,
path
=
self
.
irodsmodel
.
get_checked
()
if
path
==
None
or
self
.
ic
.
session
.
data_objects
.
exists
(
path
):
self
.
widget
.
infoLabel
.
setText
(
"ERROR: Please select a collection."
)
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
widget
.
createTicketButton
.
setEnabled
(
True
)
self
.
infoLabel
.
setText
(
"ERROR: Please select a collection."
)
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
createTicketButton
.
setEnabled
(
True
)
return
acls
=
[(
acl
.
user_name
,
acl
.
access_name
)
for
acl
in
self
.
ic
.
getPermissions
(
path
)]
if
(
self
.
ic
.
session
.
username
,
"own"
)
in
acls
:
date
=
self
.
widget
.
calendar
.
selectedDate
()
date
=
self
.
calendar
.
selectedDate
()
#format of time string for irods: 2012-05-07.23:00:00
expiryString
=
str
(
date
.
toPyDate
())
+
'.23:59:59'
ticket
,
expiryDate
=
self
.
ic
.
createTicket
(
path
,
expiryString
)
self
.
widget
.
ticketInfoBrowser
.
append
(
"iRODS server:
\t
"
+
self
.
ic
.
session
.
host
)
self
.
widget
.
ticketInfoBrowser
.
append
(
"iRODS path:
\t
"
+
path
)
self
.
widget
.
ticketInfoBrowser
.
append
(
"iRODS Ticket:
\t
"
+
ticket
)
self
.
ticketInfoBrowser
.
append
(
"iRODS server:
\t
"
+
self
.
ic
.
session
.
host
)
self
.
ticketInfoBrowser
.
append
(
"iRODS path:
\t
"
+
path
)
self
.
ticketInfoBrowser
.
append
(
"iRODS Ticket:
\t
"
+
ticket
)
if
self
.
ic
.
__name__
==
"irodsConnector"
:
self
.
widget
.
ticketInfoBrowser
.
append
(
"Expiry date:
\t
Not set (linux only)"
)
self
.
ticketInfoBrowser
.
append
(
"Expiry date:
\t
Not set (linux only)"
)
else
:
self
.
widget
.
ticketInfoBrowser
.
append
(
"Expiry date:
\t
"
+
expiryDate
)
self
.
ticketInfoBrowser
.
append
(
"Expiry date:
\t
"
+
expiryDate
)
else
:
self
.
widget
.
infoLabel
.
setText
(
"ERROR: Insufficient rights, you need to be owner."
)
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
widget
.
createTicketButton
.
setEnabled
(
True
)
self
.
infoLabel
.
setText
(
"ERROR: Insufficient rights, you need to be owner."
)
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
createTicketButton
.
setEnabled
(
True
)
return
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
widget
.
createTicketButton
.
setEnabled
(
True
)
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
createTicketButton
.
setEnabled
(
True
)
gui/irodsDataCompression.py
View file @
006a8351
from
gui.irodsTreeView
import
IrodsModel
from
gui.popupWidgets
import
irodsIndexPopup
from
PyQt5.QtWidgets
import
QMessageBox
from
PyQt5.uic
import
loadUi
from
PyQt5.QtWidgets
import
QMessageBox
,
QWidget
from
PyQt5.QtCore
import
QObject
,
QThread
,
pyqtSlot
,
pyqtSignal
from
PyQt5
import
QtGui
,
QtCore
from
os
import
path
,
getcwd
import
json
import
sys
class
irodsDataCompression
():
def
__init__
(
self
,
widget
,
ic
,
ienv
):
from
gui.irodsTreeView
import
IrodsModel
from
gui.popupWidgets
import
irodsIndexPopup
from
gui.ui_files.tabDataCompression
import
Ui_tabDataCompression
class
irodsDataCompression
(
QWidget
,
Ui_tabDataCompression
):
def
__init__
(
self
,
ic
,
ienv
):
super
(
irodsDataCompression
,
self
).
__init__
()
super
(
irodsDataCompression
,
self
).
setupUi
(
self
)
self
.
ic
=
ic
self
.
widget
=
widget
self
.
ienv
=
ienv
rescs
=
self
.
ic
.
listResources
()
if
ic
.
defaultResc
not
in
rescs
:
...
...
@@ -21,41 +22,46 @@ class irodsDataCompression():
+
'
\n
DataCompression view not setup.'
)
return
ruleFiles
=
[
path
.
join
(
getcwd
(),
'rules/tarCollection.r'
),
path
.
join
(
getcwd
(),
'rules/tarReadIndex.r'
),
path
.
join
(
getcwd
(),
'rules/tarExtract.r'
)]
if
getattr
(
sys
,
'frozen'
,
False
):
self
.
basefolder
=
path
.
join
(
path
.
dirname
(
path
.
realpath
(
sys
.
argv
[
0
])),
path
.
pardir
)
else
:
self
.
basefolder
=
path
.
dirname
(
path
.
realpath
(
sys
.
argv
[
0
]))
ruleFiles
=
[
path
.
join
(
self
.
basefolder
,
'rules/tarCollection.r'
),
path
.
join
(
self
.
basefolder
,
'rules/tarReadIndex.r'
),
path
.
join
(
self
.
basefolder
,
'rules/tarExtract.r'
)]
for
rule
in
ruleFiles
:
if
not
path
.
isfile
(
rule
):
self
.
infoPopup
(
'ERROR rules not configured:
\n
'
+
rule
\
+
'
\n
DataCompression view not setup.'
)
return
self
.
widget
.
irodsZoneLabel1
.
setText
(
"/"
+
self
.
ic
.
session
.
zone
+
":"
)
self
.
widget
.
irodsZoneLabel2
.
setText
(
"/"
+
self
.
ic
.
session
.
zone
+
":"
)
self
.
irodsZoneLabel1
.
setText
(
"/"
+
self
.
ic
.
session
.
zone
+
":"
)
self
.
irodsZoneLabel2
.
setText
(
"/"
+
self
.
ic
.
session
.
zone
+
":"
)
self
.
irodsRootColl
=
'/'
+
ic
.
session
.
zone
index
=
self
.
widget
.
decompressRescButton
.
findText
(
ic
.
defaultResc
)
self
.
widget
.
decompressRescButton
.
setCurrentIndex
(
index
)
index
=
self
.
decompressRescButton
.
findText
(
ic
.
defaultResc
)
self
.
decompressRescButton
.
setCurrentIndex
(
index
)
#irodsCollectionTree
self
.
collectionTreeModel
=
self
.
setupFsTree
(
self
.
widget
.
irodsCollectionTree
)
self
.
widget
.
irodsCollectionTree
.
expanded
.
connect
(
self
.
collectionTreeModel
.
refreshSubTree
)
#self.
widget.
irodsCollectionTree.clicked.connect(self.collectionTreeModel.refreshSubTree)
self
.
collectionTreeModel
=
self
.
setupFsTree
(
self
.
irodsCollectionTree
)
self
.
irodsCollectionTree
.
expanded
.
connect
(
self
.
collectionTreeModel
.
refreshSubTree
)
#self.irodsCollectionTree.clicked.connect(self.collectionTreeModel.refreshSubTree)
#irodsCompressionTree
self
.
compressionTreeModel
=
self
.
setupFsTree
(
self
.
widget
.
irodsCompressionTree
)
self
.
widget
.
irodsCompressionTree
.
expanded
.
connect
(
self
.
compressionTreeModel
.
refreshSubTree
)
#self.
widget.
irodsCompressionTree.clicked.connect(self.compressionTreeModel.refreshSubTree)
self
.
compressionTreeModel
=
self
.
setupFsTree
(
self
.
irodsCompressionTree
)
self
.
irodsCompressionTree
.
expanded
.
connect
(
self
.
compressionTreeModel
.
refreshSubTree
)
#self.irodsCompressionTree.clicked.connect(self.compressionTreeModel.refreshSubTree)
#resource buttons
self
.
setupResourceButton
(
self
.
widget
.
compressRescButton
)
self
.
setupResourceButton
(
self
.
widget
.
decompressRescButton
)
self
.
setupResourceButton
(
self
.
compressRescButton
)
self
.
setupResourceButton
(
self
.
decompressRescButton
)
#Create/Unpack/Index buttons
self
.
widget
.
createButton
.
clicked
.
connect
(
self
.
createDataBundle
)
self
.
widget
.
unpackButton
.
clicked
.
connect
(
self
.
unpackDataBundle
)
self
.
widget
.
indexButton
.
clicked
.
connect
(
self
.
getIndex
)
self
.
createButton
.
clicked
.
connect
(
self
.
createDataBundle
)
self
.
unpackButton
.
clicked
.
connect
(
self
.
unpackDataBundle
)
self
.
indexButton
.
clicked
.
connect
(
self
.
getIndex
)
def
infoPopup
(
self
,
message
):
QMessageBox
.
information
(
self
.
widget
,
'Information'
,
message
)
QMessageBox
.
information
(
self
,
'Information'
,
message
)
def
setupFsTree
(
self
,
treeView
):
...
...
@@ -87,39 +93,39 @@ class irodsDataCompression():
button
.
setCurrentIndex
(
index
)
def
enableButtons
(
self
,
enable
):
self
.
widget
.
compressRescButton
.
setEnabled
(
enable
)
self
.
widget
.
decompressRescButton
.
setEnabled
(
enable
)
self
.
compressRescButton
.
setEnabled
(
enable
)
self
.
decompressRescButton
.
setEnabled
(
enable
)
#Create/Unpack/Index buttons
self
.
widget
.
createButton
.
setEnabled
(
enable
)
self
.
widget
.
unpackButton
.
setEnabled
(
enable
)
self
.
widget
.
indexButton
.
setEnabled
(
enable
)
self
.
createButton
.
setEnabled
(
enable
)
self
.
unpackButton
.
setEnabled
(
enable
)
self
.
indexButton
.
setEnabled
(
enable
)
def
createDataBundle
(
self
):
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
WaitCursor
))
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
WaitCursor
))
self
.
enableButtons
(
False
)
self
.
widget
.
createStatusLabel
.
clear
()
ruleFile
=
path
.
join
(
getcwd
()
,
'rules/tarCollection.r'
)
self
.
createStatusLabel
.
clear
()
ruleFile
=
path
.
join
(
self
.
basefolder
,
'rules/tarCollection.r'
)
idx
,
source
=
self
.
collectionTreeModel
.
get_checked
()
if
not
self
.
ic
.
session
.
collections
.
exists
(
source
):
self
.
widget
.
createStatusLabel
.
setText
(
"ERROR: No collection selected."
)
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
createStatusLabel
.
setText
(
"ERROR: No collection selected."
)
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
enableButtons
(
True
)
return
#data bundling only allowed for collections in home/user
if
len
(
source
.
split
(
'/'
))
<
5
:
self
.
widget
.
createStatusLabel
.
setText
(
self
.
createStatusLabel
.
setText
(
"ERROR: Selected collection is not a user collection."
)
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
enableButtons
(
True
)
return
compress
=
self
.
widget
.
compressCheckBox
.
isChecked
()
remove
=
self
.
widget
.
removeCheckBox
.
isChecked
()
migrateResc
=
self
.
widget
.
compressRescButton
.
currentText
()
compress
=
self
.
compressCheckBox
.
isChecked
()
remove
=
self
.
removeCheckBox
.
isChecked
()
migrateResc
=
self
.
compressRescButton
.
currentText
()
params
=
{
'*coll'
:
'"'
+
source
+
'"'
,
'*resource'
:
'"'
+
migrateResc
+
'"'
,
...
...
@@ -128,7 +134,7 @@ class irodsDataCompression():
}
self
.
threadCreate
=
QThread
()
self
.
widget
.
createStatusLabel
.
setText
(
"STATUS: compressing "
+
source
)
self
.
createStatusLabel
.
setText
(
"STATUS: compressing "
+
source
)
self
.
worker
=
dataBundleCreateExtract
(
self
.
ic
,
ruleFile
,
params
,
"create"
)
self
.
worker
.
moveToThread
(
self
.
threadCreate
)
self
.
threadCreate
.
started
.
connect
(
self
.
worker
.
run
)
...
...
@@ -140,55 +146,55 @@ class irodsDataCompression():
def
dataCreateExtractFinished
(
self
,
success
,
message
,
operation
):
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
enableButtons
(
True
)
stdout
,
stderr
=
message
if
success
and
operation
==
"create"
:
idx
,
source
=
self
.
collectionTreeModel
.
get_checked
()
self
.
widget
.
createStatusLabel
.
setText
(
"STATUS: Created "
+
str
(
stdout
))
self
.
createStatusLabel
.
setText
(
"STATUS: Created "
+
str
(
stdout
))
parentIdx
=
self
.
collectionTreeModel
.
getParentIdx
(
idx
)
self
.
collectionTreeModel
.
refreshSubTree
(
parentIdx
)
elif
not
success
and
operation
==
"create"
:
self
.
widget
.
createStatusLabel
.
setText
(
"ERROR: Create failed: "
+
str
(
stderr
))
self
.
createStatusLabel
.
setText
(
"ERROR: Create failed: "
+
str
(
stderr
))
elif
success
and
operation
==
"extract"
:
idx
,
source
=
self
.
compressionTreeModel
.
get_checked
()
stdout
,
stderr
=
message
self
.
widget
.
unpackStatusLabel
.
setText
(
"STATUS: Extracted "
+
str
(
stdout
))
self
.
unpackStatusLabel
.
setText
(
"STATUS: Extracted "
+
str
(
stdout
))
parentIdx
=
self
.
compressionTreeModel
.
getParentIdx
(
idx
)
self
.
compressionTreeModel
.
refreshSubTree
(
parentIdx
)
elif
not
success
and
operation
==
"extract"
:
self
.
widget
.
unpackStatusLabel
.
setText
(
"ERROR: Create failed: "
+
str
(
stderr
))
self
.
unpackStatusLabel
.
setText
(
"ERROR: Create failed: "
+
str
(
stderr
))
def
unpackDataBundle
(
self
):
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
WaitCursor
))
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
WaitCursor
))
idx
,
source
=
self
.
compressionTreeModel
.
get_checked
()
if
not
idx
or
(
not
source
.
endswith
(
".irods.tar"
)
and
not
source
.
endswith
(
".irods.zip"
)):
self
.
widget
.
unpackStatusLabel
.
setText
(
"ERROR: No *.irods.tar or *.irods.zip selected"
)
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
unpackStatusLabel
.
setText
(
"ERROR: No *.irods.tar or *.irods.zip selected"
)
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
return
extractPath
=
path
.
dirname
(
source
)
+
'/'
+
path
.
basename
(
source
).
split
(
'.irods'
)[
0
]
if
self
.
ic
.
session
.
collections
.
exists
(
extractPath
):
extractColl
=
self
.
ic
.
session
.
collections
.
get
(
extractPath
)
if
extractColl
.
subcollections
!=
[]
or
extractColl
.
data_objects
!=
[]:
self
.
widget
.
unpackStatusLabel
.
setText
(
"ERROR: Destination not empty: "
+
extractPath
)
self
.
widget
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
self
.
unpackStatusLabel
.
setText
(
"ERROR: Destination not empty: "
+
extractPath
)
self
.
setCursor
(
QtGui
.
QCursor
(
QtCore
.
Qt
.
ArrowCursor
))
return
self
.
enableButtons
(
False
)
self
.
widget
.
unpackStatusLabel
.
clear
()
ruleFile
=
path
.
join
(
getcwd
()
,
'rules/tarExtract.r'
)
self
.
unpackStatusLabel
.
clear
()
ruleFile
=
path
.
join
(
self
.
basefolder
,
'rules/tarExtract.r'
)