[tor-commits] [nyx/master] Move tor event configuration to util

atagar at torproject.org atagar at torproject.org
Tue May 5 05:42:06 UTC 2015


commit 895c6a5d13e09c235d7446307f01d8771d11ff1d
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat May 2 13:48:39 2015 -0700

    Move tor event configuration to util
    
    Move listen_for_events() to util, and drop another largely unused helper.
---
 nyx/log_panel.py |  100 +++++++++++-------------------------------------------
 nyx/util/log.py  |   36 ++++++++++++++++++++
 2 files changed, 56 insertions(+), 80 deletions(-)

diff --git a/nyx/log_panel.py b/nyx/log_panel.py
index 2840c86..fe3e39e 100644
--- a/nyx/log_panel.py
+++ b/nyx/log_panel.py
@@ -18,7 +18,7 @@ import nyx.arguments
 import nyx.popups
 
 from nyx.util import join, panel, tor_controller, ui_tools
-from nyx.util.log import TOR_RUNLEVELS, LogFileOutput, LogGroup, LogEntry, LogFilters, read_tor_log, condense_runlevels, days_since, log_file_path
+from nyx.util.log import LogFileOutput, LogGroup, LogEntry, LogFilters, read_tor_log, condense_runlevels, listen_for_events, days_since, log_file_path
 
 ENTRY_INDENT = 2  # spaces an entry's message is indented after the first line
 
@@ -74,22 +74,16 @@ class LogPanel(panel.Panel, threading.Thread):
     threading.Thread.__init__(self)
     self.setDaemon(True)
 
+    self._logged_event_types = listen_for_events(self._register_tor_event, logged_events)
+    self._logged_events = LogGroup(CONFIG['cache.log_panel.size'], group_by_day = CONFIG['features.log.showDateDividers'])
+    self._log_file = LogFileOutput(CONFIG['features.log_file'])
     self._filter = LogFilters(initial_filters = CONFIG['features.log.regex'])
 
-    self.logged_events = []  # needs to be set before we receive any events
-
-    # restricts the input to the set of events we can listen to, and
-    # configures the controller to liten to them
-
-    self.logged_events = self.set_event_listening(logged_events)
+    self.set_pause_attr('_logged_events')
 
     self.last_content_height = 0         # height of the rendered content when last drawn
-    self._log_file = LogFileOutput(CONFIG['features.log_file'])
     self.scroll = 0
 
-    self.set_pause_attr('_msg_log')
-    self._msg_log = LogGroup(CONFIG['cache.log_panel.size'], group_by_day = CONFIG['features.log.showDateDividers'])
-
     self._last_update = -1               # time the content was last revised
     self._halt = False                   # terminates thread if true
     self._cond = threading.Condition()   # used for pausing/resuming the thread
@@ -108,8 +102,8 @@ class LogPanel(panel.Panel, threading.Thread):
       if log_location:
         try:
           for entry in reversed(list(read_tor_log(log_location, CONFIG['features.log.prepopulateReadLimit']))):
-            if entry.type in self.logged_events:
-              self._msg_log.add(entry)
+            if entry.type in self._logged_event_types:
+              self._logged_events.add(entry)
         except IOError as exc:
           log.info('Unable to read log located at %s: %s' % (log_location, exc))
         except ValueError as exc:
@@ -124,7 +118,7 @@ class LogPanel(panel.Panel, threading.Thread):
 
     # leaving last_content_height as being too low causes initialization problems
 
-    self.last_content_height = len(self._msg_log)
+    self.last_content_height = len(self._logged_events)
 
   def set_duplicate_visability(self, is_visible):
     """
@@ -138,25 +132,6 @@ class LogPanel(panel.Panel, threading.Thread):
     nyx_config = conf.get_config('nyx')
     nyx_config.set('features.log.showDuplicateEntries', str(is_visible))
 
-  def set_logged_events(self, event_types):
-    """
-    Sets the event types recognized by the panel.
-
-    Arguments:
-      event_types - event types to be logged
-    """
-
-    if event_types == self.logged_events:
-      return
-
-    with self.vals_lock:
-      # configures the controller to listen for these tor events, and provides
-      # back a subset without anything we're failing to listen to
-
-      set_types = self.set_event_listening(event_types)
-      self.logged_events = set_types
-      self.redraw(True)
-
   def get_filter(self):
     """
     Provides our currently selected regex filter.
@@ -200,9 +175,13 @@ class LogPanel(panel.Panel, threading.Thread):
 
         if user_input:
           user_input = user_input.replace(' ', '')  # strips spaces
+          event_types = nyx.arguments.expand_events(user_input)
 
           try:
-            self.set_logged_events(nyx.arguments.expand_events(user_input))
+            if event_types != self._logged_event_types:
+              with self.vals_lock:
+                self._logged_event_types = listen_for_events(self._register_tor_event, event_types)
+                self.redraw(True)
           except ValueError as exc:
             nyx.popups.show_msg('Invalid flags: %s' % str(exc), 2)
       finally:
@@ -228,7 +207,7 @@ class LogPanel(panel.Panel, threading.Thread):
     """
 
     with self.vals_lock:
-      self._msg_log = LogGroup(CONFIG['cache.log_panel.size'], group_by_day = CONFIG['features.log.showDateDividers'])
+      self._logged_events = LogGroup(CONFIG['cache.log_panel.size'], group_by_day = CONFIG['features.log.showDateDividers'])
       self.redraw(True)
 
   def save_snapshot(self, path):
@@ -257,7 +236,7 @@ class LogPanel(panel.Panel, threading.Thread):
 
     with self.vals_lock:
       try:
-        for entry in reversed(self._msg_log):
+        for entry in reversed(self._logged_events):
           is_visible = self._filter.match(entry.display_message)
 
           if is_visible:
@@ -332,7 +311,7 @@ class LogPanel(panel.Panel, threading.Thread):
     contain up to two lines. Starts with newest entries.
     """
 
-    event_log = self.get_attr('_msg_log')
+    event_log = self.get_attr('_logged_events')
 
     with self.vals_lock:
       self._last_logged_events, self._last_update = event_log, time.time()
@@ -341,7 +320,7 @@ class LogPanel(panel.Panel, threading.Thread):
       # draws the top label
 
       if self.is_title_visible():
-        comp = list(condense_runlevels(*self.logged_events))
+        comp = list(condense_runlevels(*self._logged_event_types))
 
         if self._filter.selection():
           comp.append('filter: %s' % self._filter.selection())
@@ -515,10 +494,6 @@ class LogPanel(panel.Panel, threading.Thread):
         log.debug('redrawing the log panel with the corrected content height (%s)' % force_redraw_reason)
         self.redraw(True)
 
-  def redraw(self, force_redraw=False, block=False):
-    # determines if the content needs to be redrawn or not
-    panel.Panel.redraw(self, force_redraw, block)
-
   def run(self):
     """
     Redraws the display, coalescing updates if events are rapidly logged (for
@@ -535,7 +510,7 @@ class LogPanel(panel.Panel, threading.Thread):
 
       sleep_time = 0
 
-      if (self._msg_log == self._last_logged_events and last_day == current_day) or self.is_paused():
+      if (self._logged_events == self._last_logged_events and last_day == current_day) or self.is_paused():
         sleep_time = 5
       elif time_since_reset < max_log_update_rate:
         sleep_time = max(0.05, max_log_update_rate - time_since_reset)
@@ -562,41 +537,6 @@ class LogPanel(panel.Panel, threading.Thread):
       self._halt = True
       self._cond.notifyAll()
 
-  def set_event_listening(self, events):
-    """
-    Configures the events Tor listens for, filtering non-tor events from what we
-    request from the controller. This returns a sorted list of the events we
-    successfully set.
-
-    Arguments:
-      events - event types to attempt to set
-    """
-
-    events = set(events)  # drops duplicates
-
-    # accounts for runlevel naming difference
-
-    tor_events = events.intersection(set(nyx.arguments.TOR_EVENT_TYPES.values()))
-    nyx_events = events.intersection(set(['NYX_%s' % runlevel for runlevel in TOR_RUNLEVELS]))
-
-    # adds events unrecognized by nyx if we're listening to the 'UNKNOWN' type
-
-    if 'UNKNOWN' in events:
-      tor_events.update(set(nyx.arguments.missing_event_types()))
-
-    controller = tor_controller()
-    controller.remove_event_listener(self._register_tor_event)
-
-    for event_type in list(tor_events):
-      try:
-        controller.add_event_listener(self._register_tor_event, event_type)
-      except stem.ProtocolError:
-        tor_events.remove(event_type)
-
-    # provides back the input set minus events we failed to set
-
-    return sorted(tor_events.union(nyx_events))
-
   def _register_tor_event(self, event):
     msg = ' '.join(str(event).split(' ')[1:])
 
@@ -614,11 +554,11 @@ class LogPanel(panel.Panel, threading.Thread):
     self._register_event(LogEntry(int(record.created), 'NYX_%s' % record.levelname, record.msg))
 
   def _register_event(self, event):
-    if event.type not in self.logged_events:
+    if event.type not in self._logged_event_types:
       return
 
     with self.vals_lock:
-      self._msg_log.add(event)
+      self._logged_events.add(event)
       self._log_file.write(event.display_message)
 
       # notifies the display that it has new content
diff --git a/nyx/util/log.py b/nyx/util/log.py
index 64abc4f..1371bb8 100644
--- a/nyx/util/log.py
+++ b/nyx/util/log.py
@@ -126,6 +126,42 @@ def condense_runlevels(*events):
   return result + events
 
 
+def listen_for_events(listener, events):
+  """
+  Configures tor to notify a function of these event types. If tor is
+  configured to notify this listener then the old listener is replaced.
+
+  :param function listener: listener to be notified
+  :param list events: event types to attempt to set
+
+  :returns: **list** of event types we're successfully now listening to
+  """
+
+  import nyx.arguments
+  events = set(events)  # drops duplicates
+
+  # accounts for runlevel naming difference
+
+  tor_events = events.intersection(set(nyx.arguments.TOR_EVENT_TYPES.values()))
+  nyx_events = events.intersection(set(['NYX_%s' % runlevel for runlevel in TOR_RUNLEVELS]))
+
+  # adds events unrecognized by nyx if we're listening to the 'UNKNOWN' type
+
+  if 'UNKNOWN' in events:
+    tor_events.update(set(nyx.arguments.missing_event_types()))
+
+  controller = nyx.util.tor_controller()
+  controller.remove_event_listener(listener)
+
+  for event_type in list(tor_events):
+    try:
+      controller.add_event_listener(listener, event_type)
+    except stem.ProtocolError:
+      tor_events.remove(event_type)
+
+  return sorted(tor_events.union(nyx_events))
+
+
 @lru_cache()
 def _common_log_messages():
   """





More information about the tor-commits mailing list