From 65971f02ade7cc2126b4142a32c363e02112f95c Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Fri, 3 Apr 2015 14:10:57 +1300 Subject: console: basic options page --- libmproxy/console/options.py | 151 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 libmproxy/console/options.py (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py new file mode 100644 index 00000000..c6c4afb7 --- /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) -- cgit v1.2.3 From 57bdb893425058d03b1aaf28e1c774c81a8d9403 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Fri, 3 Apr 2015 14:38:04 +1300 Subject: console: keyboard shortcuts for options --- libmproxy/console/options.py | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index c6c4afb7..bb6b6c09 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -6,15 +6,25 @@ help_context = None class OptionWidget(urwid.WidgetWrap): - def __init__(self, option, text, active, focus): + def __init__(self, option, text, shortcut, active, focus): self.option = option - opt = urwid.Text(text, align="center") + textattr = "text" + keyattr = "key" if focus and active: - opt = urwid.AttrWrap(opt, "option_active_selected") + textattr = "option_active_selected" elif focus: - opt = urwid.AttrWrap(opt, "option_selected") + textattr = "option_selected" + keyattr = "option_selected_key" elif active: - opt = urwid.AttrWrap(opt, "option_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) @@ -58,24 +68,33 @@ class OptionListBox(urwid.ListBox): self, OptionWalker(options) ) + self.options = options + self.keymap = {} + for i in options: + self.keymap[i.shortcut] = i def keypress(self, size, key): key = common.shortcuts(key) if key == "enter": - self.get_focus()[0].option.ativate() + self.get_focus()[0].option.activate() + return None + 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, getstate=None, ativate=None): + def __init__(self, text, shortcut, getstate=None, activate=None): self.text = text + self.shortcut = shortcut self.getstate = getstate or _neg - self.ativate = ativate or _neg + self.activate = activate or _neg def render(self, focus): - return OptionWidget(self, self.text, self.getstate(), focus) + return OptionWidget(self, self.text, self.shortcut, self.getstate(), focus) class Options(urwid.WidgetWrap): @@ -85,11 +104,13 @@ class Options(urwid.WidgetWrap): [ Option( "Anti-Cache", + "C", lambda: master.anticache, self.toggle_anticache ), Option( "Anti-Compression", + "o", lambda: master.anticomp, self.toggle_anticomp ), @@ -97,6 +118,7 @@ class Options(urwid.WidgetWrap): #Option("Ignore Patterns"), Option( "Kill Extra", + "E", lambda: master.killextra, self.toggle_killextra ), @@ -104,6 +126,7 @@ class Options(urwid.WidgetWrap): #Option("Replacement Patterns"), Option( "Show Host", + "H", lambda: master.showhost, self.toggle_showhost ), @@ -112,11 +135,13 @@ class Options(urwid.WidgetWrap): #Option("TCP Proxying"), Option( "No Refresh", + "R", 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 ), -- cgit v1.2.3 From 41a1a0bef3b40b744c232a1adba478f8ac0f2c6c Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Fri, 3 Apr 2015 14:47:55 +1300 Subject: console: C to clear all options, correct footer in options screen --- libmproxy/console/options.py | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index bb6b6c09..db6cc151 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -3,6 +3,10 @@ import urwid from . import common, signals help_context = None +footer = [ + ('heading_key', "enter/space"), ":toggle ", + ('heading_key', "C"), ":clear all ", +] class OptionWidget(urwid.WidgetWrap): @@ -12,6 +16,7 @@ class OptionWidget(urwid.WidgetWrap): keyattr = "key" if focus and active: textattr = "option_active_selected" + keyattr = "option_selected_key" elif focus: textattr = "option_selected" keyattr = "option_selected_key" @@ -74,10 +79,10 @@ class OptionListBox(urwid.ListBox): self.keymap[i.shortcut] = i def keypress(self, size, key): - key = common.shortcuts(key) - if key == "enter": + 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])) @@ -104,7 +109,7 @@ class Options(urwid.WidgetWrap): [ Option( "Anti-Cache", - "C", + "a", lambda: master.anticache, self.toggle_anticache ), @@ -156,6 +161,25 @@ class Options(urwid.WidgetWrap): ) self.master.loop.widget.footer.update("") + def keypress(self, size, key): + if key == "C": + self.clearall() + return None + return super(self.__class__, self).keypress(size, key) + + def clearall(self): + self.master.anticache = False + self.master.anticomp = False + self.master.killextra = False + self.master.showhost = False + self.master.refresh_server_playback = True + self.master.server.config.no_upstream_cert = False + signals.update_settings.send(self) + signals.status_message.send( + message = "All options cleared", + expire = 1 + ) + def toggle_anticache(self): self.master.anticache = not self.master.anticache -- cgit v1.2.3 From 3704411466364bea76e0fb231cd1724f45318522 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Fri, 3 Apr 2015 20:04:19 +1300 Subject: Minimal help context for options --- libmproxy/console/options.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index db6cc151..e2227f08 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -2,12 +2,21 @@ import urwid from . import common, signals -help_context = None footer = [ ('heading_key', "enter/space"), ":toggle ", ('heading_key', "C"), ":clear all ", ] +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 OptionWidget(urwid.WidgetWrap): def __init__(self, option, text, shortcut, active, focus): @@ -25,12 +34,12 @@ class OptionWidget(urwid.WidgetWrap): text = common.highlight_key( text, shortcut, - textattr=textattr, - keyattr=keyattr + textattr = textattr, + keyattr = keyattr ) opt = urwid.Text(text, align="center") opt = urwid.AttrWrap(opt, textattr) - opt = urwid.Padding(opt, align="center", width=("relative", 20)) + opt = urwid.Padding(opt, align = "center", width = ("relative", 20)) urwid.WidgetWrap.__init__(self, opt) def keypress(self, size, key): -- cgit v1.2.3 From 9e39999706dc1fbe3907a4d98aa30d777d6dfba7 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Mon, 6 Apr 2015 16:46:51 +1200 Subject: Add headings to options, start migrating more options into options screen SetHeaders first... --- libmproxy/console/options.py | 108 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 85 insertions(+), 23 deletions(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index e2227f08..b6e274f3 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -1,6 +1,6 @@ import urwid -from . import common, signals +from . import common, signals, grideditor footer = [ ('heading_key', "enter/space"), ":toggle ", @@ -37,9 +37,9 @@ class OptionWidget(urwid.WidgetWrap): textattr = textattr, keyattr = keyattr ) - opt = urwid.Text(text, align="center") + opt = urwid.Text(text, align="left") opt = urwid.AttrWrap(opt, textattr) - opt = urwid.Padding(opt, align = "center", width = ("relative", 20)) + opt = urwid.Padding(opt, align = "center", width = 40) urwid.WidgetWrap.__init__(self, opt) def keypress(self, size, key): @@ -85,7 +85,10 @@ class OptionListBox(urwid.ListBox): self.options = options self.keymap = {} for i in options: - self.keymap[i.shortcut] = i + if hasattr(i, "shortcut"): + if i.shortcut in self.keymap: + raise ValueError("Duplicate shortcut key: %s"%i.shortcut) + self.keymap[i.shortcut] = i def keypress(self, size, key): if key == "enter" or key == " ": @@ -99,6 +102,18 @@ class OptionListBox(urwid.ListBox): return super(self.__class__, self).keypress(size, key) + +class Heading: + def __init__(self, text): + self.text = text + + def render(self, focus): + opt = urwid.Text("\n" + self.text, align="left") + opt = urwid.AttrWrap(opt, "title") + opt = urwid.Padding(opt, align = "center", width = 40) + return opt + + _neg = lambda: False class Option: def __init__(self, text, shortcut, getstate=None, activate=None): @@ -116,6 +131,51 @@ class Options(urwid.WidgetWrap): self.master = master self.lb = OptionListBox( [ + Heading("Traffic Manipulation"), + Option( + "Header Set Patterns", + "H", + lambda: master.setheaders.count(), + self.setheaders + ), + Option( + "Ignore Patterns", + "I" + ), + Option( + "Replacement Patterns", + "R" + ), + Option( + "Scripts", + "S" + ), + + Heading("Interface"), + Option( + "Default Display Mode", + "M" + ), + Option( + "Show Host", + "w", + lambda: master.showhost, + self.toggle_showhost + ), + + Heading("Network"), + Option( + "No Upstream Certs", + "U", + lambda: master.server.config.no_upstream_cert, + self.toggle_upstream_cert + ), + Option( + "TCP Proxying", + "T" + ), + + Heading("Utility"), Option( "Anti-Cache", "a", @@ -128,36 +188,25 @@ class Options(urwid.WidgetWrap): lambda: master.anticomp, self.toggle_anticomp ), - #Option("Header Set Patterns"), - #Option("Ignore Patterns"), 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( "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 + "Sticky Auth", + "A" + ), + Option( + "Sticky Cookies", + "t" ), ] ) @@ -183,6 +232,7 @@ 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() signals.update_settings.send(self) signals.status_message.send( message = "All options cleared", @@ -207,3 +257,15 @@ 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 + ) + ) -- cgit v1.2.3 From 15246c34039ecd1c27da52d1474910cecf6e2061 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Mon, 6 Apr 2015 17:02:51 +1200 Subject: console: ignore patterns to new options screen. --- libmproxy/console/options.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index b6e274f3..4cc768b6 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -140,7 +140,9 @@ class Options(urwid.WidgetWrap): ), Option( "Ignore Patterns", - "I" + "I", + lambda: master.server.config.check_ignore, + self.ignorepatterns ), Option( "Replacement Patterns", @@ -233,6 +235,7 @@ class Options(urwid.WidgetWrap): self.master.refresh_server_playback = True self.master.server.config.no_upstream_cert = False self.master.setheaders.clear() + self.master.set_ignore_filter([]) signals.update_settings.send(self) signals.status_message.send( message = "All options cleared", @@ -269,3 +272,16 @@ class Options(urwid.WidgetWrap): _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 + ) + ) -- cgit v1.2.3 From 488adcb79ef2820d1bed59ab51728e59c7924e1f Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Mon, 6 Apr 2015 17:05:52 +1200 Subject: console: replacement patterns to new option screen --- libmproxy/console/options.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index 4cc768b6..88c9cd98 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -146,7 +146,9 @@ class Options(urwid.WidgetWrap): ), Option( "Replacement Patterns", - "R" + "R", + lambda: master.replacehooks.count(), + self.replacepatterns ), Option( "Scripts", @@ -235,6 +237,7 @@ class Options(urwid.WidgetWrap): 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([]) signals.update_settings.send(self) signals.status_message.send( @@ -285,3 +288,15 @@ class Options(urwid.WidgetWrap): _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 + ) + ) -- cgit v1.2.3 From acb6b5667cd3dfd972b0229be2e2e7dc62ea01ac Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Mon, 6 Apr 2015 17:11:02 +1200 Subject: console: scripts to new options screen --- libmproxy/console/options.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index 88c9cd98..10c301f4 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -152,7 +152,9 @@ class Options(urwid.WidgetWrap): ), Option( "Scripts", - "S" + "S", + lambda: master.scripts, + self.scripts ), Heading("Interface"), @@ -239,6 +241,7 @@ class Options(urwid.WidgetWrap): self.master.setheaders.clear() self.master.replacehooks.clear() self.master.set_ignore_filter([]) + self.master.scripts = [] signals.update_settings.send(self) signals.status_message.send( message = "All options cleared", @@ -300,3 +303,12 @@ class Options(urwid.WidgetWrap): _set ) ) + + def scripts(self): + self.master.view_grideditor( + grideditor.ScriptEditor( + self.master, + [[i.command] for i in self.master.scripts], + self.master.edit_scripts + ) + ) -- cgit v1.2.3 From ec7572697a3877d26a5a05569c71a1487556889e Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Mon, 6 Apr 2015 17:14:32 +1200 Subject: console: default display mode to new options screen --- libmproxy/console/options.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index 10c301f4..2b03f388 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -1,6 +1,6 @@ import urwid -from . import common, signals, grideditor +from . import common, signals, grideditor, contentview footer = [ ('heading_key', "enter/space"), ":toggle ", @@ -160,7 +160,9 @@ class Options(urwid.WidgetWrap): Heading("Interface"), Option( "Default Display Mode", - "M" + "M", + self.has_default_displaymode, + self.default_displaymode ), Option( "Show Host", @@ -312,3 +314,13 @@ class Options(urwid.WidgetWrap): 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" -- cgit v1.2.3 From c4e0f9d8d77c7306f7af4509250541f4b9ea8524 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Mon, 6 Apr 2015 17:19:52 +1200 Subject: console: TCP proxy patterns to new options screen --- libmproxy/console/options.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index 2b03f388..bfe6a591 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -180,7 +180,9 @@ class Options(urwid.WidgetWrap): ), Option( "TCP Proxying", - "T" + "T", + lambda: master.server.config.check_tcp, + self.tcp_proxy ), Heading("Utility"), @@ -243,6 +245,7 @@ class Options(urwid.WidgetWrap): self.master.setheaders.clear() self.master.replacehooks.clear() self.master.set_ignore_filter([]) + self.master.set_tcp_filter([]) self.master.scripts = [] signals.update_settings.send(self) signals.status_message.send( @@ -324,3 +327,16 @@ class Options(urwid.WidgetWrap): 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 + ) + ) -- cgit v1.2.3 From 0d6de19b070789405ed2713b6d973b06ea7922fc Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Mon, 6 Apr 2015 17:27:46 +1200 Subject: console: sticky cookies and auth to options screen --- libmproxy/console/options.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index bfe6a591..7a03f718 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -212,11 +212,15 @@ class Options(urwid.WidgetWrap): ), Option( "Sticky Auth", - "A" + "A", + lambda: master.stickyauth_txt, + self.sticky_auth ), Option( "Sticky Cookies", - "t" + "t", + lambda: master.stickycookie_txt, + self.sticky_cookie ), ] ) @@ -247,6 +251,10 @@ class Options(urwid.WidgetWrap): 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", @@ -340,3 +348,17 @@ class Options(urwid.WidgetWrap): _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 + ) -- cgit v1.2.3 From 538f215458891f045b2de6a8b675db48754fbb4a Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Mon, 6 Apr 2015 17:45:36 +1200 Subject: console: factor out selection widget --- libmproxy/console/options.py | 157 ++++++++----------------------------------- 1 file changed, 27 insertions(+), 130 deletions(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index 7a03f718..27e01468 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -1,6 +1,7 @@ import urwid from . import common, signals, grideditor, contentview +from . import select footer = [ ('heading_key', "enter/space"), ":toggle ", @@ -18,205 +19,97 @@ def _mkhelp(): help_context = _mkhelp() -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="left") - opt = urwid.AttrWrap(opt, textattr) - opt = urwid.Padding(opt, align = "center", width = 40) - 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: - if hasattr(i, "shortcut"): - if i.shortcut in self.keymap: - raise ValueError("Duplicate shortcut key: %s"%i.shortcut) - 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) - - - -class Heading: - def __init__(self, text): - self.text = text - - def render(self, focus): - opt = urwid.Text("\n" + self.text, align="left") - opt = urwid.AttrWrap(opt, "title") - opt = urwid.Padding(opt, align = "center", width = 40) - return opt - - -_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) - - class Options(urwid.WidgetWrap): def __init__(self, master): self.master = master - self.lb = OptionListBox( + self.lb = select.Select( [ - Heading("Traffic Manipulation"), - Option( + select.Heading("Traffic Manipulation"), + select.Option( "Header Set Patterns", "H", lambda: master.setheaders.count(), self.setheaders ), - Option( + select.Option( "Ignore Patterns", "I", lambda: master.server.config.check_ignore, self.ignorepatterns ), - Option( + select.Option( "Replacement Patterns", "R", lambda: master.replacehooks.count(), self.replacepatterns ), - Option( + select.Option( "Scripts", "S", lambda: master.scripts, self.scripts ), - Heading("Interface"), - Option( + select.Heading("Interface"), + select.Option( "Default Display Mode", "M", self.has_default_displaymode, self.default_displaymode ), - Option( + select.Option( "Show Host", "w", lambda: master.showhost, self.toggle_showhost ), - Heading("Network"), - Option( + select.Heading("Network"), + select.Option( "No Upstream Certs", "U", lambda: master.server.config.no_upstream_cert, self.toggle_upstream_cert ), - Option( + select.Option( "TCP Proxying", "T", lambda: master.server.config.check_tcp, self.tcp_proxy ), - Heading("Utility"), - Option( + 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( + select.Option( "Kill Extra", "x", lambda: master.killextra, self.toggle_killextra ), - Option( + select.Option( "No Refresh", "f", lambda: not master.refresh_server_playback, self.toggle_refresh_server_playback ), - Option( + select.Option( "Sticky Auth", "A", lambda: master.stickyauth_txt, self.sticky_auth ), - Option( + select.Option( "Sticky Cookies", "t", lambda: master.stickycookie_txt, @@ -224,14 +117,18 @@ class Options(urwid.WidgetWrap): ), ] ) - title = urwid.Text("Options") + title = urwid.Text("select.Options") title = urwid.Padding(title, align="left", width=("relative", 100)) - title = urwid.AttrWrap(title, "heading") + title = urwid.AttrWrap(title, "select.Heading") self._w = urwid.Frame( self.lb, 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": @@ -257,7 +154,7 @@ class Options(urwid.WidgetWrap): signals.update_settings.send(self) signals.status_message.send( - message = "All options cleared", + message = "All select.Options cleared", expire = 1 ) -- cgit v1.2.3 From 1cb1ee411b9c8ffc40f83bcca99770af7f43a521 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Tue, 7 Apr 2015 08:42:40 +1200 Subject: console: palette picker for the options screen --- libmproxy/console/options.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index 27e01468..23774dc3 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -57,6 +57,12 @@ class Options(urwid.WidgetWrap): self.has_default_displaymode, self.default_displaymode ), + select.Option( + "Palette", + "P", + lambda: False, + self.palette + ), select.Option( "Show Host", "w", @@ -117,9 +123,9 @@ class Options(urwid.WidgetWrap): ), ] ) - title = urwid.Text("select.Options") + title = urwid.Text("Options") title = urwid.Padding(title, align="left", width=("relative", 100)) - title = urwid.AttrWrap(title, "select.Heading") + title = urwid.AttrWrap(title, "heading") self._w = urwid.Frame( self.lb, header = title @@ -259,3 +265,6 @@ class Options(urwid.WidgetWrap): text = self.master.stickycookie_txt, callback = self.master.set_stickycookie ) + + def palette(self): + self.master.view_palette_picker() -- cgit v1.2.3 From e76467e977c061d92f88500b23f11bbf3cc365bb Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Tue, 7 Apr 2015 15:59:38 +1200 Subject: Refactor flow list state management - Use signal mechanism for state synchronisation - Move "Copy to clipboard" shortcut to "P" --- libmproxy/console/options.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index 23774dc3..dc7e00d5 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -1,7 +1,7 @@ import urwid from . import common, signals, grideditor, contentview -from . import select +from . import select, palettes footer = [ ('heading_key', "enter/space"), ":toggle ", @@ -60,7 +60,7 @@ class Options(urwid.WidgetWrap): select.Option( "Palette", "P", - lambda: False, + lambda: self.master.palette != palettes.DEFAULT, self.palette ), select.Option( -- cgit v1.2.3 From e963a9da4887268b03ceecf55086674121047056 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Fri, 17 Apr 2015 12:54:29 +1200 Subject: console: suport unary attributes Attributes with no value are treated as unary, e.g. "Secure" rather than "Secure=". If you really want to have an empty attribute value you can edit the header directly. Behind the scenes, restructure GridEditor to know about data conversion in and out of the editor. --- libmproxy/console/options.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index dc7e00d5..c728123f 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -197,13 +197,12 @@ class Options(urwid.WidgetWrap): def ignorepatterns(self): def _set(ignore): - patterns = (x[0] for x in ignore) - self.master.set_ignore_filter(patterns) + self.master.set_ignore_filter(ignore) signals.update_settings.send(self) self.master.view_grideditor( grideditor.HostPatternEditor( self.master, - [[x] for x in self.master.get_ignore_filter()], + self.master.get_ignore_filter(), _set ) ) @@ -241,13 +240,12 @@ class Options(urwid.WidgetWrap): def tcp_proxy(self): def _set(tcp): - patterns = (x[0] for x in tcp) - self.master.set_tcp_filter(patterns) + self.master.set_tcp_filter(tcp) signals.update_settings.send(self) self.master.view_grideditor( grideditor.HostPatternEditor( self.master, - [[x] for x in self.master.get_tcp_filter()], + self.master.get_tcp_filter(), _set ) ) -- cgit v1.2.3 From a05a70d8168a07c92b2a3ecbbb1958d85532efe3 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sat, 30 May 2015 12:03:28 +1200 Subject: Add coding style check, reformat. --- libmproxy/console/options.py | 1 + 1 file changed, 1 insertion(+) (limited to 'libmproxy/console/options.py') diff --git a/libmproxy/console/options.py b/libmproxy/console/options.py index c728123f..58a4d469 100644 --- a/libmproxy/console/options.py +++ b/libmproxy/console/options.py @@ -8,6 +8,7 @@ footer = [ ('heading_key', "C"), ":clear all ", ] + def _mkhelp(): text = [] keys = [ -- cgit v1.2.3