browser: support uploading datasets to master. Closes #480

This commit is contained in:
Sebastien Bourdeauducq 2016-07-03 12:21:36 +08:00
parent 0173a40be0
commit 77f60a3e63
2 changed files with 56 additions and 5 deletions

View File

@ -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())

View File

@ -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)