mirror of https://github.com/m-labs/artiq.git
browser: support uploading datasets to master. Closes #480
This commit is contained in:
parent
0173a40be0
commit
77f60a3e63
|
@ -1,10 +1,17 @@
|
||||||
|
import logging
|
||||||
|
import asyncio
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtWidgets
|
from PyQt5 import QtCore, QtWidgets
|
||||||
|
|
||||||
from artiq.tools import short_format
|
from artiq.tools import short_format
|
||||||
from artiq.gui.tools import LayoutWidget
|
from artiq.gui.tools import LayoutWidget
|
||||||
from artiq.gui.models import DictSyncTreeSepModel
|
from artiq.gui.models import DictSyncTreeSepModel
|
||||||
|
from artiq.protocols.pc_rpc import AsyncioClient as RPCClient
|
||||||
|
|
||||||
# reduced read-only version of artiq.gui.datasets
|
# reduced read-only version of artiq.dashboard.datasets
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Model(DictSyncTreeSepModel):
|
class Model(DictSyncTreeSepModel):
|
||||||
|
@ -16,7 +23,7 @@ class Model(DictSyncTreeSepModel):
|
||||||
|
|
||||||
|
|
||||||
class DatasetsDock(QtWidgets.QDockWidget):
|
class DatasetsDock(QtWidgets.QDockWidget):
|
||||||
def __init__(self, datasets_sub):
|
def __init__(self, datasets_sub, master_host, master_port):
|
||||||
QtWidgets.QDockWidget.__init__(self, "Datasets")
|
QtWidgets.QDockWidget.__init__(self, "Datasets")
|
||||||
self.setObjectName("Datasets")
|
self.setObjectName("Datasets")
|
||||||
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
|
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
|
||||||
|
@ -36,9 +43,17 @@ class DatasetsDock(QtWidgets.QDockWidget):
|
||||||
QtWidgets.QAbstractItemView.SingleSelection)
|
QtWidgets.QAbstractItemView.SingleSelection)
|
||||||
grid.addWidget(self.table, 1, 0)
|
grid.addWidget(self.table, 1, 0)
|
||||||
|
|
||||||
|
self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
||||||
|
upload_action = QtWidgets.QAction("Upload dataset to master", self.table)
|
||||||
|
upload_action.triggered.connect(self.upload_clicked)
|
||||||
|
self.table.addAction(upload_action)
|
||||||
|
|
||||||
self.set_model(Model(dict()))
|
self.set_model(Model(dict()))
|
||||||
datasets_sub.add_setmodel_callback(self.set_model)
|
datasets_sub.add_setmodel_callback(self.set_model)
|
||||||
|
|
||||||
|
self.master_host = master_host
|
||||||
|
self.master_port = master_port
|
||||||
|
|
||||||
def _search_datasets(self):
|
def _search_datasets(self):
|
||||||
if hasattr(self, "table_model_filter"):
|
if hasattr(self, "table_model_filter"):
|
||||||
self.table_model_filter.setFilterFixedString(
|
self.table_model_filter.setFilterFixedString(
|
||||||
|
@ -50,6 +65,31 @@ class DatasetsDock(QtWidgets.QDockWidget):
|
||||||
self.table_model_filter.setSourceModel(self.table_model)
|
self.table_model_filter.setSourceModel(self.table_model)
|
||||||
self.table.setModel(self.table_model_filter)
|
self.table.setModel(self.table_model_filter)
|
||||||
|
|
||||||
|
async def _upload_dataset(self, name, value,):
|
||||||
|
logger.info("Uploading dataset '%s' to master...", name)
|
||||||
|
try:
|
||||||
|
remote = RPCClient()
|
||||||
|
await remote.connect_rpc(self.master_host, self.master_port,
|
||||||
|
"master_dataset_db")
|
||||||
|
try:
|
||||||
|
await remote.set(name, value)
|
||||||
|
finally:
|
||||||
|
remote.close_rpc()
|
||||||
|
except:
|
||||||
|
logger.error("Failed uploading dataset '%s'",
|
||||||
|
name, exc_info=True)
|
||||||
|
else:
|
||||||
|
logger.info("Finished uploading dataset '%s'", name)
|
||||||
|
|
||||||
|
def upload_clicked(self):
|
||||||
|
idx = self.table.selectedIndexes()
|
||||||
|
if idx:
|
||||||
|
idx = self.table_model_filter.mapToSource(idx[0])
|
||||||
|
key = self.table_model.index_to_key(idx)
|
||||||
|
if key is not None:
|
||||||
|
persist, value = self.table_model.backing_store[key]
|
||||||
|
asyncio.ensure_future(self._upload_dataset(key, value))
|
||||||
|
|
||||||
def save_state(self):
|
def save_state(self):
|
||||||
return bytes(self.table.header().saveState())
|
return bytes(self.table.header().saveState())
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ from artiq.tools import verbosity_args, atexit_register_coroutine
|
||||||
from artiq.gui import state, applets, models, log
|
from artiq.gui import state, applets, models, log
|
||||||
from artiq.browser import datasets, files, experiments
|
from artiq.browser import datasets, files, experiments
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +31,13 @@ def get_argparser():
|
||||||
parser.add_argument("--browse-root", default="",
|
parser.add_argument("--browse-root", default="",
|
||||||
help="root path for directory tree "
|
help="root path for directory tree "
|
||||||
"(default %(default)s)")
|
"(default %(default)s)")
|
||||||
|
parser.add_argument(
|
||||||
|
"-s", "--server", default="::1",
|
||||||
|
help="hostname or IP of the master to connect to "
|
||||||
|
"when uploading datasets")
|
||||||
|
parser.add_argument(
|
||||||
|
"--port", default=3251, type=int,
|
||||||
|
help="TCP port to use to connect to the master")
|
||||||
parser.add_argument("select", metavar="SELECT", nargs="?",
|
parser.add_argument("select", metavar="SELECT", nargs="?",
|
||||||
help="directory to browse or file to load")
|
help="directory to browse or file to load")
|
||||||
verbosity_args(parser)
|
verbosity_args(parser)
|
||||||
|
@ -37,7 +45,8 @@ def get_argparser():
|
||||||
|
|
||||||
|
|
||||||
class Browser(QtWidgets.QMainWindow):
|
class Browser(QtWidgets.QMainWindow):
|
||||||
def __init__(self, datasets_sub, browse_root, select):
|
def __init__(self, datasets_sub, browse_root, select,
|
||||||
|
master_host, master_port):
|
||||||
QtWidgets.QMainWindow.__init__(self)
|
QtWidgets.QMainWindow.__init__(self)
|
||||||
|
|
||||||
icon = QtGui.QIcon(os.path.join(artiq_dir, "gui", "logo.svg"))
|
icon = QtGui.QIcon(os.path.join(artiq_dir, "gui", "logo.svg"))
|
||||||
|
@ -69,7 +78,8 @@ class Browser(QtWidgets.QMainWindow):
|
||||||
self.applets = applets.AppletsDock(self, datasets_sub)
|
self.applets = applets.AppletsDock(self, datasets_sub)
|
||||||
atexit_register_coroutine(self.applets.stop)
|
atexit_register_coroutine(self.applets.stop)
|
||||||
|
|
||||||
self.datasets = datasets.DatasetsDock(datasets_sub)
|
self.datasets = datasets.DatasetsDock(
|
||||||
|
datasets_sub, master_host, master_port)
|
||||||
|
|
||||||
self.log = log.LogDock(None, "log")
|
self.log = log.LogDock(None, "log")
|
||||||
self.log.setFeatures(self.log.DockWidgetMovable |
|
self.log.setFeatures(self.log.DockWidgetMovable |
|
||||||
|
@ -139,7 +149,8 @@ def main():
|
||||||
|
|
||||||
smgr = state.StateManager(args.db_file)
|
smgr = state.StateManager(args.db_file)
|
||||||
|
|
||||||
main_window = Browser(datasets_sub, args.browse_root, args.select)
|
main_window = Browser(datasets_sub, args.browse_root, args.select,
|
||||||
|
args.server, args.port)
|
||||||
widget_log_handler.callback = main_window.log.append_message
|
widget_log_handler.callback = main_window.log.append_message
|
||||||
smgr.register(main_window)
|
smgr.register(main_window)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue