Skip to content
Snippets Groups Projects
Commit 9e160cd1 authored by Staiger, Christine's avatar Staiger, Christine
Browse files

Adding browser function to ticket access.

parent 117e18a9
No related branches found
No related tags found
No related merge requests found
......@@ -34,8 +34,8 @@ class irodsCreateTicket():
#gather info
idx, path = self.irodsmodel.get_checked()
if path == None:
self.widget.infoLabel.setText("ERROR: No data selected.")
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)
return
......
from PyQt5 import QtWidgets
from PyQt5.uic import loadUi
from utils.irodsConnectorAnonymous import irodsConnectorAnonymous
import os
class irodsTicketLogin():
def __init__(self):
def __init__(self, widget):
self.ic = None
self.coll = None
self.widget = widget
self.widget.connectButton.clicked.connect(self.irodsSession)
self.widget.homeButton.clicked.connect(self.loadTable)
self.widget.collTable.doubleClicked.connect(self.browse)
print("TODO")
def irodsSession(self):
self.widget.infoLabel.clear()
host = self.widget.serverEdit.text()
token = self.widget.ticketEdit.text()
path = self.widget.pathEdit.text()
try:
self.ic = irodsConnectorAnonymous(host, token, path)
self.coll = self.ic.getData()
self.loadTable()
except Exception as e:
self.widget.infoLabel.setText("LOGIN ERROR: Check ticket and iRODS path.\n"+repr(e))
def loadTable(self, update = None):
self.widget.infoLabel.clear()
if self.coll == None:
self.widget.infoLabel.setText("No data avalaible. Check ticket and iRODS path.")
return
if update == None or update == False:
update = self.coll
self.widget.collTable.setRowCount(0)
self.widget.collTable.setRowCount(len(update.subcollections)+len(update.data_objects))
row = 0
for subcoll in update.subcollections:
self.widget.collTable.setItem(row, 0,
QtWidgets.QTableWidgetItem(os.path.dirname(subcoll.path)))
self.widget.collTable.setItem(row, 1,
QtWidgets.QTableWidgetItem(subcoll.name+"/"))
self.widget.collTable.setItem(1, 2, QtWidgets.QTableWidgetItem(""))
self.widget.collTable.setItem(1, 3, QtWidgets.QTableWidgetItem(""))
row = row + 1
for obj in update.data_objects:
self.widget.collTable.setItem(row, 0,
QtWidgets.QTableWidgetItem(os.path.dirname(obj.path)))
self.widget.collTable.setItem(row, 1, QtWidgets.QTableWidgetItem(obj.name))
self.widget.collTable.setItem(row, 2, QtWidgets.QTableWidgetItem(str(obj.size)))
self.widget.collTable.setItem(row, 3, QtWidgets.QTableWidgetItem(str(obj.checksum)))
self.widget.collTable.setItem(row, 4,
QtWidgets.QTableWidgetItem(str(obj.modify_time)))
row = row+1
self.widget.collTable.resizeColumnsToContents()
def browse(self, index):
self.widget.infoLabel.clear()
col = index.column()
row = index.row()
if self.widget.collTable.item(row, 0).text() != '':
path = self.widget.collTable.item(row, 0).text()
item = self.widget.collTable.item(row, 1).text()
if item.endswith('/'):
item = item[:-1]
if self.ic.session.collections.exists(path+'/'+item):
coll = self.ic.session.collections.get(path+'/'+item)
self.loadTable(update = coll)
......@@ -29,7 +29,7 @@ class mainmenu(QMainWindow):
if ic == None and ienv == None:
ticketAccessWidget = loadUi("gui/ui-files/tabTicketAccess.ui")
self.tabWidget.addTab(ticketAccessWidget, "Ticket Access")
self.ticketAccessTab = irodsTicketLogin()
self.ticketAccessTab = irodsTicketLogin(ticketAccessWidget)
else:
self.ic = ic
self.ienv = ienv
......
......@@ -36,34 +36,80 @@ QLineEdit
background-color: rgb(85, 87, 83);
}
QLabel#infoLabel
{
color: rgb(217, 174, 23);
}
</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Ticket:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Path</string>
<string>iRODS path: </string>
</property>
</widget>
</item>
<item row="0" column="1">
<item row="1" column="1">
<widget class="QLineEdit" name="ticketEdit"/>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="QLineEdit" name="pathEdit"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>iRODS server: </string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="serverEdit"/>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="connectButton">
<property name="text">
<string>Connect</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="infoLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
......@@ -81,7 +127,10 @@ background-color: rgb(85, 87, 83);
</spacer>
</item>
<item>
<widget class="QTableWidget" name="tableWidget">
<widget class="QTableWidget" name="collTable">
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
......@@ -101,6 +150,11 @@ background-color: rgb(85, 87, 83);
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Size</string>
</property>
</column>
<column>
<property name="text">
<string>Checksum</string>
......@@ -115,6 +169,17 @@ background-color: rgb(85, 87, 83);
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="homeButton">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>../icons/home.png</normaloff>../icons/home.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
......@@ -129,7 +194,14 @@ background-color: rgb(85, 87, 83);
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<widget class="QPushButton" name="downloadButton">
<property name="text">
<string>Download all</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="downloadSelectionButton">
<property name="text">
<string>Download selected</string>
</property>
......
from irods.session import iRODSSession
from irods.ticket import Ticket
from irods.exception import CollectionDoesNotExist
import os
from base64 import b64decode
from shutil import disk_usage
import hashlib
import logging
RED = '\x1b[1;31m'
DEFAULT = '\x1b[0m'
YEL = '\x1b[1;33m'
BLUE = '\x1b[1;34m'
class irodsConnectorAnonymous():
def __init__(self, host, ticket, path):
"""
iRODS anonymous login.
Input:
server: iRODS server
ticket: string
path: iRODS path the ticket grants access to
"""
self.__name__="irodsConnectorAnonymous"
if path.endswith('/'):
path = path[:-1]
if not path.startswith("/"):
raise Exception("Not a valid iRODS path.")
zone = path.split('/')[1]
self.session = iRODSSession(user='anonymous',
password='',
zone=zone,
port=1247,
host=host)
self.token = ticket
self.path = path
def getData(self):
ticket = Ticket(self.session, self.token)
ticket.supply()
try:
item = self.session.collections.get(self.path)
return item
except:
raise
def getUserInfo(self):
pass
def getPermissions(self, iPath):
pass
def setPermissions(self, rights, user, path, zone, recursive = False):
pass
def ensureColl(self, collPath):
pass
def search(self, keyVals = None):
pass
def listResources(self):
pass
def getResource(self, resource):
'''
Raises:
irods.exception.ResourceDoesNotExist
'''
return self.session.resources.get(resource)
def resourceSize(self, resource):
"""
Returns the available space left on a resource in bytes
resource: Name of the resource
Throws: ResourceDoesNotExist if resource not known
AttributeError if 'free_space' not set
"""
try:
size = self.session.resources.get(resource).free_space
return size
except Exception as error:
logging.info('RESOURCE ERROR: Either resource does not exist or size not set.',
exc_info=True)
raise error("RESOURCE ERROR: Either resource does not exist or size not set.")
def uploadData(self, source, destination, resource, size, buff = 1024**3,
force = False, diffs = []):
pass
def downloadData(self, source, destination, size, buff = 1024**3, force = False, diffs=[]):
'''
Download object or collection.
source: iRODS collection or data object
destination: absolute path to download folder
size: size of data to be downloaded in bytes
buff: buffer on resource that should be left over
force: If true, do not calculate storage capacity on destination
diffs: output of diff functions
'''
logging.info('iRODS DOWNLOAD: '+str(source)+'-->'+destination)
options = {kw.FORCE_FLAG_KW: '', kw.REG_CHKSUM_KW: ''}
if destination.endswith(os.sep):
destination = destination[:len(destination)-1]
if not os.path.isdir(destination):
logging.info('DOWNLOAD ERROR: destination path does not exist or is not directory',
exc_info=True)
raise FileNotFoundError(
"ERROR iRODS download: destination path does not exist or is not directory")
if not os.access(destination, os.W_OK):
logging.info('DOWNLOAD ERROR: No rights to write to destination.',
exc_info=True)
raise PermissionError("ERROR iRODS download: No rights to write to destination.")
if diffs == []:#Only download if not present or difference in files
if self.session.data_objects.exists(source.path):
(diff, onlyFS, onlyIrods, same) = self.diffObjFile(source.path,
os.path.join(
destination, os.path.basename(source.path)),
scope="checksum")
elif self.session.collections.exists(source.path):
subdir = os.path.join(destination, source.name)
if not os.path.isdir(os.path.join(destination, source.name)):
os.mkdir(os.path.join(destination, source.name))
(diff, onlyFS, onlyIrods, same) = self.diffIrodsLocalfs(
source, subdir, scope="checksum")
else:
raise FileNotFoundError("ERROR iRODS upload: not a valid source path")
else:
(diff, onlyFS, onlyIrods, same) = diffs
if not force:#Check space on destination
try:
space = disk_usage(destination).free
if int(size) > (int(space)-buff):
logging.info('DOWNLOAD ERROR: Not enough space on disk.',
exc_info=True)
raise ValueError('ERROR iRODS download: Not enough space on disk.')
if buff < 0:
logging.info('DOWNLOAD ERROR: Negative disk buffer.', exc_info=True)
raise BufferError('ERROR iRODS download: Negative disk buffer.')
except Exception as error:
logging.info('DOWNLOAD ERROR', exc_info=True)
raise error()
if self.session.data_objects.exists(source.path) and len(diff+onlyIrods) > 0:
try:
logging.info("IRODS DOWNLOADING object:"+ source.path+
"to "+ destination)
self.session.data_objects.get(source.path,
local_path=os.path.join(destination, source.name), **options)
return
except:
logging.info('DOWNLOAD ERROR: '+source.path+"-->"+destination,
exc_info=True)
raise
try: #collections/folders
subdir = os.path.join(destination, source.name)
logging.info("IRODS DOWNLOAD started:")
for d in diff:
#upload files to distinct data objects
logging.info("REPLACE: "+d[1]+" with "+d[0])
self.session.data_objects.get(d[0], local_path=d[1], **options)
for IO in onlyIrods: #can contain files and folders
#Create subcollections and upload
sourcePath = source.path + "/" + IO
locO = IO.replace("/", os.sep)
destPath = os.path.join(subdir, locO)
if not os.path.isdir(os.path.dirname(destPath)):
os.makedirs(os.path.dirname(destPath))
logging.info('INFO: Downloading '+sourcePath+" to "+destPath)
self.session.data_objects.get(sourcePath, local_path=destPath, **options)
except:
logging.info('DOWNLOAD ERROR', exc_info=True)
raise
def addMetadata(self, items, key, value, units = None):
pass
def updateMetadata(self, items, key, value, units = None):
pass
def deleteMetadata(self, items, key, value, units):
pass
def deleteData(self, item):
pass
def executeRule(self, ruleFile, params, output='ruleExecOut'):
pass
def createTicket(self, path, expiryString=""):
pass
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment