codekingpro/portable-devtools
114k
1from functools import lru_cache2 3import urwid4 5import mitmproxy.tools.console.master6from mitmproxy.tools.console import common7from mitmproxy.tools.console import layoutwidget8 9 10class FlowItem(urwid.WidgetWrap):11 def __init__(self, master, flow):12 self.master, self.flow = master, flow13 w = self.get_text()14 urwid.WidgetWrap.__init__(self, w)15 16 def get_text(self):17 cols, _ = self.master.ui.get_cols_rows()18 layout = self.master.options.console_flowlist_layout19 if layout == "list" or (layout == "default" and cols < 100):20 render_mode = common.RenderMode.LIST21 else:22 render_mode = common.RenderMode.TABLE23 24 return common.format_flow(25 self.flow,26 render_mode=render_mode,27 focused=self.flow is self.master.view.focus.flow,28 hostheader=self.master.options.showhost,29 )30 31 def selectable(self):32 return True33 34 def mouse_event(self, size, event, button, col, row, focus):35 if event == "mouse press" and button == 1:36 self.master.commands.execute("console.view.flow @focus")37 return True38 39 def keypress(self, size, key):40 return key41 42 43class FlowListWalker(urwid.ListWalker):44 master: "mitmproxy.tools.console.master.ConsoleMaster"45 46 def __init__(self, master):47 self.master = master48 49 def positions(self, reverse=False):50 # The stub implementation of positions can go once this issue is resolved:51 # https://github.com/urwid/urwid/issues/29452 ret = range(self.master.view.get_length())53 if reverse:54 return reversed(ret)55 return ret56 57 def view_changed(self):58 self._modified()59 self._get.cache_clear()60 61 def get_focus(self):62 if not self.master.view.focus.flow:63 return None, 064 f = FlowItem(self.master, self.master.view.focus.flow)65 return f, self.master.view.focus.index66 67 def set_focus(self, index):68 if self.master.commands.execute("view.properties.inbounds %d" % index):69 self.master.view.focus.index = index70 71 @lru_cache(maxsize=None)72 def _get(self, pos: int) -> tuple[FlowItem | None, int | None]:73 if not self.master.view.inbounds(pos):74 return None, None75 return FlowItem(self.master, self.master.view[pos]), pos76 77 def get_next(self, pos):78 return self._get(pos + 1)79 80 def get_prev(self, pos):81 return self._get(pos - 1)82 83 84class FlowListBox(urwid.ListBox, layoutwidget.LayoutWidget):85 title = "Flows"86 keyctx = "flowlist"87 88 def __init__(self, master: "mitmproxy.tools.console.master.ConsoleMaster") -> None:89 self.master: "mitmproxy.tools.console.master.ConsoleMaster" = master90 super().__init__(FlowListWalker(master))91 self.master.options.subscribe(92 self.set_flowlist_layout, ["console_flowlist_layout"]93 )94 95 def keypress(self, size, key):96 if key == "m_start":97 self.master.commands.execute("view.focus.go 0")98 elif key == "m_end":99 self.master.commands.execute("view.focus.go -1")100 elif key == "m_select":101 self.master.commands.execute("console.view.flow @focus")102 return urwid.ListBox.keypress(self, size, key)103 104 def view_changed(self):105 self.body.view_changed()106 107 def set_flowlist_layout(self, *_) -> None:108 self.master.ui.clear()109 