[tor-commits] [nyx/master] Finish merging controller module

atagar at torproject.org atagar at torproject.org
Fri Sep 16 06:18:14 UTC 2016


commit 85e41b3581371d9119dc678ce5e7f939453f45ba
Author: Damian Johnson <atagar at torproject.org>
Date:   Thu Sep 15 23:06:38 2016 -0700

    Finish merging controller module
    
    Moving the draw loop, making a handful of minor improvements in the process.
    This lets us finally drop the controller module.
---
 nyx/__init__.py          |  85 ++++++++++++++++++++++++++++++++---
 nyx/controller.py        | 114 -----------------------------------------------
 nyx/menu.py              |   2 +-
 nyx/popups.py            |   2 +-
 nyx/settings/strings.cfg |   4 ++
 nyx/starter.py           |  15 ++++++-
 test/__init__.py         |   2 +-
 7 files changed, 99 insertions(+), 125 deletions(-)

diff --git a/nyx/__init__.py b/nyx/__init__.py
index 33da167..69ede9b 100644
--- a/nyx/__init__.py
+++ b/nyx/__init__.py
@@ -36,7 +36,9 @@ import distutils.spawn
 import os
 import sys
 import threading
+import time
 
+import stem
 import stem.connection
 import stem.control
 import stem.util.conf
@@ -62,14 +64,23 @@ __all__ = [
   'tracker',
 ]
 
+
+def conf_handler(key, value):
+  if key == 'features.redrawRate':
+    return max(1, value)
+
+
 CONFIG = stem.util.conf.config_dict('nyx', {
+  'features.confirmQuit': True,
   'features.panels.show.graph': True,
   'features.panels.show.log': True,
   'features.panels.show.connection': True,
   'features.panels.show.config': True,
   'features.panels.show.torrc': True,
   'features.panels.show.interpreter': True,
-})
+  'features.redrawRate': 5,
+  'start_time': 0,
+}, conf_handler)
 
 NYX_INTERFACE = None
 TOR_CONTROLLER = None
@@ -94,7 +105,6 @@ except IOError as exc:
 
 def main():
   try:
-    import nyx.starter
     nyx.starter.main()
   except ImportError as exc:
     if exc.message == 'No module named stem':
@@ -119,6 +129,55 @@ def main():
     sys.exit(1)
 
 
+def draw_loop():
+  interface = nyx_interface()
+  next_key = None  # use this as the next user input
+
+  stem.util.log.info(msg('startup_time', start_time = time.time() - CONFIG['start_time']))
+
+  while not interface._quit:
+    interface.redraw()
+
+    with nyx.curses.raw_screen() as stdscr:
+      stdscr.refresh()
+
+    if next_key:
+      key, next_key = next_key, None
+    else:
+      key = nyx.curses.key_input(CONFIG['features.redrawRate'])
+
+    if key.match('right'):
+      interface.set_page((interface.get_page() + 1) % interface.page_count())
+    elif key.match('left'):
+      interface.set_page((interface.get_page() - 1) % interface.page_count())
+    elif key.match('p'):
+      interface.set_paused(not interface.is_paused())
+    elif key.match('m'):
+      nyx.menu.show_menu()
+    elif key.match('q'):
+      if CONFIG['features.confirmQuit']:
+        confirmation_key = show_message(msg('confirm_quit'), nyx.curses.BOLD, max_wait = 30)
+
+        if not confirmation_key.match('q'):
+          continue
+
+      break
+    elif key.match('x'):
+      confirmation_key = show_message(msg('confirm_reload'), nyx.curses.BOLD, max_wait = 30)
+
+      if confirmation_key.match('x'):
+        try:
+          tor_controller().signal(stem.Signal.RELOAD)
+        except stem.ControllerError as exc:
+          stem.util.log.error('Error detected when reloading tor: %s' % exc.strerror)
+    elif key.match('h'):
+      next_key = nyx.popups.show_help()
+    else:
+      for panel in interface.page_panels():
+        for keybinding in panel.key_handlers():
+          keybinding.handle(key)
+
+
 def nyx_interface():
   """
   Singleton controller for our interface.
@@ -308,7 +367,11 @@ class Interface(object):
     if CONFIG['features.panels.show.interpreter']:
       self._page_panels.append([nyx.panel.interpreter.InterpreterPanel()])
 
+    visible_panels = self.page_panels()
+
     for panel in self:
+      panel.set_visible(panel in visible_panels)
+
       if isinstance(panel, nyx.panel.DaemonPanel):
         panel.start()
 
@@ -337,6 +400,11 @@ class Interface(object):
       self._page = page_number
       self.header_panel().redraw()
 
+      visible_panels = self.page_panels()
+
+      for panel in self:
+        panel.set_visible(panel in visible_panels)
+
   def page_count(self):
     """
     Provides the number of pages the interface has.
@@ -365,7 +433,8 @@ class Interface(object):
     :returns: **list** of panels on that page
     """
 
-    return list(self._page_panels[self._page if page_number is None else page_number])
+    page_number = self._page if page_number is None else page_number
+    return [self._header_panel] + self._page_panels[page_number]
 
   def is_paused(self):
     """
@@ -409,7 +478,7 @@ class Interface(object):
 
     occupied = 0
 
-    for panel in [self.header_panel()] + self.page_panels():
+    for panel in self.page_panels():
       panel.redraw(force = force, top = occupied)
       occupied += panel.get_height()
 
@@ -430,10 +499,10 @@ class Interface(object):
     def halt_panels():
       daemons = [panel for panel in self if isinstance(panel, nyx.panel.DaemonPanel)]
 
-      for panel in daemons():
+      for panel in daemons:
         panel.stop()
 
-      for panel in daemons():
+      for panel in daemons:
         panel.join()
 
     halt_thread = threading.Thread(target = halt_panels)
@@ -448,6 +517,8 @@ class Interface(object):
         yield panel
 
 
+import nyx.curses
+import nyx.menu
 import nyx.panel
 import nyx.panel.config
 import nyx.panel.connection
@@ -456,3 +527,5 @@ import nyx.panel.header
 import nyx.panel.interpreter
 import nyx.panel.log
 import nyx.panel.torrc
+import nyx.popups
+import nyx.starter
diff --git a/nyx/controller.py b/nyx/controller.py
deleted file mode 100644
index 76fa549..0000000
--- a/nyx/controller.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Copyright 2009-2016, Damian Johnson and The Tor Project
-# See LICENSE for licensing information
-
-"""
-Main interface loop for nyx, periodically redrawing the screen and issuing
-user input to the proper panels.
-"""
-
-import time
-
-import nyx.curses
-import nyx.menu
-import nyx.popups
-
-import nyx.panel
-
-import stem
-
-from stem.util import conf, log
-
-from nyx.curses import BOLD
-from nyx import nyx_interface, tor_controller, show_message
-
-
-def conf_handler(key, value):
-  if key == 'features.redrawRate':
-    return max(1, value)
-
-
-CONFIG = conf.config_dict('nyx', {
-  'features.redrawRate': 5,
-  'features.confirmQuit': True,
-  'start_time': 0,
-}, conf_handler)
-
-
-def start_nyx():
-  """
-  Main draw loop context.
-  """
-
-  # provides notice about any unused config keys
-
-  for key in sorted(conf.get_config('nyx').unused_keys()):
-    if not key.startswith('msg.') and not key.startswith('dedup.'):
-      log.notice('Unused configuration entry: %s' % key)
-
-  interface = nyx_interface()
-
-  # logs the initialization time
-
-  log.info('nyx started (initialization took %0.3f seconds)' % (time.time() - CONFIG['start_time']))
-
-  # main draw loop
-
-  override_key = None      # uses this rather than waiting on user input
-
-  while not interface._quit:
-    display_panels = [interface.header_panel()] + interface.page_panels()
-
-    # sets panel visability
-
-    for panel in interface:
-      panel.set_visible(panel in display_panels)
-
-    interface.redraw()
-
-    with nyx.curses.raw_screen() as stdscr:
-      stdscr.refresh()
-
-    # wait for user keyboard input until timeout, unless an override was set
-
-    if override_key:
-      key, override_key = override_key, None
-    else:
-      key = nyx.curses.key_input(CONFIG['features.redrawRate'])
-
-    if key.match('right'):
-      interface.set_page((interface.get_page() + 1) % interface.page_count())
-    elif key.match('left'):
-      interface.set_page((interface.get_page() - 1) % interface.page_count())
-    elif key.match('p'):
-      interface.set_paused(not interface.is_paused())
-    elif key.match('m'):
-      nyx.menu.show_menu()
-    elif key.match('q'):
-      # provides prompt to confirm that nyx should exit
-
-      if CONFIG['features.confirmQuit']:
-        msg = 'Are you sure (q again to confirm)?'
-        confirmation_key = show_message(msg, BOLD, max_wait = 30)
-        quit_confirmed = confirmation_key.match('q')
-      else:
-        quit_confirmed = True
-
-      if quit_confirmed:
-        break
-    elif key.match('x'):
-      # provides prompt to confirm that nyx should issue a sighup
-
-      msg = "This will reset Tor's internal state. Are you sure (x again to confirm)?"
-      confirmation_key = show_message(msg, BOLD, max_wait = 30)
-
-      if confirmation_key.match('x'):
-        try:
-          tor_controller().signal(stem.Signal.RELOAD)
-        except stem.ControllerError as exc:
-          log.error('Error detected when reloading tor: %s' % exc.strerror)
-    elif key.match('h'):
-      override_key = nyx.popups.show_help()
-    else:
-      for panel in display_panels:
-        for keybinding in panel.key_handlers():
-          keybinding.handle(key)
diff --git a/nyx/menu.py b/nyx/menu.py
index 83b8479..9aa5797 100644
--- a/nyx/menu.py
+++ b/nyx/menu.py
@@ -269,7 +269,7 @@ def _view_menu():
   page_group = RadioGroup(interface.set_page, interface.get_page())
 
   for i in range(interface.page_count()):
-    page_panels = interface.page_panels(page_number = i)
+    page_panels = interface.page_panels(page_number = i)[1:]
     label = ' / '.join([type(panel).__name__.replace('Panel', '') for panel in page_panels])
     view_menu.add(RadioMenuItem(label, page_group, i))
 
diff --git a/nyx/popups.py b/nyx/popups.py
index e2f0205..0a05a2f 100644
--- a/nyx/popups.py
+++ b/nyx/popups.py
@@ -59,7 +59,7 @@ def show_help():
   interface = nyx_interface()
   handlers = []
 
-  for panel in reversed(interface.page_panels()):
+  for panel in reversed(interface.page_panels()[1:]):
     handlers += [handler for handler in panel.key_handlers() if handler.description]
 
   def _render(subwindow):
diff --git a/nyx/settings/strings.cfg b/nyx/settings/strings.cfg
index 9179519..0f24529 100644
--- a/nyx/settings/strings.cfg
+++ b/nyx/settings/strings.cfg
@@ -14,6 +14,10 @@
 
 msg.wrap {text}
 
+msg.startup_time nyx started (initialization took {start_time} seconds)
+msg.confirm_quit Are you sure (q again to confirm)?
+msg.confirm_reload This will reset Tor's internal state. Are you sure (x again to confirm)?
+
 msg.config.unable_to_read_file Failed to load configuration (using defaults): "{error}"
 msg.config.nothing_loaded No nyxrc loaded, using defaults. You can customize nyx by placing a configuration file at {path} (see the nyxrc.sample for its options).
 
diff --git a/nyx/starter.py b/nyx/starter.py
index 7ff37b2..dbb6d8c 100644
--- a/nyx/starter.py
+++ b/nyx/starter.py
@@ -16,7 +16,6 @@ import time
 
 import nyx
 import nyx.arguments
-import nyx.controller
 import nyx.curses
 import nyx.tracker
 
@@ -78,6 +77,7 @@ def main(config):
 
   _warn_if_root(controller)
   _warn_if_unable_to_get_pid(controller)
+  _warn_about_unused_config_keys()
   _setup_freebsd_chroot(controller)
   _use_english_subcommands()
   _use_no_esc_delay()
@@ -85,7 +85,7 @@ def main(config):
   _set_process_name()
 
   try:
-    nyx.curses.start(nyx.controller.start_nyx, acs_support = config.get('features.acsSupport', True), transparent_background = True, cursor = False)
+    nyx.curses.start(nyx.draw_loop, acs_support = config.get('features.acsSupport', True), transparent_background = True, cursor = False)
   except UnboundLocalError as exc:
     if os.environ['TERM'] != 'xterm':
       print(msg('setup.unknown_term', term = os.environ['TERM']))
@@ -190,6 +190,17 @@ def _warn_if_unable_to_get_pid(controller):
 
 
 @uses_settings
+def _warn_about_unused_config_keys(config):
+  """
+  Provides a notice if the user's nyxrc has any entries that are unused.
+  """
+
+  for key in sorted(config.unused_keys()):
+    if not key.startswith('msg.') and not key.startswith('dedup.'):
+      log.notice('Unused configuration entry: %s' % key)
+
+
+ at uses_settings
 def _setup_freebsd_chroot(controller, config):
   """
   If we're running under FreeBSD then check the system for a chroot path.
diff --git a/test/__init__.py b/test/__init__.py
index ebb0793..6e534e1 100644
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -83,7 +83,7 @@ def render(func, *args, **kwargs):
   attr = {}
 
   def draw_func():
-    nyx.curses.disable_acs()
+    nyx.curses._disable_acs()
     nyx.curses.CURSES_SCREEN.erase()
     start_time = time.time()
 





More information about the tor-commits mailing list