Skip to content

Commit

Permalink
Merge pull request #2945 from kajojify/shortening
Browse files Browse the repository at this point in the history
Polite shortening of statusbar messages. Fix #1433
  • Loading branch information
cortesi committed Mar 4, 2018
2 parents a2740ee + 237320a commit bc6550a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 2 deletions.
4 changes: 3 additions & 1 deletion mitmproxy/tools/console/master.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ def sig_add_log(self, event_store, entry: log.LogEntry):
self.start_err = entry
else:
signals.status_message.send(
message=(entry.level, "{}: {}".format(entry.level.title(), entry.msg)),
message=(entry.level,
"{}: {}".format(entry.level.title(),
str(entry.msg).lstrip())),
expire=5
)

Expand Down
33 changes: 32 additions & 1 deletion mitmproxy/tools/console/statusbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ def __init__(self, master):
def sig_message(self, sender, message, expire=1):
if self.prompting:
return
w = urwid.Text(message)
cols, _ = self.master.ui.get_cols_rows()
w = urwid.Text(self.shorten_message(message, cols))
self._w = w
if expire:
def cb(*args):
Expand All @@ -60,6 +61,36 @@ def cb(*args):
def prep_prompt(self, p):
return p.strip() + ": "

def shorten_message(self, msg, max_width):
"""
Shorten message so that it fits into a single line in the statusbar.
"""
if isinstance(msg, tuple):
disp_attr, msg_text = msg
elif isinstance(msg, str):
disp_attr, msg_text = None, msg
else:
return msg
msg_end = "\u2026" # unicode ellipsis for the end of shortened message
prompt = "(more in eventlog)"

msg_lines = msg_text.split("\n")
first_line = msg_lines[0]
if len(msg_lines) > 1:
# First line of messages with a few lines must end with prompt.
line_length = len(first_line) + len(prompt)
else:
line_length = len(first_line)

if line_length > max_width:
shortening_index = max(0, max_width - len(prompt) - len(msg_end))
first_line = first_line[:shortening_index] + msg_end
else:
if len(msg_lines) == 1:
prompt = ""

return [(disp_attr, first_line), ("warn", prompt)]

def sig_prompt(self, sender, prompt, text, callback, args=()):
signals.focus.send(self, section="footer")
self._w = urwid.Edit(self.prep_prompt(prompt), text or "")
Expand Down
28 changes: 28 additions & 0 deletions test/mitmproxy/tools/console/test_statusbar.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import pytest

from mitmproxy import options
from mitmproxy.tools.console import statusbar, master

Expand Down Expand Up @@ -31,3 +33,29 @@ def test_statusbar(monkeypatch):

bar = statusbar.StatusBar(m) # this already causes a redraw
assert bar.ib._w


@pytest.mark.parametrize("message,ready_message", [
("", [(None, ""), ("warn", "")]),
(("info", "Line fits into statusbar"), [("info", "Line fits into statusbar"),
("warn", "")]),
("Line doesn't fit into statusbar", [(None, "Line doesn'\u2026"),
("warn", "(more in eventlog)")]),
(("alert", "Two lines.\nFirst fits"), [("alert", "Two lines."),
("warn", "(more in eventlog)")]),
("Two long lines\nFirst doesn't fit", [(None, "Two long li\u2026"),
("warn", "(more in eventlog)")])
])
def test_shorten_message(message, ready_message):
o = options.Options()
m = master.ConsoleMaster(o)
ab = statusbar.ActionBar(m)
assert ab.shorten_message(message, max_width=30) == ready_message


def test_shorten_message_narrow():
o = options.Options()
m = master.ConsoleMaster(o)
ab = statusbar.ActionBar(m)
shorten_msg = ab.shorten_message("error", max_width=4)
assert shorten_msg == [(None, "\u2026"), ("warn", "(more in eventlog)")]

0 comments on commit bc6550a

Please sign in to comment.