Skip to content

Commit

Permalink
gscan: information on hover.
Browse files Browse the repository at this point in the history
  • Loading branch information
oliver-sanders committed Jun 15, 2016
1 parent a9243d2 commit e8c7789
Showing 1 changed file with 76 additions and 1 deletion.
77 changes: 76 additions & 1 deletion lib/cylc/gui/gscan.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@

from cylc.cfgspec.globalcfg import GLOBAL_CFG
from cylc.cfgspec.gcylc import gcfg
from cylc.exceptions import PortFileError
import cylc.flags
from cylc.gui.legend import ThemeLegendWindow
from cylc.gui.dot_maker import DotMaker
from cylc.gui.util import get_icon, setup_icons, set_exception_hook_dialog
from cylc.network.port_scan import scan_all
from cylc.network.suite_state import StateSummaryClient
from cylc.owner import USER
from cylc.version import CYLC_VERSION
from cylc.task_state import TASK_STATUSES_ORDERED, TASK_STATUS_RUNAHEAD
Expand Down Expand Up @@ -646,6 +648,29 @@ def _on_query_tooltip(self, widget, x, y, kbd_ctx, tooltip):
if column.get_title() != "Status":
tooltip.set_text(None)
return False

# If hovering over a status indicator set tooltip to show most recent
# tasks.
dot_offset, dot_width = tuple(column.cell_get_position(
column.get_cell_renderers()[1]))
cell_index = (cell_x - dot_offset) // dot_width
if cell_index >= 0:
# NOTE: TreeViewColumn.get_cell_renderers() does not allways return
# cell renderers for the correct row.
info = re.findall(r'\D+\d+', model.get(iter_, 6)[0])
if cell_index >= len(info):
return False
state = info[cell_index].strip().split(' ')[0]
point_string = model.get(iter_, 5)[0]
tasks = self.updater.get_last_n_tasks(
suite, host, state, point_string, 5) # Last 5 tasks.
tooltip.set_markup('<b>{state}</b>\n{tasks}'.format(
state=state,
tasks='\n'.join(tasks))
)
return True

# Set the tooltip to a generic status for this suite.
state_texts = []
status_column_info = 6
state_text = model.get_value(iter_, status_column_info)
Expand Down Expand Up @@ -673,7 +698,7 @@ def _set_cell_pixbuf_state(self, column, cell, model, iter_, index_tuple):
is_stopped = model.get_value(iter_, 2)
info = re.findall(r'\D+\d+', state_info)
if index < len(info):
state = info[index].rsplit(" ", 1)[0]
state = info[index].rsplit(" ", 1)[0].strip()
icon = self.dots.get_icon(state.strip(), is_stopped=is_stopped)
cell.set_property("visible", True)
else:
Expand Down Expand Up @@ -918,10 +943,14 @@ class ScanAppUpdater(BaseScanUpdater):

"""Update the scan app."""

TIME_STRINGS = ['submitted_time_string', 'started_time_string',
'finished_time_string']

def __init__(self, hosts, suite_treemodel, suite_treeview, owner=None,
poll_interval=None):
self.suite_treemodel = suite_treemodel
self.suite_treeview = suite_treeview
self.active_tasks = {}
super(ScanAppUpdater, self).__init__(hosts, owner=owner,
poll_interval=poll_interval)

Expand Down Expand Up @@ -955,6 +984,44 @@ def clear_stopped_suites(self):
self.stopped_hosts_suites_info.clear()
gobject.idle_add(self.update)

def get_last_n_tasks(self, suite, host, task_state, point_string, n):
"""Returns a list of the last 'n' tasks with the provided state for
the provided suite."""
# TODO: safety check

# Get task state summary information.
if suite + host not in self.active_tasks:
return ['<i>Could not get info, try refreshing the scanner.</i>']
tasks = self.active_tasks[suite + host]
if tasks is False:
return ['<i>Cannot connect to suite.</i>']

# If point_string specified, remove entries at other point_strings.
to_remove = []
if point_string:
for task in tasks:
_, task_point_string = task.rsplit('.', 1)
if task_point_string != point_string:
to_remove.append(task)
for task in to_remove:
del tasks[task]

# Get list of tasks that match the provided state.
ret = []
for task in tasks:
if tasks[task]['state'] == task_state:
time_strings = ['1970-01-01T00:00:00Z']
for time_string in self.TIME_STRINGS:
if time_string in tasks[task] and tasks[task][time_string]:
time_strings.append(tasks[task][time_string])
ret.append((max(time_strings), task))

# return only the n youngest items
ret.sort(reverse=True)
suffix = [] if len(ret) <= n else [
'<i>And %d more</i>' % (len(ret) - n,)]
return [task[1] for task in ret[0:n]] + suffix

def update(self):
"""Update the Applet."""
row_ids = self._get_user_expanded_row_ids()
Expand All @@ -969,7 +1036,15 @@ def update(self):
if (suite, host) not in suite_host_tuples:
suite_host_tuples.append((suite, host))
suite_host_tuples.sort()
self.active_tasks = {}
for suite, host in suite_host_tuples:

try:
self.active_tasks[suite + host] = StateSummaryClient(
suite, host=host).get_suite_state_summary()[1]
except PortFileError:
self.active_tasks[suite + host] = False

if suite in info.get(host, {}):
suite_info = info[host][suite]
is_stopped = False
Expand Down

0 comments on commit e8c7789

Please sign in to comment.