mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2025-02-01 07:49:10 +00:00
add looping around
This commit is contained in:
parent
9cf8a1a89d
commit
21efe2f2c8
@ -126,7 +126,7 @@ class FlowView(common.WWrap):
|
|||||||
def _cached_content_view(self, viewmode, hdrItems, content, limit):
|
def _cached_content_view(self, viewmode, hdrItems, content, limit):
|
||||||
return contentview.get_content_view(viewmode, hdrItems, content, limit, self.master.add_event)
|
return contentview.get_content_view(viewmode, hdrItems, content, limit, self.master.add_event)
|
||||||
|
|
||||||
def content_view(self, viewmode, conn, highlight_string = None):
|
def content_view(self, viewmode, conn):
|
||||||
full = self.state.get_flow_setting(
|
full = self.state.get_flow_setting(
|
||||||
self.flow,
|
self.flow,
|
||||||
(self.state.view_flow_mode, "fullcontents"),
|
(self.state.view_flow_mode, "fullcontents"),
|
||||||
@ -145,67 +145,84 @@ class FlowView(common.WWrap):
|
|||||||
limit
|
limit
|
||||||
)
|
)
|
||||||
|
|
||||||
if highlight_string:
|
return (description, text_objects)
|
||||||
text_objects, focus_position = self.search_highlight_text(text_objects,
|
|
||||||
highlight_string)
|
|
||||||
else:
|
|
||||||
focus_position = None
|
|
||||||
|
|
||||||
return (description, text_objects, focus_position)
|
def cont_view_handle_missing(self, conn, viewmode):
|
||||||
|
if conn.content == flow.CONTENT_MISSING:
|
||||||
|
msg, body = "", [urwid.Text([("error", "[content missing]")])], 0
|
||||||
|
else:
|
||||||
|
msg, body = self.content_view(viewmode, conn)
|
||||||
|
|
||||||
def conn_text(self, conn, highlight_string=""):
|
return (msg, body)
|
||||||
txt = common.format_keyvals(
|
|
||||||
|
def viewmode_get(self, override):
|
||||||
|
return self.state.default_body_view if override is None else override
|
||||||
|
|
||||||
|
def override_get(self):
|
||||||
|
return self.state.get_flow_setting(self.flow,
|
||||||
|
(self.state.view_flow_mode, "prettyview"))
|
||||||
|
|
||||||
|
def conn_text_raw(self, conn):
|
||||||
|
"""
|
||||||
|
Based on a request/response, conn, returns the elements for
|
||||||
|
display.
|
||||||
|
"""
|
||||||
|
headers = common.format_keyvals(
|
||||||
[(h+":", v) for (h, v) in conn.headers.lst],
|
[(h+":", v) for (h, v) in conn.headers.lst],
|
||||||
key = "header",
|
key = "header",
|
||||||
val = "text"
|
val = "text"
|
||||||
)
|
)
|
||||||
|
|
||||||
if conn.content is not None:
|
if conn.content is not None:
|
||||||
override = self.state.get_flow_setting(
|
override = self.override_get()
|
||||||
self.flow,
|
viewmode = self.viewmode_get(override)
|
||||||
(self.state.view_flow_mode, "prettyview"),
|
msg, body = self.cont_view_handle_missing(conn, viewmode)
|
||||||
)
|
|
||||||
viewmode = self.state.default_body_view if override is None else override
|
|
||||||
|
|
||||||
if conn.content == flow.CONTENT_MISSING:
|
|
||||||
msg, body, text_focus_position = "", [urwid.Text([("error", "[content missing]")])], 0
|
|
||||||
else:
|
|
||||||
msg, body, text_focus_position = self.content_view(viewmode, conn, highlight_string)
|
|
||||||
|
|
||||||
cols = [
|
|
||||||
urwid.Text(
|
|
||||||
[
|
|
||||||
("heading", msg),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
if override is not None:
|
|
||||||
cols.append(
|
|
||||||
urwid.Text(
|
|
||||||
[
|
|
||||||
" ",
|
|
||||||
('heading', "["),
|
|
||||||
('heading_key', "m"),
|
|
||||||
('heading', (":%s]"%viewmode.name)),
|
|
||||||
],
|
|
||||||
align="right"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
title = urwid.AttrWrap(urwid.Columns(cols), "heading")
|
|
||||||
txt.append(title)
|
|
||||||
txt.extend(body)
|
|
||||||
elif conn.content == flow.CONTENT_MISSING:
|
elif conn.content == flow.CONTENT_MISSING:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.last_displayed_body = urwid.ListBox(txt)
|
return headers, msg, body
|
||||||
|
|
||||||
if text_focus_position :
|
def conn_text_merge(self, headers, msg, body):
|
||||||
# +2 because of the two header columns
|
"""
|
||||||
self.last_displayed_body.set_focus(text_focus_position + 2)
|
Grabs what is returned by conn_text_raw and merges them all
|
||||||
|
toghether, mainly used by conn_text and search
|
||||||
|
"""
|
||||||
|
|
||||||
return self.last_displayed_body
|
override = self.override_get()
|
||||||
|
viewmode = self.viewmode_get(override)
|
||||||
|
|
||||||
|
cols = [urwid.Text(
|
||||||
|
[
|
||||||
|
("heading", msg),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
if override is not None:
|
||||||
|
cols.append(urwid.Text([
|
||||||
|
" ",
|
||||||
|
('heading', "["),
|
||||||
|
('heading_key', "m"),
|
||||||
|
('heading', (":%s]"%viewmode.name)),
|
||||||
|
],
|
||||||
|
align="right"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
title = urwid.AttrWrap(urwid.Columns(cols), "heading")
|
||||||
|
headers.append(title)
|
||||||
|
headers.extend(body)
|
||||||
|
|
||||||
|
return headers
|
||||||
|
|
||||||
|
def conn_text(self, conn):
|
||||||
|
"""
|
||||||
|
Same as conn_text_raw, but returns result wrapped in a listbox ready for usage.
|
||||||
|
"""
|
||||||
|
headers, msg, body = self.conn_text_raw(conn)
|
||||||
|
merged = self.conn_text_merge(headers, msg, body)
|
||||||
|
|
||||||
|
return urwid.ListBox(merged)
|
||||||
|
|
||||||
def _tab(self, content, attr):
|
def _tab(self, content, attr):
|
||||||
p = urwid.Text(content)
|
p = urwid.Text(content)
|
||||||
@ -241,14 +258,35 @@ class FlowView(common.WWrap):
|
|||||||
)
|
)
|
||||||
return f
|
return f
|
||||||
|
|
||||||
|
def search_wrapped_around(self, last_find_line, last_search_index):
|
||||||
|
"""
|
||||||
|
returns true if search wrapped around the bottom.
|
||||||
|
"""
|
||||||
|
|
||||||
|
current_find_line = self.state.get_flow_setting(self.flow,
|
||||||
|
"last_find_line")
|
||||||
|
current_search_index = self.state.get_flow_setting(self.flow,
|
||||||
|
"last_search_index")
|
||||||
|
|
||||||
|
if current_find_line <= last_find_line:
|
||||||
|
return True
|
||||||
|
elif current_find_line == last_find_line:
|
||||||
|
if current_search_index <= last_search_index:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def search(self, search_string):
|
def search(self, search_string):
|
||||||
|
"""
|
||||||
|
similar to view_response or view_request, but instead of just
|
||||||
|
displaying the conn, it highlights a word that the user is
|
||||||
|
searching for and handles all the logic surrounding that.
|
||||||
|
"""
|
||||||
|
|
||||||
if search_string == "":
|
if search_string == "":
|
||||||
search_string = self.state.get_flow_setting(self.flow,
|
search_string = self.state.get_flow_setting(self.flow,
|
||||||
"last_search_string")
|
"last_search_string")
|
||||||
|
|
||||||
# two things need to happen. 1) text needs to be highlighted. 2) we
|
|
||||||
# need to focus on the highlighted text.
|
|
||||||
if self.state.view_flow_mode == common.VIEW_FLOW_REQUEST:
|
if self.state.view_flow_mode == common.VIEW_FLOW_REQUEST:
|
||||||
text = self.flow.request
|
text = self.flow.request
|
||||||
const = common.VIEW_FLOW_REQUEST
|
const = common.VIEW_FLOW_REQUEST
|
||||||
@ -258,12 +296,31 @@ class FlowView(common.WWrap):
|
|||||||
if not self.flow.response:
|
if not self.flow.response:
|
||||||
return "no response to search in"
|
return "no response to search in"
|
||||||
|
|
||||||
# highlight
|
last_find_line = self.state.get_flow_setting(self.flow,
|
||||||
body = self.conn_text(text, search_string)
|
"last_find_line")
|
||||||
|
last_search_index = self.state.get_flow_setting(self.flow,
|
||||||
|
"last_search_index")
|
||||||
|
|
||||||
self.w = self.wrap_body(const, body)
|
# generate the body, highlight the words and get focus
|
||||||
|
headers, msg, body = self.conn_text_raw(text)
|
||||||
|
body, focus_position = self.search_highlight_text(body, search_string)
|
||||||
|
|
||||||
|
if focus_position == None:
|
||||||
|
# no results found.
|
||||||
|
return "no matches for '%s'" % search_string
|
||||||
|
|
||||||
|
# UI stuff.
|
||||||
|
merged = self.conn_text_merge(headers, msg, body)
|
||||||
|
list_box = urwid.ListBox(merged)
|
||||||
|
list_box.set_focus(focus_position + 2)
|
||||||
|
self.w = self.wrap_body(const, list_box)
|
||||||
self.master.statusbar.redraw()
|
self.master.statusbar.redraw()
|
||||||
|
|
||||||
|
self.last_displayed_body = list_box
|
||||||
|
|
||||||
|
if self.search_wrapped_around(last_find_line, last_search_index):
|
||||||
|
return "search hit BOTTOM, continuing at TOP"
|
||||||
|
|
||||||
def search_get_start(self, search_string):
|
def search_get_start(self, search_string):
|
||||||
last_search_string = self.state.get_flow_setting(self.flow, "last_search_string")
|
last_search_string = self.state.get_flow_setting(self.flow, "last_search_string")
|
||||||
if search_string == last_search_string:
|
if search_string == last_search_string:
|
||||||
@ -278,7 +335,7 @@ class FlowView(common.WWrap):
|
|||||||
|
|
||||||
return (start_line, start_index)
|
return (start_line, start_index)
|
||||||
|
|
||||||
def search_highlight_text(self, text_objects, search_string):
|
def search_highlight_text(self, text_objects, search_string, looping = False):
|
||||||
start_line, start_index = self.search_get_start(search_string)
|
start_line, start_index = self.search_get_start(search_string)
|
||||||
i = start_line
|
i = start_line
|
||||||
|
|
||||||
@ -316,7 +373,13 @@ class FlowView(common.WWrap):
|
|||||||
if found:
|
if found:
|
||||||
focus_pos = i
|
focus_pos = i
|
||||||
else :
|
else :
|
||||||
focus_pos = None
|
# loop from the beginning, but not forever.
|
||||||
|
if (start_line == 0 and start_index == 0) or looping:
|
||||||
|
focus_pos = None
|
||||||
|
else:
|
||||||
|
self.state.add_flow_setting(self.flow, "last_search_index", 0)
|
||||||
|
self.state.add_flow_setting(self.flow, "last_find_line", 0)
|
||||||
|
text_objects, focus_pos = self.search_highlight_text(text_objects, search_string, True)
|
||||||
|
|
||||||
return text_objects, focus_pos
|
return text_objects, focus_pos
|
||||||
|
|
||||||
|
@ -265,6 +265,13 @@ def test_search_highlights():
|
|||||||
text_object = tutils.get_body_line(f.last_displayed_body, 1)
|
text_object = tutils.get_body_line(f.last_displayed_body, 1)
|
||||||
assert text_object.get_text() == ('content', [(None, 5), (f.highlight_color, 2)])
|
assert text_object.get_text() == ('content', [(None, 5), (f.highlight_color, 2)])
|
||||||
|
|
||||||
|
def test_search_returns_useful_messages():
|
||||||
|
f = tutils.tflowview()
|
||||||
|
|
||||||
|
# original string is content. this string should not be in there.
|
||||||
|
response = f.search("oranges and other fruit.")
|
||||||
|
assert response == "no matches for 'oranges and other fruit.'"
|
||||||
|
|
||||||
def test_search_highlights_clears_prev():
|
def test_search_highlights_clears_prev():
|
||||||
f = tutils.tflowview(request_contents="this is string\nstring is string")
|
f = tutils.tflowview(request_contents="this is string\nstring is string")
|
||||||
|
|
||||||
@ -296,6 +303,20 @@ def test_search_highlights_multi_line():
|
|||||||
text_object = tutils.get_body_line(f.last_displayed_body, 1)
|
text_object = tutils.get_body_line(f.last_displayed_body, 1)
|
||||||
assert text_object.get_text() == ('string is string', [(None, 10), (f.highlight_color, 6)])
|
assert text_object.get_text() == ('string is string', [(None, 10), (f.highlight_color, 6)])
|
||||||
|
|
||||||
|
def test_search_loops():
|
||||||
|
f = tutils.tflowview(request_contents="this is string\nstring is string")
|
||||||
|
|
||||||
|
# get to the end.
|
||||||
|
f.search("string")
|
||||||
|
f.search("string")
|
||||||
|
f.search("string")
|
||||||
|
|
||||||
|
# should highlight the first line.
|
||||||
|
message = f.search("string")
|
||||||
|
text_object = tutils.get_body_line(f.last_displayed_body, 0)
|
||||||
|
assert text_object.get_text() == ('this is string', [(None, 8), (f.highlight_color, 6)])
|
||||||
|
assert message == "search hit BOTTOM, continuing at TOP"
|
||||||
|
|
||||||
def test_search_focuses():
|
def test_search_focuses():
|
||||||
f = tutils.tflowview(request_contents="this is string\nstring is string")
|
f = tutils.tflowview(request_contents="this is string\nstring is string")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user