diff options
Diffstat (limited to 'libmproxy/console/options.py')
-rw-r--r-- | libmproxy/console/options.py | 310 |
1 files changed, 190 insertions, 120 deletions
diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index db6cc151..dc7e00d5 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -1,154 +1,125 @@ import urwid -from . import common, signals +from . import common, signals, grideditor, contentview +from . import select, palettes -help_context = None footer = [ ('heading_key', "enter/space"), ":toggle ", ('heading_key', "C"), ":clear all ", ] - -class OptionWidget(urwid.WidgetWrap): - def __init__(self, option, text, shortcut, active, focus): - self.option = option - textattr = "text" - keyattr = "key" - if focus and active: - textattr = "option_active_selected" - keyattr = "option_selected_key" - elif focus: - textattr = "option_selected" - keyattr = "option_selected_key" - elif active: - textattr = "option_active" - text = common.highlight_key( - text, - shortcut, - textattr=textattr, - keyattr=keyattr - ) - opt = urwid.Text(text, align="center") - opt = urwid.AttrWrap(opt, textattr) - 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) - ) - self.options = options - self.keymap = {} - for i in options: - self.keymap[i.shortcut] = i - - def keypress(self, size, key): - if key == "enter" or key == " ": - self.get_focus()[0].option.activate() - return None - key = common.shortcuts(key) - if key in self.keymap: - self.keymap[key].activate() - self.set_focus(self.options.index(self.keymap[key])) - return None - return super(self.__class__, self).keypress(size, key) - - -_neg = lambda: False -class Option: - def __init__(self, text, shortcut, getstate=None, activate=None): - self.text = text - self.shortcut = shortcut - self.getstate = getstate or _neg - self.activate = activate or _neg - - def render(self, focus): - return OptionWidget(self, self.text, self.shortcut, self.getstate(), focus) +def _mkhelp(): + text = [] + keys = [ + ("enter/space", "activate option"), + ("C", "clear all options"), + ] + text.extend(common.format_keyvals(keys, key="key", val="text", indent=4)) + return text +help_context = _mkhelp() class Options(urwid.WidgetWrap): def __init__(self, master): self.master = master - self.lb = OptionListBox( + self.lb = select.Select( [ - Option( + select.Heading("Traffic Manipulation"), + select.Option( + "Header Set Patterns", + "H", + lambda: master.setheaders.count(), + self.setheaders + ), + select.Option( + "Ignore Patterns", + "I", + lambda: master.server.config.check_ignore, + self.ignorepatterns + ), + select.Option( + "Replacement Patterns", + "R", + lambda: master.replacehooks.count(), + self.replacepatterns + ), + select.Option( + "Scripts", + "S", + lambda: master.scripts, + self.scripts + ), + + select.Heading("Interface"), + select.Option( + "Default Display Mode", + "M", + self.has_default_displaymode, + self.default_displaymode + ), + select.Option( + "Palette", + "P", + lambda: self.master.palette != palettes.DEFAULT, + self.palette + ), + select.Option( + "Show Host", + "w", + lambda: master.showhost, + self.toggle_showhost + ), + + select.Heading("Network"), + select.Option( + "No Upstream Certs", + "U", + lambda: master.server.config.no_upstream_cert, + self.toggle_upstream_cert + ), + select.Option( + "TCP Proxying", + "T", + lambda: master.server.config.check_tcp, + self.tcp_proxy + ), + + select.Heading("Utility"), + select.Option( "Anti-Cache", "a", lambda: master.anticache, self.toggle_anticache ), - Option( + select.Option( "Anti-Compression", "o", lambda: master.anticomp, self.toggle_anticomp ), - #Option("Header Set Patterns"), - #Option("Ignore Patterns"), - Option( + select.Option( "Kill Extra", - "E", + "x", lambda: master.killextra, self.toggle_killextra ), - #Option("Manage Scripts"), - #Option("Replacement Patterns"), - Option( - "Show Host", - "H", - lambda: master.showhost, - self.toggle_showhost - ), - #Option("Sticky Cookies"), - #Option("Sticky Auth"), - #Option("TCP Proxying"), - Option( + select.Option( "No Refresh", - "R", + "f", lambda: not master.refresh_server_playback, self.toggle_refresh_server_playback ), - Option( - "No Upstream Certs", - "U", - lambda: master.server.config.no_upstream_cert, - self.toggle_upstream_cert + select.Option( + "Sticky Auth", + "A", + lambda: master.stickyauth_txt, + self.sticky_auth + ), + select.Option( + "Sticky Cookies", + "t", + lambda: master.stickycookie_txt, + self.sticky_cookie ), ] ) @@ -160,6 +131,10 @@ class Options(urwid.WidgetWrap): header = title ) self.master.loop.widget.footer.update("") + signals.update_settings.connect(self.sig_update_settings) + + def sig_update_settings(self, sender): + self.lb.walker._modified() def keypress(self, size, key): if key == "C": @@ -174,9 +149,18 @@ class Options(urwid.WidgetWrap): self.master.showhost = False self.master.refresh_server_playback = True self.master.server.config.no_upstream_cert = False + self.master.setheaders.clear() + self.master.replacehooks.clear() + self.master.set_ignore_filter([]) + self.master.set_tcp_filter([]) + self.master.scripts = [] + self.master.set_stickyauth(None) + self.master.set_stickycookie(None) + self.master.state.default_body_view = contentview.get("Auto") + signals.update_settings.send(self) signals.status_message.send( - message = "All options cleared", + message = "All select.Options cleared", expire = 1 ) @@ -198,3 +182,89 @@ class Options(urwid.WidgetWrap): 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) + + def setheaders(self): + def _set(*args, **kwargs): + self.master.setheaders.set(*args, **kwargs) + signals.update_settings.send(self) + self.master.view_grideditor( + grideditor.SetHeadersEditor( + self.master, + self.master.setheaders.get_specs(), + _set + ) + ) + + def ignorepatterns(self): + def _set(ignore): + patterns = (x[0] for x in ignore) + self.master.set_ignore_filter(patterns) + signals.update_settings.send(self) + self.master.view_grideditor( + grideditor.HostPatternEditor( + self.master, + [[x] for x in self.master.get_ignore_filter()], + _set + ) + ) + + def replacepatterns(self): + def _set(*args, **kwargs): + self.master.replacehooks.set(*args, **kwargs) + signals.update_settings.send(self) + self.master.view_grideditor( + grideditor.ReplaceEditor( + self.master, + self.master.replacehooks.get_specs(), + _set + ) + ) + + def scripts(self): + self.master.view_grideditor( + grideditor.ScriptEditor( + self.master, + [[i.command] for i in self.master.scripts], + self.master.edit_scripts + ) + ) + + def default_displaymode(self): + signals.status_prompt_onekey.send( + prompt = "Global default display mode", + keys = contentview.view_prompts, + callback = self.master.change_default_display_mode + ) + + def has_default_displaymode(self): + return self.master.state.default_body_view.name != "Auto" + + def tcp_proxy(self): + def _set(tcp): + patterns = (x[0] for x in tcp) + self.master.set_tcp_filter(patterns) + signals.update_settings.send(self) + self.master.view_grideditor( + grideditor.HostPatternEditor( + self.master, + [[x] for x in self.master.get_tcp_filter()], + _set + ) + ) + + def sticky_auth(self): + signals.status_prompt.send( + prompt = "Sticky auth filter", + text = self.master.stickyauth_txt, + callback = self.master.set_stickyauth + ) + + def sticky_cookie(self): + signals.status_prompt.send( + prompt = "Sticky cookie filter", + text = self.master.stickycookie_txt, + callback = self.master.set_stickycookie + ) + + def palette(self): + self.master.view_palette_picker() |