commit 38a3189f240ed6151c1c7b414a02ee3898a2a3eb Author: Damian Johnson atagar@torproject.org Date: Sun Oct 5 16:37:25 2014 -0700
Standardizing help and key input panel methods
Few minor bits of standarization...
* use the 'with' keyword for locking * use 'in' for evaluating againt multiple key inputs * drop the 'key_consumed' variable * return a list in the help function rather than repeatedly calling append() --- arm/config_panel.py | 143 ++++++++++++++++++++--------------------- arm/connections/conn_panel.py | 132 ++++++++++++++++++------------------- arm/controller.py | 10 +-- arm/graphing/graph_panel.py | 31 ++++----- arm/header_panel.py | 6 +- arm/log_panel.py | 32 +++++---- arm/torrc_panel.py | 56 ++++++++-------- 7 files changed, 192 insertions(+), 218 deletions(-)
diff --git a/arm/config_panel.py b/arm/config_panel.py index c2dac4b..637b354 100644 --- a/arm/config_panel.py +++ b/arm/config_panel.py @@ -360,81 +360,74 @@ class ConfigPanel(panel.Panel): self.set_sort_order(result_enums)
def handle_key(self, key): - self.vals_lock.acquire() - is_keystroke_consumed = True + with self.vals_lock: + if ui_tools.is_scroll_key(key): + page_height = self.get_preferred_size()[0] - 1 + detail_panel_height = CONFIG["features.config.selectionDetails.height"]
- if ui_tools.is_scroll_key(key): - page_height = self.get_preferred_size()[0] - 1 - detail_panel_height = CONFIG["features.config.selectionDetails.height"] + if detail_panel_height > 0 and detail_panel_height + 2 <= page_height: + page_height -= (detail_panel_height + 1)
- if detail_panel_height > 0 and detail_panel_height + 2 <= page_height: - page_height -= (detail_panel_height + 1) + is_changed = self.scroller.handle_key(key, self._get_config_options(), page_height)
- is_changed = self.scroller.handle_key(key, self._get_config_options(), page_height) + if is_changed: + self.redraw(True) + elif ui_tools.is_selection_key(key) and self._get_config_options(): + # Prompts the user to edit the selected configuration value. The + # interface is locked to prevent updates between setting the value + # and showing any errors.
- if is_changed: - self.redraw(True) - elif ui_tools.is_selection_key(key) and self._get_config_options(): - # Prompts the user to edit the selected configuration value. The - # interface is locked to prevent updates between setting the value - # and showing any errors. + with panel.CURSES_LOCK: + selection = self.get_selection() + config_option = selection.get(Field.OPTION)
- panel.CURSES_LOCK.acquire() + if selection.is_unset(): + initial_value = "" + else: + initial_value = selection.get(Field.VALUE)
- try: - selection = self.get_selection() - config_option = selection.get(Field.OPTION) + prompt_msg = "%s Value (esc to cancel): " % config_option + is_prepopulated = CONFIG["features.config.prepopulateEditValues"] + new_value = popups.input_prompt(prompt_msg, initial_value if is_prepopulated else "")
- if selection.is_unset(): - initial_value = "" - else: - initial_value = selection.get(Field.VALUE) + if new_value is not None and new_value != initial_value: + try: + if selection.get(Field.TYPE) == "Boolean": + # if the value's a boolean then allow for 'true' and 'false' inputs
- prompt_msg = "%s Value (esc to cancel): " % config_option - is_prepopulated = CONFIG["features.config.prepopulateEditValues"] - new_value = popups.input_prompt(prompt_msg, initial_value if is_prepopulated else "") + if new_value.lower() == "true": + new_value = "1" + elif new_value.lower() == "false": + new_value = "0" + elif selection.get(Field.TYPE) == "LineList": + # set_option accepts list inputs when there's multiple values + new_value = new_value.split(",")
- if new_value is not None and new_value != initial_value: - try: - if selection.get(Field.TYPE) == "Boolean": - # if the value's a boolean then allow for 'true' and 'false' inputs - - if new_value.lower() == "true": - new_value = "1" - elif new_value.lower() == "false": - new_value = "0" - elif selection.get(Field.TYPE) == "LineList": - # set_option accepts list inputs when there's multiple values - new_value = new_value.split(",") - - tor_controller().set_conf(config_option, new_value) - - # forces the label to be remade with the new value - - selection.label_cache = None - - # resets the is_default flag - - custom_options = tor_config.get_custom_options() - selection.fields[Field.IS_DEFAULT] = config_option not in custom_options - - self.redraw(True) - except Exception as exc: - popups.show_msg("%s (press any key)" % exc) - finally: - panel.CURSES_LOCK.release() - elif key == ord('a') or key == ord('A'): - self.show_all = not self.show_all - self.redraw(True) - elif key == ord('s') or key == ord('S'): - self.show_sort_dialog() - elif key == ord('v') or key == ord('V'): - self.show_write_dialog() - else: - is_keystroke_consumed = False + tor_controller().set_conf(config_option, new_value)
- self.vals_lock.release() - return is_keystroke_consumed + # forces the label to be remade with the new value + + selection.label_cache = None + + # resets the is_default flag + + custom_options = tor_config.get_custom_options() + selection.fields[Field.IS_DEFAULT] = config_option not in custom_options + + self.redraw(True) + except Exception as exc: + popups.show_msg("%s (press any key)" % exc) + elif key in (ord('a'), ord('A')): + self.show_all = not self.show_all + self.redraw(True) + elif key in (ord('s'), ord('S')): + self.show_sort_dialog() + elif key in (ord('v'), ord('V')): + self.show_write_dialog() + else: + return False + + return True
def show_write_dialog(self): """ @@ -566,16 +559,16 @@ class ConfigPanel(panel.Panel): popups.finalize()
def get_help(self): - options = [] - options.append(("up arrow", "scroll up a line", None)) - options.append(("down arrow", "scroll down a line", None)) - options.append(("page up", "scroll up a page", None)) - options.append(("page down", "scroll down a page", None)) - options.append(("enter", "edit configuration option", None)) - options.append(("v", "save configuration", None)) - options.append(("a", "toggle option filtering", None)) - options.append(("s", "sort ordering", None)) - return options + return [ + ('up arrow', 'scroll up a line', None), + ('down arrow', 'scroll down a line', None), + ('page up', 'scroll up a page', None), + ('page down', 'scroll down a page', None), + ('enter', 'edit configuration option', None), + ('v', 'save configuration', None), + ('a', 'toggle option filtering', None), + ('s', 'sort ordering', None), + ]
def draw(self, width, height): self.vals_lock.acquire() diff --git a/arm/connections/conn_panel.py b/arm/connections/conn_panel.py index 8168572..57c64f5 100644 --- a/arm/connections/conn_panel.py +++ b/arm/connections/conn_panel.py @@ -261,75 +261,71 @@ class ConnectionPanel(panel.Panel, threading.Thread): self.set_sort_order(results)
def handle_key(self, key): - self.vals_lock.acquire() + with self.vals_lock: + if ui_tools.is_scroll_key(key): + page_height = self.get_preferred_size()[0] - 1
- is_keystroke_consumed = True + if self._show_details: + page_height -= (DETAILS_HEIGHT + 1)
- if ui_tools.is_scroll_key(key): - page_height = self.get_preferred_size()[0] - 1 + is_changed = self._scroller.handle_key(key, self._entry_lines, page_height)
- if self._show_details: - page_height -= (DETAILS_HEIGHT + 1) + if is_changed: + self.redraw(True) + elif ui_tools.is_selection_key(key): + self._show_details = not self._show_details + self.redraw(True) + elif key in (ord('s'), ord('S')): + self.show_sort_dialog() + elif key in (ord('u'), ord('U')): + # provides a menu to pick the connection resolver
- is_changed = self._scroller.handle_key(key, self._entry_lines, page_height) + title = "Resolver Util:" + options = ["auto"] + list(connection.Resolver) + conn_resolver = arm.util.tracker.get_connection_tracker()
- if is_changed: - self.redraw(True) - elif ui_tools.is_selection_key(key): - self._show_details = not self._show_details - self.redraw(True) - elif key == ord('s') or key == ord('S'): - self.show_sort_dialog() - elif key == ord('u') or key == ord('U'): - # provides a menu to pick the connection resolver - - title = "Resolver Util:" - options = ["auto"] + list(connection.Resolver) - conn_resolver = arm.util.tracker.get_connection_tracker() - - current_overwrite = conn_resolver.get_custom_resolver() - - if current_overwrite is None: - old_selection = 0 - else: - old_selection = options.index(current_overwrite) + current_overwrite = conn_resolver.get_custom_resolver()
- selection = arm.popups.show_menu(title, options, old_selection) + if current_overwrite is None: + old_selection = 0 + else: + old_selection = options.index(current_overwrite)
- # applies new setting + selection = arm.popups.show_menu(title, options, old_selection)
- if selection != -1: - selected_option = options[selection] if selection != 0 else None - conn_resolver.set_custom_resolver(selected_option) - elif key == ord('l') or key == ord('L'): - # provides a menu to pick the primary information we list connections by + # applies new setting
- title = "List By:" - options = list(entries.ListingType) + if selection != -1: + selected_option = options[selection] if selection != 0 else None + conn_resolver.set_custom_resolver(selected_option) + elif key in (ord('l'), ord('L')): + # provides a menu to pick the primary information we list connections by
- # dropping the HOSTNAME listing type until we support displaying that content + title = "List By:" + options = list(entries.ListingType)
- options.remove(arm.connections.entries.ListingType.HOSTNAME) + # dropping the HOSTNAME listing type until we support displaying that content
- old_selection = options.index(self.get_listing_type()) - selection = arm.popups.show_menu(title, options, old_selection) + options.remove(arm.connections.entries.ListingType.HOSTNAME)
- # applies new setting + old_selection = options.index(self.get_listing_type()) + selection = arm.popups.show_menu(title, options, old_selection)
- if selection != -1: - self.set_listing_type(options[selection]) - elif key == ord('d') or key == ord('D'): - # presents popup for raw consensus data - descriptor_popup.show_descriptor_popup(self) - elif (key == ord('c') or key == ord('C')) and self.is_clients_allowed(): - count_popup.showCountDialog(count_popup.CountType.CLIENT_LOCALE, self._client_locale_usage) - elif (key == ord('e') or key == ord('E')) and self.is_exits_allowed(): - count_popup.showCountDialog(count_popup.CountType.EXIT_PORT, self._exit_port_usage) - else: - is_keystroke_consumed = False + # applies new setting
- self.vals_lock.release() - return is_keystroke_consumed + if selection != -1: + self.set_listing_type(options[selection]) + elif key in (ord('d'), ord('D')): + # presents popup for raw consensus data + descriptor_popup.show_descriptor_popup(self) + elif key in (ord('c'), ord('C')) and self.is_clients_allowed(): + count_popup.showCountDialog(count_popup.CountType.CLIENT_LOCALE, self._client_locale_usage) + elif key in (ord('e'), ord('E')) and self.is_exits_allowed(): + count_popup.showCountDialog(count_popup.CountType.EXIT_PORT, self._exit_port_usage) + else: + return False + + return True
def run(self): """ @@ -373,26 +369,24 @@ class ConnectionPanel(panel.Panel, threading.Thread): def get_help(self): resolver_util = arm.util.tracker.get_connection_tracker().get_custom_resolver()
- if resolver_util is None: - resolver_util = "auto" - - options = [] - options.append(("up arrow", "scroll up a line", None)) - options.append(("down arrow", "scroll down a line", None)) - options.append(("page up", "scroll up a page", None)) - options.append(("page down", "scroll down a page", None)) - options.append(("enter", "show connection details", None)) - options.append(("d", "raw consensus descriptor", None)) + options = [ + ('up arrow', 'scroll up a line', None), + ('down arrow', 'scroll down a line', None), + ('page up', 'scroll up a page', None), + ('page down', 'scroll down a page', None), + ('enter', 'show connection details', None), + ('d', 'raw consensus descriptor', None), + ]
if self.is_clients_allowed(): - options.append(("c", "client locale usage summary", None)) + options.append(('c', 'client locale usage summary', None))
if self.is_exits_allowed(): - options.append(("e", "exit port usage summary", None)) + options.append(('e', 'exit port usage summary', None))
- options.append(("l", "listed identity", self.get_listing_type().lower())) - options.append(("s", "sort ordering", None)) - options.append(("u", "resolving utility", resolver_util)) + options.append(('l', 'listed identity', self.get_listing_type().lower())) + options.append(('s', 'sort ordering', None)) + options.append(('u', 'resolving utility', 'auto' if resolver_util is None else resolver_util)) return options
def get_selection(self): diff --git a/arm/controller.py b/arm/controller.py index cb0cf3e..09f0f83 100644 --- a/arm/controller.py +++ b/arm/controller.py @@ -658,11 +658,11 @@ def start_arm(stdscr): control.next_page() elif key == curses.KEY_LEFT: control.prev_page() - elif key == ord('p') or key == ord('P'): + elif key in (ord('p'), ord('P')): control.set_paused(not control.is_paused()) - elif key == ord('m') or key == ord('M'): + elif key in (ord('m'), ord('M')): arm.menu.menu.show_menu() - elif key == ord('q') or key == ord('Q'): + elif key in (ord('q'), ord('Q')): # provides prompt to confirm that arm should exit
if CONFIG["features.confirmQuit"]: @@ -674,7 +674,7 @@ def start_arm(stdscr):
if quit_confirmed: control.quit() - elif key == ord('x') or key == ord('X'): + elif key in (ord('x'), ord('X')): # provides prompt to confirm that arm should issue a sighup
msg = "This will reset Tor's internal state. Are you sure (x again to confirm)?" @@ -685,7 +685,7 @@ def start_arm(stdscr): tor_controller().signal(stem.Signal.RELOAD) except IOError as exc: log.error("Error detected when reloading tor: %s" % exc.strerror) - elif key == ord('h') or key == ord('H'): + elif key in (ord('h'), ord('H')): override_key = arm.popups.show_help_popup() elif key == ord('l') - 96: # force redraw when ctrl+l is pressed diff --git a/arm/graphing/graph_panel.py b/arm/graphing/graph_panel.py index fc7f7cf..68328b8 100644 --- a/arm/graphing/graph_panel.py +++ b/arm/graphing/graph_panel.py @@ -344,15 +344,13 @@ class GraphPanel(panel.Panel): panel.CURSES_LOCK.release()
def handle_key(self, key): - is_keystroke_consumed = True - - if key == ord('r') or key == ord('R'): + if key in (ord('r'), ord('R')): self.resize_graph() - elif key == ord('b') or key == ord('B'): + elif key in (ord('b'), ord('B')): # uses the next boundary type self.bounds = Bounds.next(self.bounds) self.redraw(True) - elif key == ord('s') or key == ord('S'): + elif key in (ord('s'), ord('S')): # provides a menu to pick the graphed stats
available_stats = self.stats.keys() @@ -379,7 +377,7 @@ class GraphPanel(panel.Panel): self.set_stats(None) elif selection != -1: self.set_stats(available_stats[selection - 1]) - elif key == ord('i') or key == ord('I'): + elif key in (ord('i'), ord('I')): # provides menu to pick graph panel update interval
options = [label for (label, _) in UPDATE_INTERVALS] @@ -388,22 +386,17 @@ class GraphPanel(panel.Panel): if selection != -1: self.update_interval = selection else: - is_keystroke_consumed = False + return False
- return is_keystroke_consumed + return True
def get_help(self): - if self.current_display: - graphed_stats = self.current_display - else: - graphed_stats = 'none' - - options = [] - options.append(('r', 'resize graph', None)) - options.append(('s', 'graphed stats', graphed_stats)) - options.append(('b', 'graph bounds', self.bounds.lower())) - options.append(('i', 'graph update interval', UPDATE_INTERVALS[self.update_interval][0])) - return options + return [ + ('r', 'resize graph', None), + ('s', 'graphed stats', self.current_display if self.current_display else 'none'), + ('b', 'graph bounds', self.bounds.lower()), + ('i', 'graph update interval', UPDATE_INTERVALS[self.update_interval][0]), + ]
def draw(self, width, height): """ Redraws graph panel """ diff --git a/arm/header_panel.py b/arm/header_panel.py index 9b8ecd2..5278ca1 100644 --- a/arm/header_panel.py +++ b/arm/header_panel.py @@ -87,8 +87,6 @@ class HeaderPanel(panel.Panel, threading.Thread): arm.popups.show_msg('Requesting a new identity', 1)
def handle_key(self, key): - is_keystroke_consumed = True - if key in (ord('n'), ord('N')): self.send_newnym() elif key in (ord('r'), ord('R')) and not self._vals.is_connected: @@ -120,9 +118,9 @@ class HeaderPanel(panel.Panel, threading.Thread): arm.popups.show_msg('Unable to reconnect (%s)' % exc, 3) controller.close() else: - is_keystroke_consumed = False + return False
- return is_keystroke_consumed + return True
def draw(self, width, height): vals = self._vals # local reference to avoid concurrency concerns diff --git a/arm/log_panel.py b/arm/log_panel.py index 6f5087b..e78ecc7 100644 --- a/arm/log_panel.py +++ b/arm/log_panel.py @@ -863,8 +863,6 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler): raise exc
def handle_key(self, key): - is_keystroke_consumed = True - if ui_tools.is_scroll_key(key): page_height = self.get_preferred_size()[0] - 1 new_scroll = ui_tools.get_scroll_position(key, self.scroll, page_height, self.last_content_height) @@ -879,13 +877,13 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler): self.set_duplicate_visability(not CONFIG["features.log.showDuplicateEntries"]) self.redraw(True) self.vals_lock.release() - elif key == ord('c') or key == ord('C'): + elif key in (ord('c'), ord('C')): msg = "This will clear the log. Are you sure (c again to confirm)?" key_press = arm.popups.show_msg(msg, attr = curses.A_BOLD)
if key_press in (ord('c'), ord('C')): self.clear() - elif key == ord('f') or key == ord('F'): + elif key in (ord('f'), ord('F')): # Provides menu to pick regular expression filters or adding new ones: # for syntax see: http://docs.python.org/library/re.html#regular-expression-syntax
@@ -914,25 +912,25 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler):
if len(self.filter_options) > MAX_REGEX_FILTERS: del self.filter_options[MAX_REGEX_FILTERS:] - elif key == ord('e') or key == ord('E'): + elif key in (ord('e'), ord('E')): self.show_event_selection_prompt() - elif key == ord('a') or key == ord('A'): + elif key in (ord('a'), ord('A')): self.show_snapshot_prompt() else: - is_keystroke_consumed = False + return False
- return is_keystroke_consumed + return True
def get_help(self): - options = [] - options.append(("up arrow", "scroll log up a line", None)) - options.append(("down arrow", "scroll log down a line", None)) - options.append(("a", "save snapshot of the log", None)) - options.append(("e", "change logged events", None)) - options.append(("f", "log regex filter", "enabled" if self.regex_filter else "disabled")) - options.append(("u", "duplicate log entries", "visible" if CONFIG["features.log.showDuplicateEntries"] else "hidden")) - options.append(("c", "clear event log", None)) - return options + return [ + ('up arrow', 'scroll log up a line', None), + ('down arrow', 'scroll log down a line', None), + ('a', 'save snapshot of the log', None), + ('e', 'change logged events', None), + ('f', 'log regex filter', 'enabled' if self.regex_filter else 'disabled'), + ('u', 'duplicate log entries', 'visible' if CONFIG['features.log.showDuplicateEntries'] else 'hidden'), + ('c', 'clear event log', None), + ]
def draw(self, width, height): """ diff --git a/arm/torrc_panel.py b/arm/torrc_panel.py index 6dfaf17..2a3fb23 100644 --- a/arm/torrc_panel.py +++ b/arm/torrc_panel.py @@ -122,26 +122,24 @@ class TorrcPanel(panel.Panel): arm.popups.show_msg(result_msg, 1)
def handle_key(self, key): - self.vals_lock.acquire() - is_keystroke_consumed = True - if ui_tools.is_scroll_key(key): - page_height = self.get_preferred_size()[0] - 1 - new_scroll = ui_tools.get_scroll_position(key, self.scroll, page_height, self._last_content_height) - - if self.scroll != new_scroll: - self.scroll = new_scroll - self.redraw(True) - elif key == ord('n') or key == ord('N'): - self.set_line_number_visible(not self.show_line_num) - elif key == ord('s') or key == ord('S'): - self.set_comments_visible(self.strip_comments) - elif key == ord('r') or key == ord('R'): - self.reload_torrc() - else: - is_keystroke_consumed = False + with self.vals_lock: + if ui_tools.is_scroll_key(key): + page_height = self.get_preferred_size()[0] - 1 + new_scroll = ui_tools.get_scroll_position(key, self.scroll, page_height, self._last_content_height) + + if self.scroll != new_scroll: + self.scroll = new_scroll + self.redraw(True) + elif key in (ord('n'), ord('N')): + self.set_line_number_visible(not self.show_line_num) + elif key in (ord('s'), ord('S')): + self.set_comments_visible(self.strip_comments) + elif key in (ord('r'), ord('R')): + self.reload_torrc() + else: + return False
- self.vals_lock.release() - return is_keystroke_consumed + return True
def set_visible(self, is_visible): if not is_visible: @@ -150,16 +148,16 @@ class TorrcPanel(panel.Panel): panel.Panel.set_visible(self, is_visible)
def get_help(self): - options = [] - options.append(("up arrow", "scroll up a line", None)) - options.append(("down arrow", "scroll down a line", None)) - options.append(("page up", "scroll up a page", None)) - options.append(("page down", "scroll down a page", None)) - options.append(("s", "comment stripping", "on" if self.strip_comments else "off")) - options.append(("n", "line numbering", "on" if self.show_line_num else "off")) - options.append(("r", "reload torrc", None)) - options.append(("x", "reset tor (issue sighup)", None)) - return options + return [ + ('up arrow', 'scroll up a line', None), + ('down arrow', 'scroll down a line', None), + ('page up', 'scroll up a page', None), + ('page down', 'scroll down a page', None), + ('s', 'comment stripping', 'on' if self.strip_comments else 'off'), + ('n', 'line numbering', 'on' if self.show_line_num else 'off'), + ('r', 'reload torrc', None), + ('x', 'reset tor (issue sighup)', None), + ]
def draw(self, width, height): self.vals_lock.acquire()