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