From 65971f02ade7cc2126b4142a32c363e02112f95c Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Fri, 3 Apr 2015 14:10:57 +1300 Subject: [PATCH] console: basic options page --- libmproxy/console/__init__.py | 30 +++---- libmproxy/console/options.py | 151 ++++++++++++++++++++++++++++++++++ libmproxy/console/palettes.py | 29 +++++-- libmproxy/console/window.py | 15 +--- 4 files changed, 188 insertions(+), 37 deletions(-) create mode 100644 libmproxy/console/options.py diff --git a/libmproxy/console/__init__.py b/libmproxy/console/__init__.py index a3a8aa426..e7776fdf8 100644 --- a/libmproxy/console/__init__.py +++ b/libmproxy/console/__init__.py @@ -15,7 +15,7 @@ import urwid import weakref from .. import controller, flow, script -from . import flowlist, flowview, help, window, signals +from . import flowlist, flowview, help, window, signals, options from . import grideditor, palettes, contentview, statusbar EVENTLOG_SIZE = 500 @@ -465,6 +465,16 @@ class ConsoleMaster(flow.FlowMaster): None ) + def view_options(self): + signals.push_view_state.send(self) + self.loop.widget = window.Window( + self, + options.Options(self), + None, + statusbar.StatusBar(self, help.footer), + None + ) + def view_grideditor(self, ge): signals.push_view_state.send(self) self.loop.widget = window.Window( @@ -586,24 +596,6 @@ class ConsoleMaster(flow.FlowMaster): if a != "n": raise urwid.ExitMainLoop - def _change_options(self, a): - if a == "a": - self.anticache = not self.anticache - if a == "c": - self.anticomp = not self.anticomp - if a == "h": - self.showhost = not self.showhost - self.sync_list_view() - self.refresh_focus() - elif a == "k": - self.killextra = not self.killextra - elif a == "n": - self.refresh_server_playback = not self.refresh_server_playback - elif a == "u": - self.server.config.no_upstream_cert =\ - not self.server.config.no_upstream_cert - signals.update_settings.send(self) - def shutdown(self): self.state.killall(self) flow.FlowMaster.shutdown(self) diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py new file mode 100644 index 000000000..c6c4afb7f --- /dev/null +++ b/libmproxy/console/options.py @@ -0,0 +1,151 @@ +import urwid + +from . import common, signals + +help_context = None + + +class OptionWidget(urwid.WidgetWrap): + def __init__(self, option, text, active, focus): + self.option = option + opt = urwid.Text(text, align="center") + if focus and active: + opt = urwid.AttrWrap(opt, "option_active_selected") + elif focus: + opt = urwid.AttrWrap(opt, "option_selected") + elif active: + opt = urwid.AttrWrap(opt, "option_active") + opt = urwid.Padding(opt, align="center", width=("relative", 20)) + urwid.WidgetWrap.__init__(self, opt) + + def keypress(self, size, key): + return key + + def selectable(self): + return True + + +class OptionWalker(urwid.ListWalker): + def __init__(self, options): + urwid.ListWalker.__init__(self) + self.options = options + self.focus = 0 + signals.update_settings.connect(self.sig_update_settings) + + def sig_update_settings(self, sender): + self._modified() + + def set_focus(self, pos): + self.focus = pos + + def get_focus(self): + return self.options[self.focus].render(True), self.focus + + def get_next(self, pos): + if pos >= len(self.options)-1: + return None, None + return self.options[pos+1].render(False), pos+1 + + def get_prev(self, pos): + if pos <= 0: + return None, None + return self.options[pos-1].render(False), pos-1 + + +class OptionListBox(urwid.ListBox): + def __init__(self, options): + urwid.ListBox.__init__( + self, + OptionWalker(options) + ) + + def keypress(self, size, key): + key = common.shortcuts(key) + if key == "enter": + self.get_focus()[0].option.ativate() + return None + return super(self.__class__, self).keypress(size, key) + + +_neg = lambda: False +class Option: + def __init__(self, text, getstate=None, ativate=None): + self.text = text + self.getstate = getstate or _neg + self.ativate = ativate or _neg + + def render(self, focus): + return OptionWidget(self, self.text, self.getstate(), focus) + + +class Options(urwid.WidgetWrap): + def __init__(self, master): + self.master = master + self.lb = OptionListBox( + [ + Option( + "Anti-Cache", + lambda: master.anticache, + self.toggle_anticache + ), + Option( + "Anti-Compression", + lambda: master.anticomp, + self.toggle_anticomp + ), + #Option("Header Set Patterns"), + #Option("Ignore Patterns"), + Option( + "Kill Extra", + lambda: master.killextra, + self.toggle_killextra + ), + #Option("Manage Scripts"), + #Option("Replacement Patterns"), + Option( + "Show Host", + lambda: master.showhost, + self.toggle_showhost + ), + #Option("Sticky Cookies"), + #Option("Sticky Auth"), + #Option("TCP Proxying"), + Option( + "No Refresh", + lambda: not master.refresh_server_playback, + self.toggle_refresh_server_playback + ), + Option( + "No Upstream Certs", + lambda: master.server.config.no_upstream_cert, + self.toggle_upstream_cert + ), + ] + ) + title = urwid.Text("Options") + title = urwid.Padding(title, align="left", width=("relative", 100)) + title = urwid.AttrWrap(title, "heading") + self._w = urwid.Frame( + self.lb, + header = title + ) + self.master.loop.widget.footer.update("") + + def toggle_anticache(self): + self.master.anticache = not self.master.anticache + + def toggle_anticomp(self): + self.master.anticomp = not self.master.anticomp + + def toggle_killextra(self): + self.master.killextra = not self.master.killextra + + def toggle_showhost(self): + self.master.showhost = not self.master.showhost + + def toggle_refresh_server_playback(self): + self.master.refresh_server_playback = not self.master.refresh_server_playback + + def toggle_upstream_cert(self): + self.master.server.config.no_upstream_cert = not self.master.server.config.no_upstream_cert + signals.update_settings.send(self) diff --git a/libmproxy/console/palettes.py b/libmproxy/console/palettes.py index cfb2702c4..020863f87 100644 --- a/libmproxy/console/palettes.py +++ b/libmproxy/console/palettes.py @@ -17,6 +17,9 @@ class Palette: # Help 'key', 'head', 'text', + # Options + 'option_selected', 'option_active', 'option_active_selected', + # List and Connections 'method', 'focus', 'code_200', 'code_300', 'code_400', 'code_500', 'code_other', @@ -60,6 +63,9 @@ class LowDark(Palette): head = ('white,bold', 'default'), text = ('light gray', 'default'), + # Options + option_selected = ('light gray', 'dark blue'), + # List and Connections method = ('dark cyan', 'default'), focus = ('yellow', 'default'), @@ -112,6 +118,11 @@ class LowLight(Palette): head = ('black,bold', 'default'), text = ('dark gray', 'default'), + # Options + option_selected = ('light gray', 'dark blue'), + option_active = ('light red', 'default'), + option_active_selected = ('light red', 'dark blue'), + # List and Connections method = ('dark cyan', 'default'), focus = ('black', 'default'), @@ -181,6 +192,11 @@ class SolarizedLight(LowLight): key = (sol_blue, 'default',), head = (sol_base00, 'default'), + # Options + option_selected = (sol_base2, sol_base02), + option_active = (sol_orange, 'default'), + option_active_selected = (sol_orange, sol_base02), + # List and Connections method = (sol_cyan, 'default'), focus = (sol_base01, 'default'), @@ -223,6 +239,9 @@ class SolarizedDark(LowDark): key = (sol_blue, 'default',), head = (sol_base00, 'default'), + # Options + option_selected = (sol_base03, sol_base01), + # List and Connections method = (sol_cyan, 'default'), focus = (sol_base1, 'default'), @@ -252,10 +271,10 @@ class SolarizedDark(LowDark): palettes = { - "lowlight": LowLight(), - "lowdark": LowDark(), - "light": Light(), - "dark": Dark(), + #"lowlight": LowLight(), + #"lowdark": LowDark(), + #"light": Light(), + #"dark": Dark(), "solarized_light": SolarizedLight(), - "solarized_dark": SolarizedDark(), + #"solarized_dark": SolarizedDark(), } diff --git a/libmproxy/console/window.py b/libmproxy/console/window.py index 14a3acd2b..1d22f280c 100644 --- a/libmproxy/console/window.py +++ b/libmproxy/console/window.py @@ -64,6 +64,8 @@ class Window(urwid.Frame): text = self.master.state.intercept_txt, callback = self.master.set_intercept ) + elif k == "o": + self.master.view_options() elif k == "Q": raise urwid.ExitMainLoop elif k == "q": @@ -107,19 +109,6 @@ class Window(urwid.Frame): ), callback = self.master.stop_server_playback_prompt, ) - elif k == "o": - signals.status_prompt_onekey.send( - prompt = "Options", - keys = ( - ("anticache", "a"), - ("anticomp", "c"), - ("showhost", "h"), - ("killextra", "k"), - ("norefresh", "n"), - ("no-upstream-certs", "u"), - ), - callback = self.master._change_options - ) elif k == "t": signals.status_prompt.send( prompt = "Sticky cookie filter",