Skip to content

Commit

Permalink
[cuegui] MonitorCue displays all jobs/groups to move. (#979)
Browse files Browse the repository at this point in the history
  • Loading branch information
roulaoregan-spi committed May 11, 2022
1 parent 02cb67f commit 596088e
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 51 deletions.
125 changes: 98 additions & 27 deletions cuegui/cuegui/CueJobMonitorTree.py
Expand Up @@ -22,6 +22,7 @@

from builtins import str
from builtins import map
from collections import namedtuple
import time

from PySide2 import QtCore
Expand All @@ -43,6 +44,7 @@


logger = cuegui.Logger.getLogger(__file__)
Body = namedtuple("Body", "group_names, group_ids, job_names, job_ids")

COLUMN_COMMENT = 1
COLUMN_EAT = 2
Expand Down Expand Up @@ -291,35 +293,23 @@ def dropEvent(self, event):
if item and item.type() in (cuegui.Constants.TYPE_ROOTGROUP, cuegui.Constants.TYPE_GROUP):
job_ids = cuegui.Utils.dropEvent(event, "application/x-job-ids")
group_ids = cuegui.Utils.dropEvent(event, "application/x-group-ids")
job_names = cuegui.Utils.dropEvent(event, "application/x-job-names")
group_names = cuegui.Utils.dropEvent(event, "application/x-group-names")

if job_ids or group_ids:
body = ""
if group_ids:
body += "Groups:\n" + "\n".join(
cuegui.Utils.dropEvent(event, "application/x-group-names"))
if group_ids and job_ids:
body += "\n\n"
if job_ids:
body += "Jobs:\n" + "\n".join(
cuegui.Utils.dropEvent(event, "application/x-job-names"))

result = QtWidgets.QMessageBox.question(
self,
"Move groups/jobs?",
"Move the following into the group: " +
"\"%s\"?\n\n%s" % (
item.rpcObject.data.name, body),
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)

if result == QtWidgets.QMessageBox.Yes:
if job_ids:
jobs = [opencue.api.getJob(id_) for id_ in job_ids]
item.rpcObject.asGroup().reparentJobs(jobs)

if group_ids:
item.rpcObject.asGroup().reparentGroupIds(group_ids)

self.updateRequest()
body_content = Body(group_names=group_names,
group_ids=group_ids,
job_names=job_names,
job_ids=job_ids)

dialog = MoveDialog(title="Move Groups/Jobs",
text="Move the following into the group: %s?" \
% item.rpcObject.data.name,
event_item=item,
items=body_content,
dist_groups={},
parent=self)
dialog.exec_()

def addShow(self, show, update=True):
"""Adds a show to the list of monitored shows
Expand Down Expand Up @@ -812,3 +802,84 @@ def data(self, col, role):
return self._cache.get("FST", cuegui.Constants.QVARIANT_NULL)

return cuegui.Constants.QVARIANT_NULL


class MoveDialog(QtWidgets.QDialog):
"""
A dialog for moving selected Jobs/Groups into another Group
"""
def __init__(self, title, text, event_item, items, dst_groups,
send_to_groups=False, parent=None):
"""
Initializes the list of jobs/groups to move
@type title: str
@param title: Window Title
@type text: str
@param text: Confirmation question to the user
@type event_item: rpcObject
@param event_item: the rpcObject to act on
@type items: namedtuple
@param items: object that holds job_ids, group_ids, group_names, job_names to act on
@type dst_groups: dict
@param dst_groups: dict of destination groups to move jobs/groups to
@type parent: AbstractTreeWidget
@param parent: The dialog's parent
"""
QtWidgets.QDialog.__init__(self, parent)
self.parent = parent
self.items = items
self.event_item = event_item
self.send_to_groups = send_to_groups
self.dst_groups = dst_groups
_btn_accept = QtWidgets.QPushButton("Ok", self)
_btn_cancel = QtWidgets.QPushButton("Cancel", self)
_label_text = QtWidgets.QLabel(text, self)
_label_text.setWordWrap(True)

_vlayout = QtWidgets.QVBoxLayout(self)
_vlayout.addWidget(_label_text)

self._listView = QtWidgets.QListView(self)
_vlayout.addWidget(self._listView)
_model = QtGui.QStandardItemModel(self._listView)
self.setWindowTitle(title)
for item in self.items.job_names:
standard_item = QtGui.QStandardItem(item)
_model.appendRow(standard_item)
for item in self.items.group_names:
_standard_item = QtGui.QStandardItem(item)
_model.appendRow(_standard_item)
self._listView.setModel(_model)

if self.send_to_groups:
self.combo = QtWidgets.QComboBox(self)
self.combo.addItems(sorted(self.dst_groups.keys()))
self.layout().addWidget(self.combo)

_hlayout = QtWidgets.QHBoxLayout()
_hlayout.addWidget(_btn_accept)
_hlayout.addWidget(_btn_cancel)
_vlayout.addLayout(_hlayout)

self.connect(_btn_accept,
QtCore.SIGNAL("clicked()"),
self.move_items)
self.connect(_btn_cancel,
QtCore.SIGNAL("clicked()"),
self.reject)

def move_items(self):
"""Reparent jobs to new group"""

if not self.send_to_groups:
if self.items.job_ids:
jobs = [opencue.api.getJob(id_) for id_ in self.items.job_ids]
self.event_item.rpcObject.asGroup().reparentJobs(jobs)

if self.items.group_ids:
self.event_item.rpcObject.asGroup().reparentGroupIds(self.items.group_ids)
self.parent.updateRequest()
else:
selected_group = self.combo.currentText()
self.dst_groups[str(selected_group)].reparentJobs(self.items.job_ids)
self.accept()
26 changes: 15 additions & 11 deletions cuegui/cuegui/MenuActions.py
Expand Up @@ -594,17 +594,21 @@ def sendToGroup(self, rpcObjects=None):
return

title = "Send jobs to group"
groups = {
group.data.name: group for group in opencue.api.findShow(jobs[0].data.show).getGroups()}
body = "What group should these jobs move to?\n" + \
"\n".join([job.data.name for job in jobs])

(group, choice) = QtWidgets.QInputDialog.getItem(
self._caller, title, body, sorted(groups.keys()), 0, False)
if not choice:
return

groups[str(group)].reparentJobs(jobs)
groups = {group.data.name: group for group in opencue.api.findShow(
jobs[0].data.show).getGroups()}

body_content = cuegui.CueJobMonitorTree.Body(group_names=[],
group_ids=[],
job_names=[job.name() for job in jobs],
job_ids=jobs)

dialog = cuegui.CueJobMonitorTree.MoveDialog(title=title,
text="What group should these jobs move to?",
event_item=None,
items=body_content,
dst_groups=groups,
send_to_groups=True)
dialog.exec_()
self._update()

useLocalCores_info = [
Expand Down
47 changes: 34 additions & 13 deletions cuegui/tests/MenuActions_tests.py
Expand Up @@ -445,34 +445,55 @@ def test_unbook(self, unbookDialogMock):
unbookDialogMock.assert_called_with(jobs, self.widgetMock)
unbookDialogMock.return_value.exec_.assert_called()

@mock.patch('PySide2.QtWidgets.QInputDialog.getItem')
@mock.patch('cuegui.CueJobMonitorTree.MoveDialog.move_items')
@mock.patch('opencue.api.findShow')
def test_sendToGroup(self, findShowMock, getItemMock):
def test_sendToGroup(self, findShowMock, move_itemsMock):

move_dialogMock = mock.Mock()

move_dialogMock.open()
group_name = 'arbitrary-group-name'
job = opencue.wrappers.job.Job(
opencue.compiled_proto.job_pb2.Job(
name='arbitrary-job-name', show='arbitrary-show-name'))
show = opencue.wrappers.show.Show()
body_content = cuegui.CueJobMonitorTree.Body(group_names=[],
group_ids=[],
job_names=[job.name()],
job_ids=[job])

group = opencue.wrappers.group.Group(opencue.compiled_proto.job_pb2.Group(name=group_name))
group.reparentJobs = mock.Mock()

show = opencue.wrappers.show.Show()
findShowMock.return_value = show
show.getGroups = mock.Mock(return_value=[group])
getItemMock.return_value = (group_name, True)

self.job_actions.sendToGroup(rpcObjects=[job])
move_dialogMock.dst_groups = {str(group_name): group}
move_itemsMock.return_value = move_dialogMock.dst_groups[str(group_name)].reparentJobs(
body_content.job_ids)
move_dialogMock.accept()

group.reparentJobs.assert_called_with([job])
group.reparentJobs.assert_called_with(body_content.job_ids)

@mock.patch('PySide2.QtWidgets.QInputDialog.getItem')
@mock.patch('cuegui.CueJobMonitorTree.MoveDialog.move_items')
@mock.patch('opencue.api.findShow')
def test_sendToGroupCanceled(self, findShowMock, getItemMock):
job = opencue.wrappers.job.Job(opencue.compiled_proto.job_pb2.Job(name='job-name'))
group = opencue.wrappers.group.Group()
def test_sendToGroupCanceled(self, findShowMock, move_itemsMock):

move_dialogMock = mock.Mock()

move_dialogMock.open()
group_name = 'arbitrary-group-name'
job = opencue.wrappers.job.Job(
opencue.compiled_proto.job_pb2.Job(
name='arbitrary-job-name', show='arbitrary-show-name'))
group = opencue.wrappers.group.Group(opencue.compiled_proto.job_pb2.Group(name=group_name))
group.reparentJobs = mock.Mock()
findShowMock.getGroups.return_value = []
getItemMock.return_value = (None, False)

self.job_actions.sendToGroup(rpcObjects=[job])
show = opencue.wrappers.show.Show()
findShowMock.return_value = show
show.getGroups = mock.Mock(return_value=[group])
move_itemsMock.return_value = (None, False)
move_dialogMock.reject()

group.reparentJobs.assert_not_called()

Expand Down

0 comments on commit 596088e

Please sign in to comment.