-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR is related to #44.
- Loading branch information
Showing
15 changed files
with
773 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
--- | ||
name: Bug report | ||
about: Create a report to help us improve | ||
title: '' | ||
labels: bug | ||
assignees: '' | ||
|
||
--- | ||
|
||
### Describe the bug | ||
A clear and concise description of what the bug is. | ||
|
||
### Expected behavior | ||
A clear and concise description of what you expected to happen. | ||
|
||
### To Reproduce | ||
Steps to reproduce the behavior: | ||
1. Go to '...' | ||
2. Click on '....' | ||
3. Scroll down to '....' | ||
4. See error | ||
|
||
### Expected causes and correction methods | ||
Even if you don't know the exact reason, please write it down. | ||
|
||
### Screenshots | ||
If applicable, add screenshots to help explain your problem. | ||
|
||
### Additional context | ||
Add any other context about the problem here. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
--- | ||
name: Implement a new feature | ||
about: Create an article about the motivation and specification of a new feature | ||
title: '' | ||
labels: enhancement | ||
assignees: '' | ||
|
||
--- | ||
|
||
### Feature you want to implement | ||
What is the feature you want to implement? | ||
|
||
### How the feature is implemented | ||
ex) Add *B* method to *A* class, Upgrade *C* model | ||
|
||
### Additional context | ||
Add any other context or screenshots about the feature here. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: Pylint | ||
|
||
on: [push] | ||
|
||
env: | ||
QIWIS_VERSION: v2.0.2 | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
python-version: ["3.7", "3.8", "3.9", "3.10"] | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- name: Install dependencies | ||
run: | | ||
sudo apt-get update | ||
python -m pip install --upgrade pip | ||
pip install pylint | ||
- name: Add dependencies about external libraries | ||
run: | | ||
pip install pyqt5 | ||
pip install requests | ||
pip install git+https://github.com/snu-quiqcl/qiwis.git@${{ env.QIWIS_VERSION }} | ||
- name: Analyze the code with pylint | ||
run: | | ||
pylint iquip --report=y | ||
pylint tests --rcfile tests/.pylintrc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
name: Unit test | ||
|
||
on: [push] | ||
|
||
env: | ||
QIWIS_VERSION: v2.0.2 | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
python-version: ["3.7", "3.8", "3.9", "3.10"] | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- name: Install dependencies | ||
run: | | ||
sudo apt-get update | ||
python -m pip install --upgrade pip | ||
pip install coverage | ||
- name: Add dependencies about external libraries | ||
run: | | ||
pip install pyqt5 | ||
pip install requests | ||
sudo apt-get install python3-pyqt5 | ||
pip install git+https://github.com/snu-quiqcl/qiwis.git@${{ env.QIWIS_VERSION }} | ||
- name: Run the unit tests and check coverage | ||
run: | | ||
xvfb-run `which coverage` run -m unittest discover | ||
xvfb-run `which coverage` report --include="iquip/*.py" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[MASTER] | ||
extension-pkg-whitelist=PyQt5 | ||
|
||
[BASIC] | ||
argument-rgx=_?_?(?:(?:[a-z0-9]+(?:_[a-z0-9]+)*_?_?)|(?:[a-z0-9]+(?:[A-Z][a-z0-9]*)*))$ | ||
attr-rgx=_?_?(?:(?:[a-z0-9]+(?:_[a-z0-9]+)*_?_?)|(?:[a-z0-9]+(?:[A-Z][a-z0-9]*)*))$ | ||
method-rgx=_?_?(?:(?:[a-z0-9]+(?:_[a-z0-9]+)*_?_?)|(?:[a-z0-9]+(?:[A-Z][a-z0-9]*)*))$ | ||
variable-rgx=_?_?(?:(?:[a-z0-9]+(?:_[a-z0-9]+)*_?_?)|(?:[a-z0-9]+(?:[A-Z][a-z0-9]*)*))$ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
# iquip | ||
Ion trap Quantum computing User Interface Project | ||
|
||
[![Pylint](https://github.com/snu-quiqcl/iquip/actions/workflows/pylint.yml/badge.svg)](https://github.com/snu-quiqcl/iquip/actions/workflows/pylint.yml) | ||
[![Unit test](https://github.com/snu-quiqcl/iquip/actions/workflows/unittest.yml/badge.svg)](https://github.com/snu-quiqcl/iquip/actions/workflows/unittest.yml) |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
"""App module for showing the experiment list and opening an experiment.""" | ||
|
||
import posixpath | ||
from typing import Callable, List, Optional, Tuple, Union | ||
|
||
import requests | ||
from PyQt5.QtCore import QObject, Qt, QThread, pyqtSlot, pyqtSignal | ||
from PyQt5.QtWidgets import ( | ||
QPushButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget | ||
) | ||
|
||
import qiwis | ||
|
||
class ExplorerFrame(QWidget): | ||
"""Frame for showing the experiment list and opening an experiment. | ||
Attributes: | ||
fileTree: The tree widget for showing the file structure. | ||
reloadButton: The buttont for reloading the fileTree. | ||
openButton: The button for opening the selected experiment file. | ||
""" | ||
|
||
def __init__(self, parent: Optional[QWidget] = None): | ||
"""Extended.""" | ||
super().__init__(parent=parent) | ||
# widgets | ||
self.fileTree = QTreeWidget(self) | ||
self.fileTree.header().setVisible(False) | ||
self.reloadButton = QPushButton("Reload", self) | ||
self.openButton = QPushButton("Open", self) | ||
# layout | ||
layout = QVBoxLayout(self) | ||
layout.addWidget(self.reloadButton) | ||
layout.addWidget(self.fileTree) | ||
layout.addWidget(self.openButton) | ||
|
||
|
||
class _FileFinderThread(QThread): | ||
"""QThread for finding the file list using a command line. | ||
Signals: | ||
fetched(experimentList, widget): The file list is fetched. | ||
Attributes: | ||
path: The path of the directory to search for experiment files. | ||
widget: The widget corresponding to the path. | ||
""" | ||
|
||
fetched = pyqtSignal(list, object) | ||
|
||
def __init__( | ||
self, | ||
path: str, | ||
widget: Union[QTreeWidget, QTreeWidgetItem], | ||
callback: Callable[[List[str], Union[QTreeWidget, QTreeWidgetItem]], None], | ||
parent: Optional[QObject] = None | ||
): | ||
"""Extended. | ||
Args: | ||
path, widget: See the attributes section in _FileFinderThread. | ||
callback: The callback method called after this thread is finished. | ||
""" | ||
super().__init__(parent=parent) | ||
self.path = path | ||
self.widget = widget | ||
self.fetched.connect(callback, type=Qt.QueuedConnection) | ||
|
||
def run(self): | ||
"""Overridden. | ||
Fetches the file list using a command line. | ||
Searches for only files in path, not in deeper path and adds them into the widget. | ||
After finished, the fetched signal is emitted. | ||
""" | ||
try: | ||
response = requests.get("http://127.0.0.1:8000/ls/", | ||
params={"directory": self.path}, | ||
timeout=10) | ||
response.raise_for_status() | ||
experimentList = response.json() | ||
except requests.exceptions.RequestException as err: | ||
print(err) | ||
return | ||
self.fetched.emit(experimentList, self.widget) | ||
|
||
|
||
class ExplorerApp(qiwis.BaseApp): | ||
"""App for showing the experiment list and opening an experiment. | ||
Attributes: | ||
explorerFrame: The frame that shows the file tree. | ||
thread: The _FileFinderThread object. | ||
""" | ||
|
||
def __init__(self, name: str, parent: Optional[QObject] = None): | ||
"""Extended.""" | ||
super().__init__(name, parent=parent) | ||
self.explorerFrame = ExplorerFrame() | ||
self.loadFileTree() | ||
# connect signals to slots | ||
self.explorerFrame.fileTree.itemExpanded.connect(self.lazyLoadFile) | ||
self.explorerFrame.reloadButton.clicked.connect(self.loadFileTree) | ||
self.explorerFrame.openButton.clicked.connect(self.openExperiment) | ||
|
||
@pyqtSlot() | ||
def loadFileTree(self): | ||
"""Loads the experiment file structure in self.explorerFrame.fileTree.""" | ||
self.explorerFrame.fileTree.clear() | ||
self.thread = _FileFinderThread( | ||
".", | ||
self.explorerFrame.fileTree, | ||
self._addFile, | ||
self | ||
) | ||
self.thread.start() | ||
|
||
@pyqtSlot(QTreeWidgetItem) | ||
def lazyLoadFile(self, experimentFileItem: QTreeWidgetItem): | ||
"""Loads the experiment file in the directory. | ||
This will be called when a directory item is expanded, | ||
so it makes loading files lazy. | ||
Args: | ||
experimentFileItem: The expanded file item. | ||
""" | ||
if experimentFileItem.childCount() != 1 or experimentFileItem.child(0).columnCount() != 0: | ||
return | ||
# Remove the empty item of an unloaded directory. | ||
experimentFileItem.takeChild(0) | ||
experimentPath = self.fullPath(experimentFileItem) | ||
self.thread = _FileFinderThread( | ||
experimentPath, | ||
experimentFileItem, | ||
self._addFile, | ||
self | ||
) | ||
self.thread.start() | ||
|
||
def _addFile(self, experimentList: List[str], widget: Union[QTreeWidget, QTreeWidgetItem]): | ||
"""Adds the files into the children of the widget. | ||
A file or directory which starts with "_" will be ignored, e.g. __pycache__/. | ||
Args: | ||
experimentList: The list of files under the widget path. | ||
widget: See _FileFinderThread class. | ||
""" | ||
for experimentFile in experimentList: | ||
if experimentFile.startswith("_"): | ||
continue | ||
if experimentFile.endswith("/"): | ||
experimentFileItem = QTreeWidgetItem(widget) | ||
experimentFileItem.setText(0, experimentFile[:-1]) | ||
# Make an empty item for indicating that it is a directory. | ||
QTreeWidgetItem(experimentFileItem) | ||
elif experimentFile.endswith(".py"): | ||
experimentFileItem = QTreeWidgetItem(widget) | ||
experimentFileItem.setText(0, experimentFile) | ||
|
||
@pyqtSlot() | ||
def openExperiment(self): | ||
"""Opens the experiment builder of the selected experiment. | ||
Once the openButton is clicked, this is called. | ||
If the selected element is a directory, it will be ignored. | ||
TODO(BECATRUE): Open the experiment builder. It will be implemented in Basic Runner project. | ||
""" | ||
experimentFileItem = self.explorerFrame.fileTree.currentItem() | ||
experimentPath = self.fullPath(experimentFileItem) # pylint: disable=unused-variable | ||
|
||
def fullPath(self, experimentFileItem: QTreeWidgetItem) -> str: | ||
"""Finds the full path of the file item and returns it. | ||
Args: | ||
experimentFileItem: The file item to get its full path. | ||
""" | ||
paths = [experimentFileItem.text(0)] | ||
while experimentFileItem.parent(): | ||
experimentFileItem = experimentFileItem.parent() | ||
paths.append(experimentFileItem.text(0)) | ||
return posixpath.join(*reversed(paths)) | ||
|
||
def frames(self) -> Tuple[ExplorerFrame]: | ||
"""Overridden.""" | ||
return (self.explorerFrame,) |
Oops, something went wrong.