Commit e9bcb841 authored by Samuel GAIST's avatar Samuel GAIST
Browse files

[widgets][editor] Implement support for creating new assets

That can be one or more of:
- New
- New version
- Fork

It depends on the asset type.
parent 8878ac44
......@@ -32,6 +32,7 @@ from PyQt5 import QtCore
from PyQt5.QtWidgets import QMessageBox
from ..widgets.assetwidget import AssetWidget
from ..widgets.dialogs import AssetCreationDialog
from ..widgets.editor import PlaceholderEditor
from ..widgets.algorithmeditor import AlgorithmEditor
......@@ -45,6 +46,7 @@ from ..widgets.protocoltemplateeditor import ProtocolTemplateEditor
from ..widgets.toolchaineditor import ToolchainEditor
from ..backend.assetmodel import AssetType
from ..backend.assetmodel import AssetModel
@pytest.fixture()
......@@ -157,3 +159,125 @@ class TestAssetWidget:
with open(asset_path, "rt") as json_file:
json_data = json.loads(json_file.read())
assert json_data[description_key] == description
def test_new(self, qtbot, monkeypatch, test_prefix, beat_context, asset_type):
if asset_type.can_create():
asset_widget = AssetWidget()
qtbot.addWidget(asset_widget)
asset_widget.set_context(beat_context)
asset_name = "test_name"
user = beat_context.meta["config"].user
monkeypatch.setattr(
AssetCreationDialog,
"getAssetInfo",
classmethod(
lambda *args, **kwargs: (True, AssetCreationDialog.NEW, asset_name)
),
)
asset_widget.editors_type[asset_type].create_action.trigger()
asset_model = AssetModel()
asset_model.asset_type = asset_type
asset_model.prefix_path = test_prefix
if asset_type.split_count() == 2:
target_name = f"{user}/{asset_name}/1"
else:
target_name = f"{asset_name}/1"
assert target_name in asset_model.stringList()
assert os.path.exists(asset_model.json_path(target_name))
def test_new_version(
self,
qtbot,
monkeypatch,
test_prefix,
beat_context,
asset_type,
asset_type_prefix_entry_map,
):
if asset_type.can_create():
asset_widget = AssetWidget()
qtbot.addWidget(asset_widget)
asset_widget.set_context(beat_context)
asset_name = asset_type_prefix_entry_map[asset_type][0]
monkeypatch.setattr(
AssetCreationDialog,
"getAssetInfo",
classmethod(
lambda *args, **kwargs: (
True,
AssetCreationDialog.NEW_VERSION,
asset_name,
)
),
)
asset_widget.editors_type[asset_type].create_action.trigger()
asset_model = AssetModel()
asset_model.asset_type = asset_type
asset_model.prefix_path = test_prefix
if asset_type.split_count() == 2:
user_name, name, version = asset_name.split("/")
target_name = f"{user_name}/{name}/{int(version) + 1}"
else:
name, version = asset_name.split("/")
target_name = f"{name}/{int(version) + 1}"
assert target_name in asset_model.stringList()
assert os.path.exists(asset_model.json_path(target_name))
def test_fork(
self,
qtbot,
monkeypatch,
test_prefix,
beat_context,
asset_type,
asset_type_prefix_entry_map,
):
if asset_type.can_fork():
asset_widget = AssetWidget()
qtbot.addWidget(asset_widget)
asset_widget.set_context(beat_context)
asset_name = asset_type_prefix_entry_map[asset_type][0]
target_name = "forked"
user = beat_context.meta["config"].user
monkeypatch.setattr(
AssetCreationDialog,
"getAssetInfo",
classmethod(
lambda *args, **kwargs: (
True,
AssetCreationDialog.FORK,
(asset_name, target_name),
)
),
)
asset_widget.editors_type[asset_type].create_action.trigger()
asset_model = AssetModel()
asset_model.asset_type = asset_type
asset_model.prefix_path = test_prefix
if asset_type.split_count() == 2:
user_name, name, version = asset_name.split("/")
target_name = f"{user}/{target_name}/{version}"
elif asset_type.split_count() == 1:
name, version = asset_name.split("/")
target_name = f"{target_name}/{version}"
else:
items = asset_name.split("/")
items[0] = user
items[4] = target_name
target_name = "/".join(items)
assert target_name in asset_model.stringList()
assert os.path.exists(asset_model.json_path(target_name))
......@@ -23,6 +23,8 @@
# #
###############################################################################
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtWidgets import QComboBox
from PyQt5.QtWidgets import QDialog
from PyQt5.QtWidgets import QDialogButtonBox
......@@ -43,6 +45,18 @@ class CreationType:
def __init__(self, **kwds):
super().__init__(**kwds)
@staticmethod
def typeToString(type_):
text = QCoreApplication.translate("CreationType", "Unknown")
if type_ == CreationType.NEW:
text = QCoreApplication.translate("CreationType", "New")
elif type_ == CreationType.NEW_VERSION:
text = QCoreApplication.translate("CreationType", "New version")
elif type_ == CreationType.FORK:
text = QCoreApplication.translate("CreationType", "Fork")
return text
class AssetCreationDialog(QDialog, CreationType):
def __init__(self, context, asset_type, parent=None):
......
......@@ -28,15 +28,19 @@ import simplejson as json
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtCore import pyqtProperty
from PyQt5.QtWidgets import QAction
from PyQt5.QtWidgets import QFormLayout
from PyQt5.QtWidgets import QGroupBox
from PyQt5.QtWidgets import QLabel
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QVBoxLayout
from ..backend.assetmodel import AssetType
from .dialogs import AssetCreationDialog
class AbstractAssetEditor(QWidget):
"""Base class for BEAT asset editors"""
......@@ -61,6 +65,9 @@ class AbstractAssetEditor(QWidget):
self.schema_version = None
self.clear_dirty()
self.create_action = QAction("{}".format(asset_type.name.title()))
self.title_label = QLabel(self.tr("Unknown"))
self.description_lineedit = QLineEdit()
......@@ -75,6 +82,7 @@ class AbstractAssetEditor(QWidget):
layout.addWidget(self.title_label)
layout.addWidget(self.information_group_box)
self.create_action.triggered.connect(self._create_new_asset)
self.description_lineedit.textChanged.connect(self.dataChanged)
self.dataChanged.connect(self.set_dirty)
......@@ -97,6 +105,54 @@ class AbstractAssetEditor(QWidget):
widget.setVisible(visible)
self.information_layout.labelForField(widget).setVisible(visible)
def _create_new_asset(self):
"""Implement whatever is needed to create a new asset managed by this editor"""
ok_pressed, creation_type, asset_info = AssetCreationDialog.getAssetInfo(
self, self.context, self.asset_type
)
if ok_pressed:
user = self.context.meta["config"].user
if creation_type == AssetCreationDialog.NEW:
if self.asset_type.split_count() == 1:
asset_name = f"{asset_info}/1"
else:
asset_name = f"{user}/{asset_info}/1"
status = self.asset_type.create_new(self.prefix_path, asset_name)
elif creation_type == AssetCreationDialog.NEW_VERSION:
status = self.asset_type.create_new_version(
self.prefix_path, asset_info
)
else:
source_asset, target_name = asset_info
if self.asset_type.split_count() == 1:
name, version = source_asset.split("/")
target_asset = f"{target_name}/{version}"
elif self.asset_type.split_count() == 2:
name, version = source_asset.split("/")[-2:]
target_asset = f"{user}/{target_name}/{version}"
else:
items = source_asset.split("/")
items[0] = user
items[4] = target_name
target_asset = "/".join(items)
status = self.asset_type.fork(
self.prefix_path, source_asset, target_asset
)
if not status:
QMessageBox.critical(
self,
self.tr("Error occurred"),
self.tr(
"The {} operation failed".format(
AssetCreationDialog.typeToString(creation_type)
)
),
)
def _load_json(self, json_object):
"""To be implemented by subclass to load their specific JSON parts"""
......@@ -198,6 +254,7 @@ class PlaceholderEditor(AbstractAssetEditor):
super(PlaceholderEditor, self).__init__(AssetType.UNKNOWN, parent)
self.set_title(self.tr("Nothing to edit"))
self.information_group_box.hide()
self.create_action = None
def _load_json(self, json_object):
"""Re-imp. Does nothing"""
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment