Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move to a package #151

Merged
merged 7 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
irods-basicGUI/logs/*
irods-iBridgesGui.spec
*DS_Store

ibridgesgui/_version.py

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
94 changes: 53 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,55 +10,67 @@

## About

The git repository contains a generic *iRODS* graphical user interface and the corresponding command-line interface clients. The GUI and CLI work with any *iRODS* instance. However, for user and data security we depend on some *iRODS* event hooks that need to be installed on the *iRODS* server. Please refer to the documentation below.
The git repository contains a generic *iRODS* graphical user interface. The iRODS functioality is based on [ibridges](https://github.com/UtrechtUniversity/iBridges) and works with any *iRODS* instance.



## Highlights

- Works on Windows, Mac OS and Linux
- Runs on Python 3.9 or higher.
- Supported iRODS server versions: 4.2.11 or higher and 4.3.0 or higher.
- **Upload** and **Download** your data.
- Manipulate the **metadata** on the iRODS server.
- **Synchronize** your data between your local computer and the iRODS server.
- **Search** through all metadata for your dataset or collection.
- Safe default options when working with your data.

## Installation
- As python package

```bash
pip install ibridges
pip install git+https://github.com/chStaiger/iBridges-Gui.git@develop
```
- Locally from code (for developers)

```bash
git clone git@github.com:chStaiger/iBridges-Gui.git
cd iBridges-Gui
pip install .
```

## Start the GUI
- From a pip python package

```bash
ibridges-gui
```
- From code (for developers)

```bash
python ibridgesgui/__main__.py
```



## Authors
**Christine Staiger (Maintainer) [ORCID](https://orcid.org/0000-0002-6754-7647)**

Tim van Daalen, Christine Staiger
- *Wageningen University & Research* 2021 - 2022
- *Utrecht University* 2022

Wageningen University & Research 2021
**Tim van Daalen**, *Wageningen University & Research* 2021

## Contributors

J.P. Mc Farland

University of Groningen, Center for Information Technology, 2022

## Dependencies

### Supported iRODS versions

- 4.2.11, 4.2.12
- 4.3.0

### Python
**Maarten Schermer (Maintainer) [ORCID](https://orcid.org/my-orcid?orcid=0000-0001-6770-3155)**, *Utrecht University* 2023

- Python 3 (>= 3.9)
- Tested with python versions 3.9 and 3.10 on Windows, Ubuntu20.22 and MacOs
- pip-22.2.2
- Python packages (see install via `requirements.txt` below)
**Raoul Schram (Maintainer) [ORCID](https://orcid.org/my-orcid?orcid=0000-0001-6616-230X)**.
*Utrecht University* 2023

Install dependencies with, for example:

```sh
python3.10 -m pip install -r requirements.txt
```
### icommands (optional)
If the icommands are installed, the users can choose them as backend for up and downloads.

## Usage
```
export PYTHON_IRODSCLIENT_DEFAULT_XML=QUASI_XML
./iBridges.py
```



Please consult the documentation for more information about the configuration:

## Contributors

<p align="center">
<a href="https://chstaiger.github.io/iBridges-Gui/docs/getting-started.html#configuration"><strong> iBridges Configuration »</strong></a> .
**J.P. Mc Farland**,
*University of Groningen, Center for Information Technology*, 2022

## Contributing
### Code
Expand Down
12 changes: 7 additions & 5 deletions gui/IrodsExampleTab.py → ibridgesgui/IrodsExampleTab.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import logging
import sys

import meta
import PyQt6.QtCore
import PyQt6.QtGui
import PyQt6.QtWidgets
import PyQt6.uic

import gui
import meta
import utils
from gui.irodsTreeView import IrodsModel

import ibridgesgui as gui
from ibridgesgui.gui_utils import UI_FILE_DIR
from ibridgesgui.irodsTreeView import IrodsModel


class IrodsExampleTab(PyQt6.QtWidgets.QWidget,
gui.ui_files.ExampleTab.Ui_ExampleTab):
Expand All @@ -19,7 +21,7 @@ def __init__(self):
if getattr(sys, 'frozen', False):
super().setupUi(self)
else:
PyQt6.uic.loadUi("gui/ui_files/ExampleTab.ui", self)
PyQt6.uic.loadUi(UI_FILE_DIR / "ExampleTab.ui", self)
self.error_label.setText("Whooohoo")

self.ienv_dict = self.context.irods_environment.config
Expand Down
9 changes: 5 additions & 4 deletions gui/IrodsInfo.py → ibridgesgui/IrodsInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import PyQt6
import PyQt6.QtWidgets
import PyQt6.uic

from ibridges.resources import Resources
import gui
from gui.gui_utils import populate_table

import ibridgesgui as gui
from ibridgesgui.gui_utils import UI_FILE_DIR, populate_table


class IrodsInfo(PyQt6.QtWidgets.QWidget,
gui.ui_files.tabInfo.Ui_tabInfo):
Expand All @@ -22,7 +23,7 @@ def __init__(self, session):
if getattr(sys, 'frozen', False):
super().setupUi(self)
else:
PyQt6.uic.loadUi("gui/ui_files/tabInfo.ui", self)
PyQt6.uic.loadUi(UI_FILE_DIR / "tabInfo.ui", self)
self.session = session

self.refreshButton.clicked.connect(self.refresh_info)
Expand Down
10 changes: 6 additions & 4 deletions gui/IrodsLogin.py → ibridgesgui/IrodsLogin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
import sys
from pathlib import Path

from ibridges import Session
from ibridges.session import LoginError, PasswordError
from PyQt6.QtWidgets import QDialog, QLineEdit
from PyQt6.uic import loadUi

from gui.ui_files.irodsLogin import Ui_irodsLogin
from ibridges import Session
from ibridges.session import LoginError, PasswordError
from ibridgesgui.gui_utils import UI_FILE_DIR
from ibridgesgui.ui_files.irodsLogin import Ui_irodsLogin


class IrodsLogin(QDialog, Ui_irodsLogin):
"""Definition and initialization of the iRODS login window.
Expand All @@ -20,7 +22,7 @@ def __init__(self, session_dict):
if getattr(sys, 'frozen', False):
super().setupUi(self)
else:
loadUi("gui/ui_files/irodsLogin.ui", self)
loadUi(UI_FILE_DIR / "irodsLogin.ui", self)

self.session_dict = session_dict
self.irods_path = Path('~', '.irods').expanduser()
Expand Down
File renamed without changes.
File renamed without changes.
17 changes: 8 additions & 9 deletions iBridges.py → ibridgesgui/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
"""iBridges GUI startup script."""
import os
import sys
import setproctitle

import PyQt6.QtWidgets
import PyQt6.uic
import setproctitle

from gui import ui_files
from gui.info import Info
from gui.login import Login
from gui.browser import Browser
from ibridgesgui import ui_files
from ibridgesgui.browser import Browser
from ibridgesgui.gui_utils import UI_FILE_DIR
from ibridgesgui.info import Info
from ibridgesgui.login import Login

# Global constants
THIS_APPLICATION = 'iBridges-GUI'
Expand All @@ -30,7 +31,7 @@ def __init__(self, widget):
if getattr(sys, 'frozen', False):
super().setupUi(self)
else:
PyQt6.uic.loadUi('gui/ui_files/MainMenu.ui', self)
PyQt6.uic.loadUi(UI_FILE_DIR/'MainMenu.ui', self)

self.ui_tabs_lookup = {
'tabBrowser': self.init_browser_tab,
Expand Down Expand Up @@ -100,9 +101,7 @@ def init_browser_tab(self):
self.tabWidget.addTab(self.irods_browser, "Browser")

def main():
"""Main function

"""
"""Main function"""
# Initialize logger first because Context may want to log as well.
application_name = THIS_APPLICATION
setproctitle.setproctitle(application_name)
Expand Down
21 changes: 13 additions & 8 deletions gui/browser.py → ibridgesgui/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,24 @@
import PyQt6.QtGui
import PyQt6.QtWidgets
import PyQt6.uic

from ibridges import get_collection, get_dataobject
from ibridges import upload, download
from ibridges import IrodsPath
from ibridges import IrodsPath, download, get_collection, get_dataobject, upload
from ibridges.data_operations import obj_replicas
from ibridges.meta import MetaData
from ibridges.permissions import Permissions

import gui.popup_widgets
from gui.gui_utils import populate_table, get_irods_item, get_coll_dict, get_downloads_dir
import ibridgesgui as gui
import ibridgesgui.popup_widgets
from ibridgesgui.gui_utils import (
UI_FILE_DIR,
get_coll_dict,
get_downloads_dir,
get_irods_item,
populate_table,
)


class Browser(PyQt6.QtWidgets.QWidget,
gui.ui_files.tabBrowser.Ui_tabBrowser):
gui.ui_files.tabBrowser.Ui_tabBrowser):
"""Browser view for iRODS session.

"""
Expand All @@ -32,7 +37,7 @@ def __init__(self, session):
if getattr(sys, 'frozen', False):
super().setupUi(self)
else:
PyQt6.uic.loadUi("gui/ui_files/tabBrowser.ui", self)
PyQt6.uic.loadUi(UI_FILE_DIR / "tabBrowser.ui", self)

self.session = session
self.viewTabs.setCurrentIndex(0)
Expand Down
12 changes: 7 additions & 5 deletions gui/checkableFsTree.py → ibridgesgui/checkableFsTree.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from PyQt6.QtWidgets import QFileIconProvider, QMessageBox
from PyQt6.QtCore import QFile, Qt, QDir
from PyQt6.QtGui import QFileSystemModel, QStandardItemModel, QStandardItem
from sys import platform
from time import sleep
import logging
import os
from sys import platform
from time import sleep

from PyQt6.QtCore import QDir, QFile, Qt
from PyQt6.QtGui import QFileSystemModel, QStandardItem, QStandardItemModel
from PyQt6.QtWidgets import QFileIconProvider, QMessageBox


# a class to put checkbox on the folders and record which ones are checked.
class checkableFsTreeModel(QFileSystemModel):
Expand Down
10 changes: 7 additions & 3 deletions gui/gui_utils.py → ibridgesgui/gui_utils.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
"""Handy and reusable functions for the GUI"""
import PyQt6
import irods
import pathlib
from importlib.resources import files

import irods
import PyQt6
from ibridges import get_collection, get_dataobject

UI_FILE_DIR = files(__package__) / "ui_files"


def populate_table(tableWidget, rows, data_by_row):

tableWidget.setRowCount(rows)
for row, data in enumerate(data_by_row):
for col, item in enumerate(data):
tableWidget.setItem(row, col, PyQt6.QtWidgets.QTableWidgetItem(str(item)))
tableWidget.resizeColumnsToContents()
tableWidget.resizeColumnsToContents()

def get_irods_item(irods_path):
try:
Expand Down
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
9 changes: 5 additions & 4 deletions gui/info.py → ibridgesgui/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import PyQt6
import PyQt6.QtWidgets
import PyQt6.uic

from ibridges.resources import Resources
import gui
from gui.gui_utils import populate_table

import ibridgesgui as gui
from ibridgesgui.gui_utils import populate_table, UI_FILE_DIR


class Info(PyQt6.QtWidgets.QWidget, gui.ui_files.tabInfo.Ui_tabInfo):
"""Set iRODS information in the GUI"""
Expand All @@ -19,7 +20,7 @@ def __init__(self, session):
if getattr(sys, 'frozen', False):
super().setupUi(self)
else:
PyQt6.uic.loadUi("gui/ui_files/tabInfo.ui", self)
PyQt6.uic.loadUi(UI_FILE_DIR / "tabInfo.ui", self)
self.session = session

self.refreshButton.clicked.connect(self.refresh_info)
Expand Down
9 changes: 5 additions & 4 deletions gui/irodsSearch.py → ibridgesgui/irodsSearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
import os
import sys

from PyQt6 import QtWidgets, QtGui, QtCore
import utils
from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtWidgets import QDialog, QMessageBox
from PyQt6.uic import loadUi

from gui.ui_files.searchDialog import Ui_searchDialog
import utils
from ibridgesgui.gui_utils import UI_FILE_DIR
from ibridgesgui.ui_files.searchDialog import Ui_searchDialog


class irodsSearch(QDialog, Ui_searchDialog):
Expand All @@ -32,7 +33,7 @@ def __init__(self, collTable):
if getattr(sys, 'frozen', False):
super().setupUi(self)
else:
loadUi("gui/ui_files/searchDialog.ui", self)
loadUi(UI_FILE_DIR / "searchDialog.ui", self)

self.conn = self.context.irods_connector

Expand Down
1 change: 0 additions & 1 deletion gui/irodsTreeView.py → ibridgesgui/irodsTreeView.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import PyQt6.QtCore
import PyQt6.QtGui
import PyQt6.QtWidgets

import utils

ACCESS_NAMES = [
Expand Down
Loading