commit b02b595cda76428723e000082089cc0270d47298 Author: Damian Johnson atagar@torproject.org Date: Sun Oct 25 13:46:21 2015 -0700
Use methods for ConfigEntry attributes rather than a single get()
To get all attributes we had a single ConfigEntry get() method that took an enum. This was done to avoid needing a separate sort_value() method. Fine idea, but clunky.
Our connection panel has a sort_value(), that's fine. Also we'll be moving much of this to Stem, in which case proper methods jive better. --- nyx/config/attributes.cfg | 16 ++-- nyx/config_panel.py | 190 +++++++++++++++++++++++++++------------------ nyx/connection_panel.py | 5 +- 3 files changed, 122 insertions(+), 89 deletions(-)
diff --git a/nyx/config/attributes.cfg b/nyx/config/attributes.cfg index 39faa1e..3685673 100644 --- a/nyx/config/attributes.cfg +++ b/nyx/config/attributes.cfg @@ -84,11 +84,11 @@ attr.config.category_color Hidden Service => cyan attr.config.category_color Testing => white attr.config.category_color Unknown => white
-attr.config.field_color Category => red -attr.config.field_color Option Name => blue -attr.config.field_color Value => cyan -attr.config.field_color Arg Type => green -attr.config.field_color Arg Usage => yellow -attr.config.field_color Summary => green -attr.config.field_color Description => white -attr.config.field_color Man Page Entry => blue +attr.config.sort_color Option => blue +attr.config.sort_color Value => cyan +attr.config.sort_color Value Type => green +attr.config.sort_color Category => red +attr.config.sort_color Usage => yellow +attr.config.sort_color Summary => green +attr.config.sort_color Description => white +attr.config.sort_color Man Page Entry => blue diff --git a/nyx/config_panel.py b/nyx/config_panel.py index b5c42e2..2e5d0f2 100644 --- a/nyx/config_panel.py +++ b/nyx/config_panel.py @@ -14,19 +14,7 @@ from nyx.util import panel, tor_config, tor_controller, ui_tools from stem.control import State from stem.util import conf, enum, str_tools
-# attributes of a ConfigEntry - -Field = enum.Enum( - ('CATEGORY', 'Category'), - ('OPTION', 'Option Name'), - ('VALUE', 'Value'), - ('TYPE', 'Arg Type'), - ('ARG_USAGE', 'Arg Usage'), - ('SUMMARY', 'Summary'), - ('DESCRIPTION', 'Description'), - ('MAN_ENTRY', 'Man Page Entry'), - ('IS_SET', 'Is Set'), -) +SortAttr = enum.Enum('OPTION', 'VALUE', 'VALUE_TYPE', 'CATEGORY', 'USAGE', 'SUMMARY', 'DESCRIPTION', 'MAN_PAGE_ENTRY', 'IS_SET')
DETAILS_HEIGHT = 6 OPTION_WIDTH = 25 @@ -35,13 +23,13 @@ VALUE_WIDTH = 15
def conf_handler(key, value): if key == 'features.config.order': - return conf.parse_enum_csv(key, value[0], Field, 3) + return conf.parse_enum_csv(key, value[0], SortAttr, 3)
CONFIG = conf.config_dict('nyx', { 'attr.config.category_color': {}, - 'attr.config.field_color': {}, - 'features.config.order': [Field.MAN_ENTRY, Field.OPTION, Field.IS_SET], + 'attr.config.sort_color': {}, + 'features.config.order': [SortAttr.MAN_PAGE_ENTRY, SortAttr.OPTION, SortAttr.IS_SET], 'features.config.state.showPrivateOptions': False, 'features.config.state.showVirtualOptions': False, }, conf_handler) @@ -53,70 +41,120 @@ class ConfigEntry(): """
def __init__(self, option, entry_type): - man_entry = tor_config.get_config_description(option) + self._option = option + self._value_type = entry_type + self._man_entry = tor_config.get_config_description(option)
- self._fields = { - Field.OPTION: option, - Field.TYPE: entry_type, - Field.SUMMARY: tor_config.get_config_summary(option), - - Field.MAN_ENTRY: man_entry.index if man_entry else 99999, # sorts non-man entries last - Field.CATEGORY: man_entry.category if man_entry else tor_config.Category.UNKNOWN, - Field.ARG_USAGE: man_entry.arg_usage if man_entry else '', - Field.DESCRIPTION: man_entry.description if man_entry else '', - } - - # uses the full man page description if a summary is unavailable - - if self._fields[Field.SUMMARY] is None: - self._fields[Field.SUMMARY] = self._fields[Field.DESCRIPTION] - - def get(self, field): + def category(self): """ - Provides back the value in the given field. + Provides the category of this configuration option.
- Arguments: - field - enum for the field to be provided back + :returns: **Category** this option belongs to """
- if field == Field.IS_SET: - return bool(tor_controller().get_conf(self.get(Field.OPTION), [], False)) - - return self._get_value() if field == Field.VALUE else self._fields[field] + return self._man_entry.category if self._man_entry else tor_config.Category.UNKNOWN
- def sort_value(self, attr): + def option(self): """ - Provides a heuristic for sorting by a given value. - - :param Field attr: sort attribute to provide a heuristic for + Provides the name of the configuration option.
- :returns: comparable value for sorting + :returns: **str** of the configuration option """
- return self.get(attr) if attr != Field.IS_SET else not self.get(attr) + return self._option
- def _get_value(self): + def value(self): """ - Provides the current value of the configuration entry, taking advantage of - the tor_tools caching to effectively query the accurate value. This uses the - value's type to provide a user friendly representation if able. + Provides the value of this configuration option. + + :returns: **str** representation of the current config value """
- conf_value = ', '.join(tor_controller().get_conf(self.get(Field.OPTION), [], True)) + conf_value = ', '.join(tor_controller().get_conf(self.option(), [], True))
# provides nicer values for recognized types
if not conf_value: conf_value = '<none>' - elif self.get(Field.TYPE) == 'Boolean' and conf_value in ('0', '1'): + elif self.value_type() == 'Boolean' and conf_value in ('0', '1'): conf_value = 'False' if conf_value == '0' else 'True' - elif self.get(Field.TYPE) == 'DataSize' and conf_value.isdigit(): + elif self.value_type() == 'DataSize' and conf_value.isdigit(): conf_value = str_tools.size_label(int(conf_value)) - elif self.get(Field.TYPE) == 'TimeInterval' and conf_value.isdigit(): + elif self.value_type() == 'TimeInterval' and conf_value.isdigit(): conf_value = str_tools.time_label(int(conf_value), is_long = True)
return conf_value
+ def value_type(self): + """ + Provides this configuration value's type. + + :returns: **str** representation of this configuration value's type + """ + + return self._value_type # TODO: should this be an enum instead? + + def summary(self): + """ + Provides a summery of this configuration option. + + :returns: short **str** description of the option + """ + + summary = tor_config.get_config_summary(self.option()) + + if summary: + return summary + else: + # uses the full man page description if a summary is unavailable + return self._man_entry.description if self._man_entry else '' + + def manual_entry(self): + """ + Provides the entry's man page entry. + + :returns: **ManPageEntry** if it was loaded, and **None** otherwise + """ + + return self._man_entry + + def is_set(self): + """ + Checks if the configuration option has a custom value. + + :returns: **True** if the option has a custom value, **False** otherwise + """ + + return bool(tor_controller().get_conf(self.option(), [], False)) + + def sort_value(self, attr): + """ + Provides a heuristic for sorting by a given value. + + :param SortAttr attr: sort attribute to provide a heuristic for + + :returns: comparable value for sorting + """ + + if attr == SortAttr.CATEGORY: + return self.category() + elif attr == SortAttr.OPTION: + return self.option() + elif attr == SortAttr.VALUE: + return self.value() + elif attr == SortAttr.VALUE_TYPE: + return self.value_type() + elif attr == SortAttr.USAGE: + return self._man_entry.arg_usage if self._man_entry else '' + elif attr == SortAttr.SUMMARY: + return self.summary() + elif attr == SortAttr.DESCRIPTION: + return self._man_entry.description if self._man_entry else '' + elif attr == SortAttr.MAN_PAGE_ENTRY: + return self._man_entry.index if self._man_entry else 99999 # sorts non-man entries last + elif attr == SortAttr.IS_SET: + return not self.is_set() +
class ConfigPanel(panel.Panel): """ @@ -179,7 +217,7 @@ class ConfigPanel(panel.Panel):
# mirror listing with only the important configuration options
- self.conf_important_contents = filter(lambda entry: tor_config.is_important(entry.get(Field.OPTION)), self.conf_contents) + self.conf_important_contents = filter(lambda entry: tor_config.is_important(entry.option()), self.conf_contents)
# if there aren't any important options then show everything
@@ -201,8 +239,8 @@ class ConfigPanel(panel.Panel): Provides the dialog for sorting our configuration options. """
- sort_colors = dict([(field, CONFIG['attr.config.field_color'].get(field, 'white')) for field in Field]) - results = nyx.popups.show_sort_dialog('Config Option Ordering:', Field, self._sort_order, sort_colors) + sort_colors = dict([(attr, CONFIG['attr.config.sort_color'].get(attr, 'white')) for attr in SortAttr]) + results = nyx.popups.show_sort_dialog('Config Option Ordering:', SortAttr, self._sort_order, sort_colors)
if results: self._sort_order = results @@ -224,22 +262,22 @@ class ConfigPanel(panel.Panel):
with panel.CURSES_LOCK: selection = self.get_selection() - config_option = selection.get(Field.OPTION) + config_option = selection.option()
- initial_value = '' if not selection.get(Field.IS_SET) else selection.get(Field.VALUE) + initial_value = '' if not selection.is_set() else selection.value() prompt_msg = '%s Value (esc to cancel): ' % config_option new_value = nyx.popups.input_prompt(prompt_msg, initial_value)
if new_value is not None and new_value != initial_value: try: - if selection.get(Field.TYPE) == 'Boolean': + if selection.value_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': + elif selection.value_type() == 'LineList': # set_option accepts list inputs when there's multiple values new_value = new_value.split(',')
@@ -452,17 +490,15 @@ class ConfigPanel(panel.Panel): entry = self._get_config_options()[line_number] draw_line = line_number + DETAILS_HEIGHT + 2 - scroll_location
- line_format = [curses.A_BOLD if entry.get(Field.IS_SET) else curses.A_NORMAL] - - if entry.get(Field.CATEGORY): - line_format += [CONFIG['attr.config.category_color'].get(entry.get(Field.CATEGORY), 'white')] + line_format = [curses.A_BOLD if entry.is_set() else curses.A_NORMAL] + line_format += [CONFIG['attr.config.category_color'].get(entry.category(), 'white')]
if entry == cursor_selection: line_format += [curses.A_STANDOUT]
- option_label = str_tools.crop(entry.get(Field.OPTION), OPTION_WIDTH) - value_label = str_tools.crop(entry.get(Field.VALUE), value_width) - summary_label = str_tools.crop(entry.get(Field.SUMMARY), description_width, None) + option_label = str_tools.crop(entry.option(), OPTION_WIDTH) + value_label = str_tools.crop(entry.value(), value_width) + summary_label = str_tools.crop(entry.summary(), description_width, None) line_text_layout = '%%-%is %%-%is %%-%is' % (OPTION_WIDTH, value_width, description_width) line_text = line_text_layout % (option_label, value_label, summary_label)
@@ -487,33 +523,33 @@ class ConfigPanel(panel.Panel): if is_scrollbar_visible: self.addch(detail_panel_height, 1, curses.ACS_TTEE)
- selection_format = (curses.A_BOLD, CONFIG['attr.config.category_color'].get(selection.get(Field.CATEGORY), 'white')) + selection_format = (curses.A_BOLD, CONFIG['attr.config.category_color'].get(selection.category(), 'white'))
# first entry: # <option> (<category> Option)
- option_label = ' (%s Option)' % selection.get(Field.CATEGORY) - self.addstr(1, 2, selection.get(Field.OPTION) + option_label, *selection_format) + option_label = ' (%s Option)' % selection.category() + self.addstr(1, 2, selection.option() + option_label, *selection_format)
# second entry: # Value: <value> ([default|custom], <type>, usage: <argument usage>)
if detail_panel_height >= 3: value_attr_label = ', '.join([ - 'custom' if selection.get(Field.IS_SET) else 'default', - selection.get(Field.TYPE), - 'usage: %s' % (selection.get(Field.ARG_USAGE)) + 'custom' if selection.is_set() else 'default', + selection.value_type(), + 'usage: %s' % (selection.manual_entry().arg_usage if selection.manual_entry() else '') ])
value_label_width = width - 12 - len(value_attr_label) - value_label = str_tools.crop(selection.get(Field.VALUE), value_label_width) + value_label = str_tools.crop(selection.value(), value_label_width)
self.addstr(2, 2, 'Value: %s (%s)' % (value_label, value_attr_label), *selection_format)
# remainder is filled with the man page description
description_height = max(0, detail_panel_height - 3) - description_content = 'Description: ' + selection.get(Field.DESCRIPTION) + description_content = 'Description: %s' % (selection.manual_entry().description if selection.manual_entry() else '')
for i in range(description_height): # checks if we're done writing the description diff --git a/nyx/connection_panel.py b/nyx/connection_panel.py index ff6daf8..5f4f68b 100644 --- a/nyx/connection_panel.py +++ b/nyx/connection_panel.py @@ -65,10 +65,7 @@ CONFIG = conf.config_dict('nyx', { 'attr.connection.category_color': {}, 'attr.connection.sort_color': {}, 'features.connection.resolveApps': True, - 'features.connection.order': [ - SortAttr.CATEGORY, - SortAttr.IP_ADDRESS, - SortAttr.UPTIME], + 'features.connection.order': [SortAttr.CATEGORY, SortAttr.IP_ADDRESS, SortAttr.UPTIME], 'features.connection.showIps': True, }, conf_handler)
tor-commits@lists.torproject.org