[tor-commits] [nyx/master] Use 'with' for log panel locking
atagar at torproject.org
atagar at torproject.org
Tue May 5 05:42:06 UTC 2015
commit 68cef741685f139c852f55b9f25d57cad78aa78f
Author: Damian Johnson <atagar at torproject.org>
Date: Wed Apr 15 10:03:31 2015 -0700
Use 'with' for log panel locking
Safer locking so unexpected exceptions won't cause us to have an unreleased
lock.
---
nyx/log_panel.py | 520 ++++++++++++++++++++++++++----------------------------
1 file changed, 251 insertions(+), 269 deletions(-)
diff --git a/nyx/log_panel.py b/nyx/log_panel.py
index dc63af8..e691b29 100644
--- a/nyx/log_panel.py
+++ b/nyx/log_panel.py
@@ -316,35 +316,32 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
Clears the event log and repopulates it from the nyx and tor backlogs.
"""
- self.vals_lock.acquire()
+ with self.vals_lock:
+ # clears the event log
- # clears the event log
+ self.msg_log = []
- self.msg_log = []
+ # fetches past tor events from log file, if available
- # fetches past tor events from log file, if available
+ if CONFIG['features.log.prepopulate']:
+ set_runlevels = list(set.intersection(set(self.logged_events), set(list(log.Runlevel))))
+ read_limit = CONFIG['features.log.prepopulateReadLimit']
- if CONFIG['features.log.prepopulate']:
- set_runlevels = list(set.intersection(set(self.logged_events), set(list(log.Runlevel))))
- read_limit = CONFIG['features.log.prepopulateReadLimit']
+ logging_location = log_file_path()
- logging_location = log_file_path()
-
- if logging_location:
- try:
- for entry in read_tor_log(logging_location, read_limit):
- if entry.type in set_runlevels:
- self.msg_log.append(entry)
- except IOError as exc:
- log.info('Unable to read log located at %s: %s' % (logging_location, exc))
- except ValueError as exc:
- log.info(str(exc))
-
- # crops events that are either too old, or more numerous than the caching size
+ if logging_location:
+ try:
+ for entry in read_tor_log(logging_location, read_limit):
+ if entry.type in set_runlevels:
+ self.msg_log.append(entry)
+ except IOError as exc:
+ log.info('Unable to read log located at %s: %s' % (logging_location, exc))
+ except ValueError as exc:
+ log.info(str(exc))
- self._trim_events(self.msg_log)
+ # crops events that are either too old, or more numerous than the caching size
- self.vals_lock.release()
+ self._trim_events(self.msg_log)
def set_duplicate_visability(self, is_visible):
"""
@@ -394,18 +391,16 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
log.error('Unable to write to log file: %s' % exc.strerror)
self.log_file = None
- self.vals_lock.acquire()
- self.msg_log.insert(0, event)
- self._trim_events(self.msg_log)
-
- # notifies the display that it has new content
+ with self.vals_lock:
+ self.msg_log.insert(0, event)
+ self._trim_events(self.msg_log)
- if not self.regex_filter or self.regex_filter.search(event.display_message):
- self._cond.acquire()
- self._cond.notifyAll()
- self._cond.release()
+ # notifies the display that it has new content
- self.vals_lock.release()
+ if not self.regex_filter or self.regex_filter.search(event.display_message):
+ self._cond.acquire()
+ self._cond.notifyAll()
+ self._cond.release()
def set_logged_events(self, event_types):
"""
@@ -418,15 +413,13 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
if event_types == self.logged_events:
return
- self.vals_lock.acquire()
-
- # configures the controller to listen for these tor events, and provides
- # back a subset without anything we're failing to listen to
+ 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)
- self.vals_lock.release()
+ set_types = self.set_event_listening(event_types)
+ self.logged_events = set_types
+ self.redraw(True)
def get_filter(self):
"""
@@ -447,10 +440,9 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
if log_filter == self.regex_filter:
return
- self.vals_lock.acquire()
- self.regex_filter = log_filter
- self.redraw(True)
- self.vals_lock.release()
+ with self.vals_lock:
+ self.regex_filter = log_filter
+ self.redraw(True)
def make_filter_selection(self, selected_option):
"""
@@ -549,10 +541,9 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
Clears the contents of the event log.
"""
- self.vals_lock.acquire()
- self.msg_log = []
- self.redraw(True)
- self.vals_lock.release()
+ with self.vals_lock:
+ self.msg_log = []
+ self.redraw(True)
def save_snapshot(self, path):
"""
@@ -577,19 +568,16 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
raise IOError("unable to make directory '%s'" % base_dir)
snapshot_file = open(path, 'w')
- self.vals_lock.acquire()
-
- try:
- for entry in self.msg_log:
- is_visible = not self.regex_filter or self.regex_filter.search(entry.display_message)
- if is_visible:
- snapshot_file.write(entry.display_message + '\n')
+ with self.vals_lock:
+ try:
+ for entry in self.msg_log:
+ is_visible = not self.regex_filter or self.regex_filter.search(entry.display_message)
- self.vals_lock.release()
- except Exception as exc:
- self.vals_lock.release()
- raise exc
+ if is_visible:
+ snapshot_file.write(entry.display_message + '\n')
+ except Exception as exc:
+ raise exc
def handle_key(self, key):
if key.is_scroll():
@@ -597,15 +585,13 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
new_scroll = ui_tools.get_scroll_position(key, self.scroll, page_height, self.last_content_height)
if self.scroll != new_scroll:
- self.vals_lock.acquire()
- self.scroll = new_scroll
- self.redraw(True)
- self.vals_lock.release()
+ with self.vals_lock:
+ self.scroll = new_scroll
+ self.redraw(True)
elif key.match('u'):
- self.vals_lock.acquire()
- self.set_duplicate_visability(not CONFIG['features.log.showDuplicateEntries'])
- self.redraw(True)
- self.vals_lock.release()
+ with self.vals_lock:
+ self.set_duplicate_visability(not CONFIG['features.log.showDuplicateEntries'])
+ self.redraw(True)
elif key.match('c'):
msg = 'This will clear the log. Are you sure (c again to confirm)?'
key_press = nyx.popups.show_msg(msg, attr = curses.A_BOLD)
@@ -669,173 +655,171 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
current_log = self.get_attr('msg_log')
- self.vals_lock.acquire()
- self._last_logged_events, self._last_update = list(current_log), time.time()
+ with self.vals_lock:
+ self._last_logged_events, self._last_update = list(current_log), time.time()
- # draws the top label
+ # draws the top label
- if self.is_title_visible():
- self.addstr(0, 0, self._get_title(width), curses.A_STANDOUT)
+ if self.is_title_visible():
+ self.addstr(0, 0, self._get_title(width), curses.A_STANDOUT)
- # restricts scroll location to valid bounds
+ # restricts scroll location to valid bounds
- self.scroll = max(0, min(self.scroll, self.last_content_height - height + 1))
+ self.scroll = max(0, min(self.scroll, self.last_content_height - height + 1))
- # draws left-hand scroll bar if content's longer than the height
+ # draws left-hand scroll bar if content's longer than the height
- msg_indent, divider_indent = 1, 0 # offsets for scroll bar
- is_scroll_bar_visible = self.last_content_height > height - 1
+ msg_indent, divider_indent = 1, 0 # offsets for scroll bar
+ is_scroll_bar_visible = self.last_content_height > height - 1
- if is_scroll_bar_visible:
- msg_indent, divider_indent = 3, 2
- self.add_scroll_bar(self.scroll, self.scroll + height - 1, self.last_content_height, 1)
+ if is_scroll_bar_visible:
+ msg_indent, divider_indent = 3, 2
+ self.add_scroll_bar(self.scroll, self.scroll + height - 1, self.last_content_height, 1)
- # draws log entries
+ # draws log entries
- line_count = 1 - self.scroll
- seen_first_date_divider = False
- divider_attr, duplicate_attr = (curses.A_BOLD, 'yellow'), (curses.A_BOLD, 'green')
+ line_count = 1 - self.scroll
+ seen_first_date_divider = False
+ divider_attr, duplicate_attr = (curses.A_BOLD, 'yellow'), (curses.A_BOLD, 'green')
- is_dates_shown = self.regex_filter is None and CONFIG['features.log.showDateDividers']
- event_log = get_daybreaks(current_log, self.is_paused()) if is_dates_shown else list(current_log)
+ is_dates_shown = self.regex_filter is None and CONFIG['features.log.showDateDividers']
+ event_log = get_daybreaks(current_log, self.is_paused()) if is_dates_shown else list(current_log)
- if not CONFIG['features.log.showDuplicateEntries']:
- deduplicated_log = get_duplicates(event_log)
+ if not CONFIG['features.log.showDuplicateEntries']:
+ deduplicated_log = get_duplicates(event_log)
- if deduplicated_log is None:
- log.warn('Deduplication took too long. Its current implementation has difficulty handling large logs so disabling it to keep the interface responsive.')
- self.set_duplicate_visability(True)
+ if deduplicated_log is None:
+ log.warn('Deduplication took too long. Its current implementation has difficulty handling large logs so disabling it to keep the interface responsive.')
+ self.set_duplicate_visability(True)
+ deduplicated_log = [(entry, 0) for entry in event_log]
+ else:
deduplicated_log = [(entry, 0) for entry in event_log]
- else:
- deduplicated_log = [(entry, 0) for entry in event_log]
- # determines if we have the minimum width to show date dividers
+ # determines if we have the minimum width to show date dividers
- show_daybreaks = width - divider_indent >= 3
+ show_daybreaks = width - divider_indent >= 3
- while deduplicated_log:
- entry, duplicate_count = deduplicated_log.pop(0)
+ while deduplicated_log:
+ entry, duplicate_count = deduplicated_log.pop(0)
- if self.regex_filter and not self.regex_filter.search(entry.display_message):
- continue # filter doesn't match log message - skip
+ if self.regex_filter and not self.regex_filter.search(entry.display_message):
+ continue # filter doesn't match log message - skip
- # checks if we should be showing a divider with the date
+ # checks if we should be showing a divider with the date
- if entry.type == DAYBREAK_EVENT:
- # bottom of the divider
+ if entry.type == DAYBREAK_EVENT:
+ # bottom of the divider
- if seen_first_date_divider:
- if line_count >= 1 and line_count < height and show_daybreaks:
- self.addch(line_count, divider_indent, curses.ACS_LLCORNER, *divider_attr)
- self.hline(line_count, divider_indent + 1, width - divider_indent - 2, *divider_attr)
- self.addch(line_count, width - 1, curses.ACS_LRCORNER, *divider_attr)
+ if seen_first_date_divider:
+ if line_count >= 1 and line_count < height and show_daybreaks:
+ self.addch(line_count, divider_indent, curses.ACS_LLCORNER, *divider_attr)
+ self.hline(line_count, divider_indent + 1, width - divider_indent - 2, *divider_attr)
+ self.addch(line_count, width - 1, curses.ACS_LRCORNER, *divider_attr)
- line_count += 1
+ line_count += 1
- # top of the divider
+ # top of the divider
- if line_count >= 1 and line_count < height and show_daybreaks:
- time_label = time.strftime(' %B %d, %Y ', time.localtime(entry.timestamp))
- self.addch(line_count, divider_indent, curses.ACS_ULCORNER, *divider_attr)
- self.addch(line_count, divider_indent + 1, curses.ACS_HLINE, *divider_attr)
- self.addstr(line_count, divider_indent + 2, time_label, curses.A_BOLD, *divider_attr)
-
- line_length = width - divider_indent - len(time_label) - 3
- self.hline(line_count, divider_indent + len(time_label) + 2, line_length, *divider_attr)
- self.addch(line_count, divider_indent + len(time_label) + 2 + line_length, curses.ACS_URCORNER, *divider_attr)
-
- seen_first_date_divider = True
- line_count += 1
- else:
- # entry contents to be displayed, tuples of the form:
- # (msg, formatting, includeLinebreak)
-
- display_queue = []
+ if line_count >= 1 and line_count < height and show_daybreaks:
+ time_label = time.strftime(' %B %d, %Y ', time.localtime(entry.timestamp))
+ self.addch(line_count, divider_indent, curses.ACS_ULCORNER, *divider_attr)
+ self.addch(line_count, divider_indent + 1, curses.ACS_HLINE, *divider_attr)
+ self.addstr(line_count, divider_indent + 2, time_label, curses.A_BOLD, *divider_attr)
- msg_comp = entry.display_message.split('\n')
+ line_length = width - divider_indent - len(time_label) - 3
+ self.hline(line_count, divider_indent + len(time_label) + 2, line_length, *divider_attr)
+ self.addch(line_count, divider_indent + len(time_label) + 2 + line_length, curses.ACS_URCORNER, *divider_attr)
- for i in range(len(msg_comp)):
- font = curses.A_BOLD if 'ERR' in entry.type else curses.A_NORMAL # emphasizes ERR messages
- display_queue.append((msg_comp[i].strip(), (font, CONFIG['attr.log_color'].get(entry.type, 'white')), i != len(msg_comp) - 1))
+ seen_first_date_divider = True
+ line_count += 1
+ else:
+ # entry contents to be displayed, tuples of the form:
+ # (msg, formatting, includeLinebreak)
- if duplicate_count:
- plural_label = 's' if duplicate_count > 1 else ''
- duplicate_msg = DUPLICATE_MSG % (duplicate_count, plural_label)
- display_queue.append((duplicate_msg, duplicate_attr, False))
+ display_queue = []
- cursor_location, line_offset = msg_indent, 0
- max_entries_per_line = CONFIG['features.log.max_lines_per_entry']
+ msg_comp = entry.display_message.split('\n')
- while display_queue:
- msg, format, include_break = display_queue.pop(0)
- draw_line = line_count + line_offset
+ for i in range(len(msg_comp)):
+ font = curses.A_BOLD if 'ERR' in entry.type else curses.A_NORMAL # emphasizes ERR messages
+ display_queue.append((msg_comp[i].strip(), (font, CONFIG['attr.log_color'].get(entry.type, 'white')), i != len(msg_comp) - 1))
- if line_offset == max_entries_per_line:
- break
+ if duplicate_count:
+ plural_label = 's' if duplicate_count > 1 else ''
+ duplicate_msg = DUPLICATE_MSG % (duplicate_count, plural_label)
+ display_queue.append((duplicate_msg, duplicate_attr, False))
- max_msg_size = width - cursor_location - 1
+ cursor_location, line_offset = msg_indent, 0
+ max_entries_per_line = CONFIG['features.log.max_lines_per_entry']
- if len(msg) > max_msg_size:
- # message is too long - break it up
- if line_offset == max_entries_per_line - 1:
- msg = str_tools.crop(msg, max_msg_size)
- else:
- msg, remainder = str_tools.crop(msg, max_msg_size, 4, 4, str_tools.Ending.HYPHEN, True)
- display_queue.insert(0, (remainder.strip(), format, include_break))
+ while display_queue:
+ msg, format, include_break = display_queue.pop(0)
+ draw_line = line_count + line_offset
- include_break = True
+ if line_offset == max_entries_per_line:
+ break
- if draw_line < height and draw_line >= 1:
- if seen_first_date_divider and width - divider_indent >= 3 and show_daybreaks:
- self.addch(draw_line, divider_indent, curses.ACS_VLINE, *divider_attr)
- self.addch(draw_line, width - 1, curses.ACS_VLINE, *divider_attr)
+ max_msg_size = width - cursor_location - 1
- self.addstr(draw_line, cursor_location, msg, *format)
+ if len(msg) > max_msg_size:
+ # message is too long - break it up
+ if line_offset == max_entries_per_line - 1:
+ msg = str_tools.crop(msg, max_msg_size)
+ else:
+ msg, remainder = str_tools.crop(msg, max_msg_size, 4, 4, str_tools.Ending.HYPHEN, True)
+ display_queue.insert(0, (remainder.strip(), format, include_break))
- cursor_location += len(msg)
+ include_break = True
- if include_break or not display_queue:
- line_offset += 1
- cursor_location = msg_indent + ENTRY_INDENT
+ if draw_line < height and draw_line >= 1:
+ if seen_first_date_divider and width - divider_indent >= 3 and show_daybreaks:
+ self.addch(draw_line, divider_indent, curses.ACS_VLINE, *divider_attr)
+ self.addch(draw_line, width - 1, curses.ACS_VLINE, *divider_attr)
- line_count += line_offset
+ self.addstr(draw_line, cursor_location, msg, *format)
- # if this is the last line and there's room, then draw the bottom of the divider
+ cursor_location += len(msg)
- if not deduplicated_log and seen_first_date_divider:
- if line_count < height and show_daybreaks:
- self.addch(line_count, divider_indent, curses.ACS_LLCORNER, *divider_attr)
- self.hline(line_count, divider_indent + 1, width - divider_indent - 2, *divider_attr)
- self.addch(line_count, width - 1, curses.ACS_LRCORNER, *divider_attr)
+ if include_break or not display_queue:
+ line_offset += 1
+ cursor_location = msg_indent + ENTRY_INDENT
- line_count += 1
+ line_count += line_offset
- # redraw the display if...
- # - last_content_height was off by too much
- # - we're off the bottom of the page
+ # if this is the last line and there's room, then draw the bottom of the divider
- new_content_height = line_count + self.scroll - 1
- content_height_delta = abs(self.last_content_height - new_content_height)
- force_redraw, force_redraw_reason = True, ''
+ if not deduplicated_log and seen_first_date_divider:
+ if line_count < height and show_daybreaks:
+ self.addch(line_count, divider_indent, curses.ACS_LLCORNER, *divider_attr)
+ self.hline(line_count, divider_indent + 1, width - divider_indent - 2, *divider_attr)
+ self.addch(line_count, width - 1, curses.ACS_LRCORNER, *divider_attr)
- if content_height_delta >= CONTENT_HEIGHT_REDRAW_THRESHOLD:
- force_redraw_reason = 'estimate was off by %i' % content_height_delta
- elif new_content_height > height and self.scroll + height - 1 > new_content_height:
- force_redraw_reason = 'scrolled off the bottom of the page'
- elif not is_scroll_bar_visible and new_content_height > height - 1:
- force_redraw_reason = "scroll bar wasn't previously visible"
- elif is_scroll_bar_visible and new_content_height <= height - 1:
- force_redraw_reason = "scroll bar shouldn't be visible"
- else:
- force_redraw = False
+ line_count += 1
- self.last_content_height = new_content_height
+ # redraw the display if...
+ # - last_content_height was off by too much
+ # - we're off the bottom of the page
+
+ new_content_height = line_count + self.scroll - 1
+ content_height_delta = abs(self.last_content_height - new_content_height)
+ force_redraw, force_redraw_reason = True, ''
+
+ if content_height_delta >= CONTENT_HEIGHT_REDRAW_THRESHOLD:
+ force_redraw_reason = 'estimate was off by %i' % content_height_delta
+ elif new_content_height > height and self.scroll + height - 1 > new_content_height:
+ force_redraw_reason = 'scrolled off the bottom of the page'
+ elif not is_scroll_bar_visible and new_content_height > height - 1:
+ force_redraw_reason = "scroll bar wasn't previously visible"
+ elif is_scroll_bar_visible and new_content_height <= height - 1:
+ force_redraw_reason = "scroll bar shouldn't be visible"
+ else:
+ force_redraw = False
- if force_redraw:
- log.debug('redrawing the log panel with the corrected content height (%s)' % force_redraw_reason)
- self.redraw(True)
+ self.last_content_height = new_content_height
- self.vals_lock.release()
+ if force_redraw:
+ 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
@@ -957,110 +941,108 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
# usually the attributes used to make the label are decently static, so
# provide cached results if they're unchanged
- self.vals_lock.acquire()
- current_pattern = self.regex_filter.pattern if self.regex_filter else None
- is_unchanged = self._title_args[0] == self.logged_events
- is_unchanged &= self._title_args[1] == current_pattern
- is_unchanged &= self._title_args[2] == width
+ with self.vals_lock:
+ current_pattern = self.regex_filter.pattern if self.regex_filter else None
+ is_unchanged = self._title_args[0] == self.logged_events
+ is_unchanged &= self._title_args[1] == current_pattern
+ is_unchanged &= self._title_args[2] == width
- if is_unchanged:
- self.vals_lock.release()
- return self._title_cache
+ if is_unchanged:
+ return self._title_cache
- events_list = list(self.logged_events)
+ events_list = list(self.logged_events)
- if not events_list:
- if not current_pattern:
- panel_label = 'Events:'
+ if not events_list:
+ if not current_pattern:
+ panel_label = 'Events:'
+ else:
+ label_pattern = str_tools.crop(current_pattern, width - 18)
+ panel_label = 'Events (filter: %s):' % label_pattern
else:
- label_pattern = str_tools.crop(current_pattern, width - 18)
- panel_label = 'Events (filter: %s):' % label_pattern
- else:
- # does the following with all runlevel types (tor, nyx, and stem):
- # - pulls to the start of the list
- # - condenses range if there's three or more in a row (ex. "NYX_INFO - WARN")
- # - condense further if there's identical runlevel ranges for multiple
- # types (ex. "NOTICE - ERR, NYX_NOTICE - ERR" becomes "TOR/NYX NOTICE - ERR")
-
- tmp_runlevels = [] # runlevels pulled from the list (just the runlevel part)
- runlevel_ranges = [] # tuple of type, start_level, end_level for ranges to be consensed
-
- # reverses runlevels and types so they're appended in the right order
-
- reversed_runlevels = list(log.Runlevel)
- reversed_runlevels.reverse()
-
- for prefix in ('NYX_', ''):
- # blank ending runlevel forces the break condition to be reached at the end
- for runlevel in reversed_runlevels + ['']:
- event_type = prefix + runlevel
- if runlevel and event_type in events_list:
- # runlevel event found, move to the tmp list
- events_list.remove(event_type)
- tmp_runlevels.append(runlevel)
- elif tmp_runlevels:
- # adds all tmp list entries to the start of events_list
- if len(tmp_runlevels) >= 3:
- # save condense sequential runlevels to be added later
- runlevel_ranges.append((prefix, tmp_runlevels[-1], tmp_runlevels[0]))
- else:
- # adds runlevels individaully
- for tmp_runlevel in tmp_runlevels:
- events_list.insert(0, prefix + tmp_runlevel)
+ # does the following with all runlevel types (tor, nyx, and stem):
+ # - pulls to the start of the list
+ # - condenses range if there's three or more in a row (ex. "NYX_INFO - WARN")
+ # - condense further if there's identical runlevel ranges for multiple
+ # types (ex. "NOTICE - ERR, NYX_NOTICE - ERR" becomes "TOR/NYX NOTICE - ERR")
+
+ tmp_runlevels = [] # runlevels pulled from the list (just the runlevel part)
+ runlevel_ranges = [] # tuple of type, start_level, end_level for ranges to be consensed
+
+ # reverses runlevels and types so they're appended in the right order
+
+ reversed_runlevels = list(log.Runlevel)
+ reversed_runlevels.reverse()
+
+ for prefix in ('NYX_', ''):
+ # blank ending runlevel forces the break condition to be reached at the end
+ for runlevel in reversed_runlevels + ['']:
+ event_type = prefix + runlevel
+ if runlevel and event_type in events_list:
+ # runlevel event found, move to the tmp list
+ events_list.remove(event_type)
+ tmp_runlevels.append(runlevel)
+ elif tmp_runlevels:
+ # adds all tmp list entries to the start of events_list
+ if len(tmp_runlevels) >= 3:
+ # save condense sequential runlevels to be added later
+ runlevel_ranges.append((prefix, tmp_runlevels[-1], tmp_runlevels[0]))
+ else:
+ # adds runlevels individaully
+ for tmp_runlevel in tmp_runlevels:
+ events_list.insert(0, prefix + tmp_runlevel)
- tmp_runlevels = []
+ tmp_runlevels = []
- # adds runlevel ranges, condensing if there's identical ranges
+ # adds runlevel ranges, condensing if there's identical ranges
- for i in range(len(runlevel_ranges)):
- if runlevel_ranges[i]:
- prefix, start_level, end_level = runlevel_ranges[i]
+ for i in range(len(runlevel_ranges)):
+ if runlevel_ranges[i]:
+ prefix, start_level, end_level = runlevel_ranges[i]
- # check for matching ranges
+ # check for matching ranges
- matches = []
+ matches = []
- for j in range(i + 1, len(runlevel_ranges)):
- if runlevel_ranges[j] and runlevel_ranges[j][1] == start_level and runlevel_ranges[j][2] == end_level:
- matches.append(runlevel_ranges[j])
- runlevel_ranges[j] = None
+ for j in range(i + 1, len(runlevel_ranges)):
+ if runlevel_ranges[j] and runlevel_ranges[j][1] == start_level and runlevel_ranges[j][2] == end_level:
+ matches.append(runlevel_ranges[j])
+ runlevel_ranges[j] = None
- if matches:
- # strips underscores and replaces empty entries with "TOR"
+ if matches:
+ # strips underscores and replaces empty entries with "TOR"
- prefixes = [entry[0] for entry in matches] + [prefix]
+ prefixes = [entry[0] for entry in matches] + [prefix]
- for k in range(len(prefixes)):
- if prefixes[k] == '':
- prefixes[k] = 'TOR'
- else:
- prefixes[k] = prefixes[k].replace('_', '')
+ for k in range(len(prefixes)):
+ if prefixes[k] == '':
+ prefixes[k] = 'TOR'
+ else:
+ prefixes[k] = prefixes[k].replace('_', '')
- events_list.insert(0, '%s %s - %s' % ('/'.join(prefixes), start_level, end_level))
- else:
- events_list.insert(0, '%s%s - %s' % (prefix, start_level, end_level))
+ events_list.insert(0, '%s %s - %s' % ('/'.join(prefixes), start_level, end_level))
+ else:
+ events_list.insert(0, '%s%s - %s' % (prefix, start_level, end_level))
- # truncates to use an ellipsis if too long, for instance:
+ # truncates to use an ellipsis if too long, for instance:
- attr_label = ', '.join(events_list)
+ attr_label = ', '.join(events_list)
- if current_pattern:
- attr_label += ' - filter: %s' % current_pattern
+ if current_pattern:
+ attr_label += ' - filter: %s' % current_pattern
- attr_label = str_tools.crop(attr_label, width - 10, 1)
+ attr_label = str_tools.crop(attr_label, width - 10, 1)
- if attr_label:
- attr_label = ' (%s)' % attr_label
+ if attr_label:
+ attr_label = ' (%s)' % attr_label
- panel_label = 'Events%s:' % attr_label
+ panel_label = 'Events%s:' % attr_label
- # cache results and return
+ # cache results and return
- self._title_cache = panel_label
- self._title_args = (list(self.logged_events), current_pattern, width)
- self.vals_lock.release()
+ self._title_cache = panel_label
+ self._title_args = (list(self.logged_events), current_pattern, width)
- return panel_label
+ return panel_label
def _trim_events(self, event_listing):
"""
More information about the tor-commits
mailing list