aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/console/searchable.py
diff options
context:
space:
mode:
authorJim Shaver <dcypherd@gmail.com>2015-05-31 01:21:44 -0400
committerJim Shaver <dcypherd@gmail.com>2015-05-31 01:21:44 -0400
commitb51363b3ca43f6572acb673186e6ae78a1f48434 (patch)
treea7488b32871c142141a813dc6ff2ede172672c31 /libmproxy/console/searchable.py
parent4fe2c069cca07aadf983f54e18dac4de492d5d69 (diff)
parent06fba18106a8f759ec6f08453e86772a170c653b (diff)
downloadmitmproxy-b51363b3ca43f6572acb673186e6ae78a1f48434.tar.gz
mitmproxy-b51363b3ca43f6572acb673186e6ae78a1f48434.tar.bz2
mitmproxy-b51363b3ca43f6572acb673186e6ae78a1f48434.zip
Merge remote-tracking branch 'upstream/master' into print-bracket-fix
Conflicts: examples/har_extractor.py examples/nonblocking.py examples/read_dumpfile libmproxy/web/app.py
Diffstat (limited to 'libmproxy/console/searchable.py')
-rw-r--r--libmproxy/console/searchable.py91
1 files changed, 91 insertions, 0 deletions
diff --git a/libmproxy/console/searchable.py b/libmproxy/console/searchable.py
new file mode 100644
index 00000000..627d595d
--- /dev/null
+++ b/libmproxy/console/searchable.py
@@ -0,0 +1,91 @@
+import urwid
+
+from . import signals
+
+
+class Highlight(urwid.AttrMap):
+ def __init__(self, t):
+ urwid.AttrMap.__init__(
+ self,
+ urwid.Text(t.text),
+ "focusfield",
+ )
+ self.backup = t
+
+
+class Searchable(urwid.ListBox):
+ def __init__(self, state, contents):
+ self.walker = urwid.SimpleFocusListWalker(contents)
+ urwid.ListBox.__init__(self, self.walker)
+ self.state = state
+ self.search_offset = 0
+ self.current_highlight = None
+ self.search_term = None
+
+ def keypress(self, size, key):
+ if key == "/":
+ signals.status_prompt.send(
+ prompt = "Search for",
+ text = "",
+ callback = self.set_search
+ )
+ elif key == "n":
+ self.find_next(False)
+ elif key == "N":
+ self.find_next(True)
+ elif key == "G":
+ self.set_focus(0)
+ self.walker._modified()
+ elif key == "g":
+ self.set_focus(len(self.walker) - 1)
+ self.walker._modified()
+ else:
+ return super(self.__class__, self).keypress(size, key)
+
+ def set_search(self, text):
+ self.state.last_search = text
+ self.search_term = text or None
+ self.find_next(False)
+
+ def set_highlight(self, offset):
+ if self.current_highlight is not None:
+ old = self.body[self.current_highlight]
+ self.body[self.current_highlight] = old.backup
+ if offset is None:
+ self.current_highlight = None
+ else:
+ self.body[offset] = Highlight(self.body[offset])
+ self.current_highlight = offset
+
+ def get_text(self, w):
+ if isinstance(w, urwid.Text):
+ return w.text
+ elif isinstance(w, Highlight):
+ return w.backup.text
+ else:
+ return None
+
+ def find_next(self, backwards):
+ if not self.search_term:
+ if self.state.last_search:
+ self.search_term = self.state.last_search
+ else:
+ self.set_highlight(None)
+ return
+ # Start search at focus + 1
+ if backwards:
+ rng = xrange(len(self.body) - 1, -1, -1)
+ else:
+ rng = xrange(1, len(self.body) + 1)
+ for i in rng:
+ off = (self.focus_position + i) % len(self.body)
+ w = self.body[off]
+ txt = self.get_text(w)
+ if txt and self.search_term in txt:
+ self.set_highlight(off)
+ self.set_focus(off, coming_from="above")
+ self.body._modified()
+ return
+ else:
+ self.set_highlight(None)
+ signals.status_message.send(message="Search not found.", expire=1)