commit e7385ff70800c162699c72de30822139b053982e Author: Damian Johnson atagar@torproject.org Date: Thu Jul 14 10:24:59 2016 -0700
Centralize pausing in Controller
Pausing is a global state. We never pause only some of our interface, as such this belongs in the Controller. There's a couple panels that need special handling but otherwise a pretty straight forward move. --- nyx/controller.py | 42 +++++++++++++++++++++++++++++++++--------- nyx/panel/__init__.py | 42 ++++-------------------------------------- nyx/panel/connection.py | 6 ++++-- nyx/panel/graph.py | 12 +++++++----- nyx/panel/header.py | 5 +++-- nyx/panel/log.py | 5 ++--- test/panel/header.py | 1 + 7 files changed, 54 insertions(+), 59 deletions(-)
diff --git a/nyx/controller.py b/nyx/controller.py index 964e27d..fc38185 100644 --- a/nyx/controller.py +++ b/nyx/controller.py @@ -120,7 +120,8 @@ class Controller(object):
self.quit_signal = False self._page = 0 - self._is_paused = False + self._paused = False + self._pause_time = -1 self._force_redraw = False self._last_drawn = 0
@@ -171,23 +172,46 @@ class Controller(object):
def is_paused(self): """ - True if the interface is paused, false otherwise. + Provides if the interface is configured to be paused or not. + + :returns: **True** if the interface is paused and **False** otherwise """
- return self._is_paused + return self._paused
def set_paused(self, is_pause): """ - Sets the interface to be paused or unpaused. + Pauses or unpauses the interface. + + :param bool is_pause: suspends the interface if **True**, resumes it + otherwise """
- if is_pause != self._is_paused: - self._is_paused = is_pause - self._force_redraw = True - self.header_panel().redraw() + if is_pause != self._paused: + if is_pause: + self._pause_time = time.time() + + # Couple panels have their own pausing behavior. I'll later change this to + # a listener approach or someting else that's less hacky.
for panel_impl in self.get_all_panels(): - panel_impl.set_paused(is_pause) + if isinstance(panel_impl, nyx.panel.graph.GraphPanel) or isinstance(panel_impl, nyx.panel.log.LogPanel): + panel_impl.set_paused(is_pause) + + self._paused = is_pause + + for panel_impl in self.get_display_panels(): + panel_impl.redraw() + + def get_pause_time(self): + """ + Provides the time that we were last paused, returning -1 if we've never + been paused. + + :returns: **float** with the unix timestamp for when we were last paused + """ + + return self._pause_time
def header_panel(self): return self._header_panel diff --git a/nyx/panel/__init__.py b/nyx/panel/__init__.py index ee938dc..1d6ae9f 100644 --- a/nyx/panel/__init__.py +++ b/nyx/panel/__init__.py @@ -72,9 +72,6 @@ class Panel(object): def __init__(self): self._visible = False
- self._paused = False - self._pause_time = -1 - self._top = 0 self._left = 0 self._height = -1 @@ -90,40 +87,6 @@ class Panel(object):
self._visible = is_visible
- def is_paused(self): - """ - Provides if the panel's configured to be paused or not. - """ - - return self._paused - - def set_paused(self, is_pause): - """ - Toggles if the panel is paused or not. This causes the panel to be redrawn - when toggling is pause state unless told to do otherwise. This is - important when pausing since otherwise the panel's display could change - when redrawn for other reasons. - - Arguments: - is_pause - freezes the state of the pause attributes if true, makes - them editable otherwise - """ - - if is_pause != self._paused: - if is_pause: - self._pause_time = time.time() - - self._paused = is_pause - self.redraw() - - def get_pause_time(self): - """ - Provides the time that we were last paused, returning -1 if we've never - been paused. - """ - - return self._pause_time - def get_top(self): """ Provides the top position used for subwindows. @@ -234,10 +197,13 @@ class DaemonPanel(Panel, threading.Thread): Performs our _update() action at the given rate. """
+ import nyx.controller + last_ran = -1 + nyx_controller = nyx.controller.get_controller()
while not self._halt: - if self.is_paused() or (time.time() - last_ran) < self._update_rate: + if nyx_controller.is_paused() or (time.time() - last_ran) < self._update_rate: with self._pause_condition: if not self._halt: self._pause_condition.wait(0.2) diff --git a/nyx/panel/connection.py b/nyx/panel/connection.py index 8e032e6..bd78a9b 100644 --- a/nyx/panel/connection.py +++ b/nyx/panel/connection.py @@ -11,6 +11,7 @@ import collections import curses import itertools
+import nyx.controller import nyx.curses import nyx.panel import nyx.popups @@ -401,6 +402,7 @@ class ConnectionPanel(nyx.panel.DaemonPanel):
def draw(self, subwindow): controller = tor_controller() + nyx_controller = nyx.controller.get_controller() entries = self._entries
lines = list(itertools.chain.from_iterable([entry.get_lines() for entry in entries])) @@ -408,8 +410,8 @@ class ConnectionPanel(nyx.panel.DaemonPanel): details_offset = DETAILS_HEIGHT + 1 if is_showing_details else 0 selected, scroll = self._scroller.selection(lines, subwindow.height - details_offset - 1)
- if self.is_paused(): - current_time = self.get_pause_time() + if nyx_controller.is_paused(): + current_time = nyx_controller.get_pause_time() elif not controller.is_alive(): current_time = controller.connection_time() else: diff --git a/nyx/panel/graph.py b/nyx/panel/graph.py index 029f417..e5f9cc7 100644 --- a/nyx/panel/graph.py +++ b/nyx/panel/graph.py @@ -481,8 +481,9 @@ class GraphPanel(nyx.panel.Panel): if not self.displayed_stat: return 0
+ nyx_controller = nyx.controller.get_controller() height = DEFAULT_CONTENT_HEIGHT + self._graph_height - accounting_stats = self._accounting_stats if self.is_paused() else self._accounting_stats_paused + accounting_stats = self._accounting_stats if nyx_controller.is_paused() else self._accounting_stats_paused
if self.displayed_stat == GraphStat.BANDWIDTH and accounting_stats: height += 3 @@ -556,13 +557,13 @@ class GraphPanel(nyx.panel.Panel): self._accounting_stats_paused = copy.copy(self._accounting_stats) self._stats_paused = dict([(key, type(self._stats[key])(self._stats[key])) for key in self._stats])
- nyx.panel.Panel.set_paused(self, is_pause) - def draw(self, subwindow): if not self.displayed_stat: return
- if not self.is_paused(): + nyx_controller = nyx.controller.get_controller() + + if not nyx_controller.is_paused(): stat = self._stats[self.displayed_stat] accounting_stats = self._accounting_stats else: @@ -586,10 +587,11 @@ class GraphPanel(nyx.panel.Panel): if not CONFIG['features.graph.bw.accounting.show']: self._accounting_stats = None elif not self._accounting_stats or time.time() - self._accounting_stats.retrieved >= ACCOUNTING_RATE: + nyx_controller = nyx.controller.get_controller() old_accounting_stats = self._accounting_stats self._accounting_stats = tor_controller().get_accounting_stats(None)
- if not self.is_paused(): + if not nyx_controller.is_paused(): # if we either added or removed accounting info then redraw the whole # screen to account for resizing
diff --git a/nyx/panel/header.py b/nyx/panel/header.py index a2a5ae7..5f33f4f 100644 --- a/nyx/panel/header.py +++ b/nyx/panel/header.py @@ -148,9 +148,10 @@ class HeaderPanel(nyx.panel.DaemonPanel):
# space available for content
+ nyx_controller = nyx.controller.get_controller() left_width = max(subwindow.width / 2, 77) if is_wide else subwindow.width right_width = subwindow.width - left_width - pause_time = self.get_pause_time() if self.is_paused() else None + pause_time = nyx_controller.get_pause_time() if nyx_controller.is_paused() else None
_draw_platform_section(subwindow, 0, 0, left_width, vals)
@@ -175,7 +176,7 @@ class HeaderPanel(nyx.panel.DaemonPanel): _draw_fingerprint_and_fd_usage(subwindow, 0, 3, left_width, vals) _draw_flags(subwindow, 0, 4, vals.flags)
- _draw_status(subwindow, 0, self.get_height() - 1, self.is_paused(), self._message, *self._message_attr) + _draw_status(subwindow, 0, self.get_height() - 1, nyx_controller.is_paused(), self._message, *self._message_attr)
def reset_listener(self, controller, event_type, _): self._update() diff --git a/nyx/panel/log.py b/nyx/panel/log.py index 81b7a64..02cd7fe 100644 --- a/nyx/panel/log.py +++ b/nyx/panel/log.py @@ -250,17 +250,16 @@ class LogPanel(nyx.panel.DaemonPanel): if is_pause: self._event_log_paused = self._event_log.clone()
- nyx.panel.Panel.set_paused(self, is_pause) - def draw(self, subwindow): scroll = self._scroller.location(self._last_content_height, subwindow.height - 1)
+ nyx_controller = nyx.controller.get_controller() event_filter = self._filter.clone() event_types = list(self._event_types) last_content_height = self._last_content_height show_duplicates = self._show_duplicates
- event_log = self._event_log_paused if self.is_paused() else self._event_log + event_log = self._event_log_paused if nyx_controller.is_paused() else self._event_log event_log = filter(lambda entry: event_filter.match(entry.display_message), event_log) event_log = filter(lambda entry: not entry.is_duplicate or show_duplicates, event_log)
diff --git a/test/panel/header.py b/test/panel/header.py index 3e47afa..c14b404 100644 --- a/test/panel/header.py +++ b/test/panel/header.py @@ -73,6 +73,7 @@ class TestHeaderPanel(unittest.TestCase): @patch('nyx.panel.header.tor_controller') @patch('nyx.panel.header.Sampling.create') def test_rendering_panel(self, sampling_mock, tor_controller_mock, nyx_controller_mock): + nyx_controller_mock().is_paused.return_value = False nyx_controller_mock().get_page.return_value = 1 nyx_controller_mock().get_page_count.return_value = 4 sampling_mock.return_value = test_sampling()
tor-commits@lists.torproject.org