commit 7e583acbe7ae25652d6aae48403b839b4239b0e1 Author: Damian Johnson atagar@torproject.org Date: Sun Aug 31 17:12:30 2014 -0700
Replacing ui_tools.crop_str() with str_tools.crop()
Replacing our crop method with the one moved to stem. --- arm/config_panel.py | 14 ++-- arm/connections/circ_entry.py | 6 +- arm/connections/conn_entry.py | 20 +++--- arm/connections/count_popup.py | 2 - arm/connections/descriptor_popup.py | 6 +- arm/graphing/bandwidth_stats.py | 2 +- arm/header_panel.py | 5 +- arm/log_panel.py | 10 +-- arm/torrc_panel.py | 6 +- arm/util/ui_tools.py | 122 +---------------------------------- 10 files changed, 37 insertions(+), 156 deletions(-)
diff --git a/arm/config_panel.py b/arm/config_panel.py index 061da61..e71948b 100644 --- a/arm/config_panel.py +++ b/arm/config_panel.py @@ -171,9 +171,9 @@ class ConfigEntry(): arg_set = (option_width, value_width, summary_width)
if not self.label_cache or self.label_cache_args != arg_set: - option_label = ui_tools.crop_str(self.get(Field.OPTION), option_width) - value_label = ui_tools.crop_str(self.get(Field.VALUE), value_width) - summary_label = ui_tools.crop_str(self.get(Field.SUMMARY), summary_width, None) + option_label = str_tools.crop(self.get(Field.OPTION), option_width) + value_label = str_tools.crop(self.get(Field.VALUE), value_width) + summary_label = str_tools.crop(self.get(Field.SUMMARY), summary_width, None) line_text_layout = "%%-%is %%-%is %%-%is" % (option_width, value_width, summary_width) self.label_cache = line_text_layout % (option_label, value_label, summary_label) self.label_cache_args = arg_set @@ -500,7 +500,7 @@ class ConfigPanel(panel.Panel): visible_config_lines = height - 3 if is_option_line_separate else height - 2
for i in range(visible_config_lines): - line = ui_tools.crop_str(config_lines[i], width - 2) + line = str_tools.crop(config_lines[i], width - 2)
if " " in line: option, arg = line.split(" ", 1) @@ -686,7 +686,7 @@ class ConfigPanel(panel.Panel): value_attr_label = ", ".join(value_attr)
value_label_width = width - 12 - len(value_attr_label) - value_label = ui_tools.crop_str(selection.get(Field.VALUE), value_label_width) + value_label = str_tools.crop(selection.get(Field.VALUE), value_label_width)
self.addstr(2, 2, "Value: %s (%s)" % (value_label, value_attr_label), *selection_format)
@@ -716,11 +716,11 @@ class ConfigPanel(panel.Panel): if i != description_height - 1: # there's more lines to display
- msg, remainder = ui_tools.crop_str(line_content, width - 3, 4, 4, ui_tools.Ending.HYPHEN, True) + msg, remainder = str_tools.crop(line_content, width - 3, 4, 4, str_tools.Ending.HYPHEN, True) description_content = remainder.strip() + description_content else: # this is the last line, end it with an ellipse
- msg = ui_tools.crop_str(line_content, width - 3, 4, 4) + msg = str_tools.crop(line_content, width - 3, 4, 4)
self.addstr(3 + i, 2, msg, *selection_format) diff --git a/arm/connections/circ_entry.py b/arm/connections/circ_entry.py index 4e7b2d6..c6db152 100644 --- a/arm/connections/circ_entry.py +++ b/arm/connections/circ_entry.py @@ -11,7 +11,9 @@ followed by an entry for each hop in the circuit. For instance: import curses
from arm.connections import entries, conn_entry -from arm.util import tor_controller, ui_tools +from arm.util import tor_controller + +from stem.util import str_tools
ADDRESS_LOOKUP_CACHE = {}
@@ -191,7 +193,7 @@ class CircLine(conn_entry.ConnectionLine):
# fills the nickname into the empty space here
- dst = "%s%-25s " % (dst[:25], ui_tools.crop_str(self.foreign.get_nickname(), 25, 0)) + dst = "%s%-25s " % (dst[:25], str_tools.crop(self.foreign.get_nickname(), 25, 0))
etc = self.get_etc_content(width - baseline_space - len(dst), listing_type) elif listing_type == entries.ListingType.HOSTNAME: diff --git a/arm/connections/conn_entry.py b/arm/connections/conn_entry.py index cad2dbb..4b9a017 100644 --- a/arm/connections/conn_entry.py +++ b/arm/connections/conn_entry.py @@ -6,7 +6,7 @@ Connection panel entries related to actual connections to or from the system import time import curses
-from arm.util import tor_controller, ui_tools +from arm.util import tor_controller from arm.connections import entries
import stem.control @@ -561,7 +561,7 @@ class ConnectionLine(entries.ConnectionPanelLine): # show nickname (column width: remainder)
nickname_space = width - used_space - nickname_label = ui_tools.crop_str(self.foreign.get_nickname(), nickname_space, 0) + nickname_label = str_tools.crop(self.foreign.get_nickname(), nickname_space, 0) etc += ("%%-%is " % nickname_space) % nickname_label used_space += nickname_space + 2 elif listing_type == entries.ListingType.HOSTNAME: @@ -578,7 +578,7 @@ class ConnectionLine(entries.ConnectionPanelLine): if width > used_space + 17 and CONFIG["features.connection.showColumn.nickname"]: # show nickname (column width: min 17 characters, uses half of the remainder) nickname_space = 15 + (width - (used_space + 17)) / 2 - nickname_label = ui_tools.crop_str(self.foreign.get_nickname(), nickname_space, 0) + nickname_label = str_tools.crop(self.foreign.get_nickname(), nickname_space, 0) etc += ("%%-%is " % nickname_space) % nickname_label used_space += (nickname_space + 2) elif listing_type == entries.ListingType.FINGERPRINT: @@ -597,7 +597,7 @@ class ConnectionLine(entries.ConnectionPanelLine): nickname_space -= 28
if CONFIG["features.connection.showColumn.nickname"]: - nickname_label = ui_tools.crop_str(self.foreign.get_nickname(), nickname_space, 0) + nickname_label = str_tools.crop(self.foreign.get_nickname(), nickname_space, 0) etc += ("%%-%is " % nickname_space) % nickname_label used_space += nickname_space + 2
@@ -723,7 +723,7 @@ class ConnectionLine(entries.ConnectionPanelLine):
# truncates long hostnames and sets dst to <hostname>:<port>
- hostname = ui_tools.crop_str(hostname, hostname_space, 0) + hostname = str_tools.crop(hostname, hostname_space, 0) dst = ("%%-%is" % hostname_space) % (hostname + port_label) elif listing_type == entries.ListingType.FINGERPRINT: src = "localhost" @@ -757,8 +757,8 @@ class ConnectionLine(entries.ConnectionPanelLine): used_space = width # prevents padding at the end
if len(src) + len(dst) > base_space: - src = ui_tools.crop_str(src, base_space / 3) - dst = ui_tools.crop_str(dst, base_space - len(src)) + src = str_tools.crop(src, base_space / 3) + dst = str_tools.crop(dst, base_space - len(src))
# pads dst entry to its max space
@@ -901,7 +901,7 @@ class ConnectionLine(entries.ConnectionPanelLine): # crops any lines that are too long
for i in range(len(lines)): - lines[i] = ui_tools.crop_str(lines[i], width - 2) + lines[i] = str_tools.crop(lines[i], width - 2)
return lines
@@ -951,7 +951,7 @@ class ConnectionLine(entries.ConnectionPanelLine):
# crops with a hyphen if too long
- purpose = ui_tools.crop_str(purpose, space_available, end_type = ui_tools.Ending.HYPHEN) + purpose = str_tools.crop(purpose, space_available, ending = str_tools.Ending.HYPHEN)
destination_address += " (%s)" % purpose elif not connection.is_private_address(self.foreign.get_address()): @@ -971,7 +971,7 @@ class ConnectionLine(entries.ConnectionPanelLine): # dividers if there's multiple pieces of extra data
max_hostname_space = space_available - 2 * len(extra_info) - destination_hostname = ui_tools.crop_str(destination_hostname, max_hostname_space) + destination_hostname = str_tools.crop(destination_hostname, max_hostname_space) extra_info.append(destination_hostname) space_available -= len(destination_hostname)
diff --git a/arm/connections/count_popup.py b/arm/connections/count_popup.py index 50fb7d8..4decf46 100644 --- a/arm/connections/count_popup.py +++ b/arm/connections/count_popup.py @@ -8,8 +8,6 @@ import operator import arm.controller import arm.popups
-from arm.util import ui_tools - from stem.util import connection, enum, log
CountType = enum.Enum("CLIENT_LOCALE", "EXIT_PORT") diff --git a/arm/connections/descriptor_popup.py b/arm/connections/descriptor_popup.py index 30adb6c..af6ee69 100644 --- a/arm/connections/descriptor_popup.py +++ b/arm/connections/descriptor_popup.py @@ -10,6 +10,8 @@ import arm.connections.conn_entry
from arm.util import panel, tor_controller, ui_tools
+from stem.util import str_tools + # field keywords used to identify areas for coloring
LINE_NUM_COLOR = "yellow" @@ -238,12 +240,12 @@ def draw(popup, fingerprint, display_text, display_color, scroll, show_line_numb if len(msg) >= max_msg_size: # needs to split up the line
- msg, remainder = ui_tools.crop_str(msg, max_msg_size, None, end_type = None, get_remainder = True) + msg, remainder = str_tools.crop(msg, max_msg_size, None, ending = None, get_remainder = True)
if x_offset == cursor_location and msg == "": # first word is longer than the line
- msg = ui_tools.crop_str(remainder, max_msg_size) + msg = str_tools.crop(remainder, max_msg_size)
if " " in remainder: remainder = remainder.split(" ", 1)[1] diff --git a/arm/graphing/bandwidth_stats.py b/arm/graphing/bandwidth_stats.py index 634a0f5..16cc349 100644 --- a/arm/graphing/bandwidth_stats.py +++ b/arm/graphing/bandwidth_stats.py @@ -9,7 +9,7 @@ import curses import arm.controller
from arm.graphing import graph_panel -from arm.util import tor_controller, ui_tools +from arm.util import tor_controller
from stem.control import State from stem.util import conf, log, str_tools, system diff --git a/arm/header_panel.py b/arm/header_panel.py index d8dc8ad..13194e4 100644 --- a/arm/header_panel.py +++ b/arm/header_panel.py @@ -18,10 +18,9 @@ import arm.controller import arm.popups import arm.starter import arm.util.tracker -import arm.util.ui_tools
from stem.control import Listener, State -from stem.util import conf, log +from stem.util import conf, log, str_tools
from util import panel, tor_controller
@@ -510,7 +509,7 @@ class Sampling(object): formatted_msg = msg.format(**self.__dict__)
if crop_width: - formatted_msg = arm.util.ui_tools.crop_str(formatted_msg, crop_width) + formatted_msg = str_tools.crop(formatted_msg, crop_width)
return formatted_msg
diff --git a/arm/log_panel.py b/arm/log_panel.py index e39c70f..6f5087b 100644 --- a/arm/log_panel.py +++ b/arm/log_panel.py @@ -14,7 +14,7 @@ import threading import stem from stem.control import State from stem.response import events -from stem.util import conf, log, system +from stem.util import conf, log, str_tools, system
import arm.arguments import arm.popups @@ -1051,9 +1051,9 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler): if len(msg) > max_msg_size: # message is too long - break it up if line_offset == max_entries_per_line - 1: - msg = ui_tools.crop_str(msg, max_msg_size) + msg = str_tools.crop(msg, max_msg_size) else: - msg, remainder = ui_tools.crop_str(msg, max_msg_size, 4, 4, ui_tools.Ending.HYPHEN, True) + 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))
include_break = True @@ -1246,7 +1246,7 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler): if not current_pattern: panel_label = "Events:" else: - label_pattern = ui_tools.crop_str(current_pattern, width - 18) + 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, arm, and stem): @@ -1320,7 +1320,7 @@ class LogPanel(panel.Panel, threading.Thread, logging.Handler): if current_pattern: attr_label += " - filter: %s" % current_pattern
- attr_label = ui_tools.crop_str(attr_label, width - 10, 1) + attr_label = str_tools.crop(attr_label, width - 10, 1)
if attr_label: attr_label = " (%s)" % attr_label diff --git a/arm/torrc_panel.py b/arm/torrc_panel.py index a299ef9..6dfaf17 100644 --- a/arm/torrc_panel.py +++ b/arm/torrc_panel.py @@ -11,7 +11,7 @@ import arm.popups from arm.util import panel, tor_config, tor_controller, ui_tools
from stem.control import State -from stem.util import conf, enum +from stem.util import conf, enum, str_tools
def conf_handler(key, value): @@ -316,10 +316,10 @@ class TorrcPanel(panel.Panel): # message is too long - break it up
if line_offset == max_lines_per_entry - 1: - msg = ui_tools.crop_str(msg, max_msg_size) + msg = str_tools.crop(msg, max_msg_size) else: include_break = True - msg, remainder = ui_tools.crop_str(msg, max_msg_size, 4, 4, ui_tools.Ending.HYPHEN, True) + msg, remainder = str_tools.crop(msg, max_msg_size, 4, 4, str_tools.Ending.HYPHEN, True) display_queue.insert(0, (remainder.strip(), format))
draw_line = display_line + line_offset diff --git a/arm/util/ui_tools.py b/arm/util/ui_tools.py index 01daffa..cfa6ba3 100644 --- a/arm/util/ui_tools.py +++ b/arm/util/ui_tools.py @@ -2,14 +2,13 @@ Toolkit for working with curses. """
-import sys import curses
from curses.ascii import isprint
from arm.util import log, msg
-from stem.util import conf, enum, system +from stem.util import conf, system
COLOR_LIST = { 'red': curses.COLOR_RED, @@ -25,7 +24,6 @@ COLOR_LIST = { DEFAULT_COLOR_ATTR = dict([(color, 0) for color in COLOR_LIST]) COLOR_ATTR = None
-Ending = enum.Enum('ELLIPSE', 'HYPHEN') SCROLL_KEYS = (curses.KEY_UP, curses.KEY_DOWN, curses.KEY_PPAGE, curses.KEY_NPAGE, curses.KEY_HOME, curses.KEY_END)
@@ -183,124 +181,6 @@ def get_printable(line, keep_newlines = True): return line
-def crop_str(msg, size, min_word_length = 4, min_crop = 0, end_type = Ending.ELLIPSE, get_remainder = False): - """ - Provides the msg constrained to the given length, truncating on word breaks. - If the last words is long this truncates mid-word with an ellipse. If there - isn't room for even a truncated single word (or one word plus the ellipse if - including those) then this provides an empty string. If a cropped string ends - with a comma or period then it's stripped (unless we're providing the - remainder back). For example... - - >>> crop_str("This is a looooong message", 17) - "This is a looo..." - - >>> crop_str("This is a looooong message", 12) - "This is a..." - - >>> crop_str("This is a looooong message", 3) - "" - - :param str msg: text to be processed - :param int size: space available for text - :param int min_word_length: minimum characters before which a word is - dropped, requires whole word if **None** - :param int min_crop: minimum characters that must be dropped if a word is - cropped - :param Ending end_type: type of ending used when truncating, no special - truncation is used if **None** - :param bool get_remainder: returns a tuple with the second part being the - cropped portion of the message - - :returns: **str** of the text truncated to the given length - """ - - # checks if there's room for the whole message - - if len(msg) <= size: - if get_remainder: - return (msg, "") - else: - return msg - - # avoids negative input - - size = max(0, size) - - if min_word_length is not None: - min_word_length = max(0, min_word_length) - - min_crop = max(0, min_crop) - - # since we're cropping, the effective space available is less with an - # ellipse, and cropping words requires an extra space for hyphens - - if end_type == Ending.ELLIPSE: - size -= 3 - elif end_type == Ending.HYPHEN and min_word_length is not None: - min_word_length += 1 - - # checks if there isn't the minimum space needed to include anything - - last_wordbreak = msg.rfind(" ", 0, size + 1) - - if last_wordbreak == -1: - # we're splitting the first word - - if min_word_length is None or size < min_word_length: - if get_remainder: - return ("", msg) - else: - return "" - - include_crop = True - else: - last_wordbreak = len(msg[:last_wordbreak].rstrip()) # drops extra ending whitespaces - - if (min_word_length is not None and size < min_word_length) or (min_word_length is None and last_wordbreak < 1): - if get_remainder: - return ("", msg) - else: - return "" - - if min_word_length is None: - min_word_length = sys.maxint - - include_crop = size - last_wordbreak - 1 >= min_word_length - - # if there's a max crop size then make sure we're cropping at least that many characters - - if include_crop and min_crop: - next_wordbreak = msg.find(" ", size) - - if next_wordbreak == -1: - next_wordbreak = len(msg) - - include_crop = next_wordbreak - size + 1 >= min_crop - - if include_crop: - return_msg, remainder = msg[:size], msg[size:] - - if end_type == Ending.HYPHEN: - remainder = return_msg[-1] + remainder - return_msg = return_msg[:-1].rstrip() + "-" - else: - return_msg, remainder = msg[:last_wordbreak], msg[last_wordbreak:] - - # if this is ending with a comma or period then strip it off - - if not get_remainder and return_msg and return_msg[-1] in (",", "."): - return_msg = return_msg[:-1] - - if end_type == Ending.ELLIPSE: - return_msg = return_msg.rstrip() + "..." - - if get_remainder: - return (return_msg, remainder) - else: - return return_msg - - def pad_str(msg, size, crop_extra = False): """ Provides the string padded with whitespace to the given length.