Add blinker dependency, start using it to refactor console app

Blinker lets us set up a central pub/sub mechanism to disentangle our object
structure.
This commit is contained in:
Aldo Cortesi 2015-03-21 11:19:20 +13:00
parent b475c8d6ea
commit 8725d50d03
9 changed files with 51 additions and 52 deletions

View File

@ -15,7 +15,7 @@ import urwid
import weakref
from .. import controller, flow, script
from . import flowlist, flowview, help, common, window
from . import flowlist, flowview, help, common, window, signals
from . import grideditor, palettes, contentview, flowdetailview, statusbar
EVENTLOG_SIZE = 500
@ -238,7 +238,9 @@ class ConsoleMaster(flow.FlowMaster):
try:
s = script.Script(command, self)
except script.ScriptError, v:
self.statusbar.message("Error loading script.")
signals.status_message.send(
message = "Error loading script."
)
self.add_event("Error loading script:\n%s"%v.args[0], "error")
return
@ -257,7 +259,7 @@ class ConsoleMaster(flow.FlowMaster):
return
ret = self.load_script(command)
if ret:
self.statusbar.message(ret)
signals.status_message.send(message=ret)
self.state.last_script = command
def toggle_eventlog(self):
@ -279,7 +281,7 @@ class ConsoleMaster(flow.FlowMaster):
print >> sys.stderr, e.strerror
sys.exit(1)
else:
self.statusbar.message(e.strerror)
signals.status_message.send(message=e.strerror)
return None
def client_playback_path(self, path):
@ -314,7 +316,7 @@ class ConsoleMaster(flow.FlowMaster):
try:
subprocess.call(cmd)
except:
self.statusbar.message("Can't start editor: %s" % " ".join(c))
signals.status_message.send(message="Can't start editor: %s" % " ".join(c))
else:
data = open(name, "rb").read()
self.ui.start()
@ -353,8 +355,8 @@ class ConsoleMaster(flow.FlowMaster):
try:
subprocess.call(cmd, shell=shell)
except:
self.statusbar.message(
"Can't start external viewer: %s" % " ".join(c)
signals.status_message.send(
message="Can't start external viewer: %s" % " ".join(c)
)
self.ui.start()
os.unlink(name)
@ -505,7 +507,7 @@ class ConsoleMaster(flow.FlowMaster):
fw.add(i)
f.close()
except IOError, v:
self.statusbar.message(v.strerror)
signals.status_message.send(message=v.strerror)
def save_one_flow(self, path, flow):
return self._write_flows(path, [flow])
@ -565,7 +567,7 @@ class ConsoleMaster(flow.FlowMaster):
self.prompting = False
self.onekey = False
self.view.set_focus("body")
self.statusbar.message("")
signals.status_message.send(message="")
def prompt_execute(self, txt=None):
if not txt:
@ -574,7 +576,7 @@ class ConsoleMaster(flow.FlowMaster):
self.prompt_done()
msg = p(txt, *args)
if msg:
self.statusbar.message(msg, 1000)
signals.status_message.send(message=msg, expire=1000)
def prompt_cancel(self):
self.prompt_done()

View File

@ -6,6 +6,7 @@ import os
from .. import utils
from ..protocol.http import CONTENT_MISSING, decoded
from . import signals
try:
import pyperclip
@ -198,7 +199,7 @@ def save_data(path, data, master, state):
with file(path, "wb") as f:
f.write(data)
except IOError, v:
master.statusbar.message(v.strerror)
signals.status_message.send(message=v.strerror)
def ask_save_path(prompt, data, master, state):
@ -248,11 +249,11 @@ def copy_flow(part, scope, flow, master, state):
if not data:
if scope == "q":
master.statusbar.message("No request content to copy.")
signals.status_message.send(message="No request content to copy.")
elif scope == "s":
master.statusbar.message("No response content to copy.")
signals.status_message.send(message="No response content to copy.")
else:
master.statusbar.message("No contents to copy.")
signals.status_message.send(message="No contents to copy.")
return
try:
@ -336,7 +337,7 @@ def ask_save_body(part, master, state, flow):
state
)
else:
master.statusbar.message("No content to save.")
signals.status_message.send(message="No content to save.")
class FlowCache:

View File

@ -1,7 +1,7 @@
from __future__ import absolute_import
import urwid
from netlib import http
from . import common
from . import common, signals
def _mkhelp():
@ -171,7 +171,7 @@ class ConnectionItem(urwid.WidgetWrap):
elif key == "r":
r = self.master.replay_request(self.flow)
if r:
self.master.statusbar.message(r)
signals.status_message.send(message=r)
self.master.sync_list_view()
elif key == "S":
if not self.master.server_playback:
@ -195,11 +195,11 @@ class ConnectionItem(urwid.WidgetWrap):
)
elif key == "V":
if not self.flow.modified():
self.master.statusbar.message("Flow not modified.")
signals.status_message.send(message="Flow not modified.")
return
self.state.revert(self.flow)
self.master.sync_list_view()
self.master.statusbar.message("Reverted.")
signals.status_message.send(message="Reverted.")
elif key == "w":
self.master.prompt_onekey(
"Save",
@ -285,7 +285,7 @@ class FlowListBox(urwid.ListBox):
def new_request(self, url, method):
parts = http.parse_url(str(url))
if not parts:
self.master.statusbar.message("Invalid Url")
signals.status_message.send(message="Invalid Url")
return
scheme, host, port, path = parts
f = self.master.create_request(method, scheme, host, port, path)

View File

@ -1,7 +1,7 @@
from __future__ import absolute_import
import os, sys, copy
import urwid
from . import common, grideditor, contentview
from . import common, grideditor, contentview, signals
from .. import utils, flow, controller
from ..protocol.http import HTTPRequest, HTTPResponse, CONTENT_MISSING, decoded
@ -282,10 +282,10 @@ class FlowView(urwid.WidgetWrap):
if last_search_string:
message = self.search(last_search_string, backwards)
if message:
self.master.statusbar.message(message)
signals.status_message.send(message=message)
else:
message = "no previous searches have been made"
self.master.statusbar.message(message)
signals.status_message.send(message=message)
return message
@ -606,7 +606,7 @@ class FlowView(urwid.WidgetWrap):
else:
new_flow, new_idx = self.state.get_prev(idx)
if new_flow is None:
self.master.statusbar.message("No more flows!")
signals.status_message.send(message="No more flows!")
return
self.master.view_flow(new_flow)
@ -681,7 +681,7 @@ class FlowView(urwid.WidgetWrap):
elif key == "D":
f = self.master.duplicate_flow(self.flow)
self.master.view_flow(f)
self.master.statusbar.message("Duplicated.")
signals.status_message.send(message="Duplicated.")
elif key == "e":
if self.state.view_flow_mode == common.VIEW_FLOW_REQUEST:
self.master.prompt_onekey(
@ -710,14 +710,14 @@ class FlowView(urwid.WidgetWrap):
)
key = None
elif key == "f":
self.master.statusbar.message("Loading all body data...")
signals.status_message.send(message="Loading all body data...")
self.state.add_flow_setting(
self.flow,
(self.state.view_flow_mode, "fullcontents"),
True
)
self.master.refresh_flow(self.flow)
self.master.statusbar.message("")
signals.status_message.send(message="")
elif key == "g":
if self.state.view_flow_mode == common.VIEW_FLOW_REQUEST:
scope = "q"
@ -738,15 +738,15 @@ class FlowView(urwid.WidgetWrap):
elif key == "r":
r = self.master.replay_request(self.flow)
if r:
self.master.statusbar.message(r)
signals.status_message.send(message=r)
self.master.refresh_flow(self.flow)
elif key == "V":
if not self.flow.modified():
self.master.statusbar.message("Flow not modified.")
signals.status_message.send(message="Flow not modified.")
return
self.state.revert(self.flow)
self.master.refresh_flow(self.flow)
self.master.statusbar.message("Reverted.")
signals.status_message.send(message="Reverted.")
elif key == "W":
self.master.path_prompt(
"Save this flow: ",
@ -761,7 +761,7 @@ class FlowView(urwid.WidgetWrap):
if os.environ.has_key("EDITOR") or os.environ.has_key("PAGER"):
self.master.spawn_external_viewer(conn.content, t)
else:
self.master.statusbar.message("Error! Set $EDITOR or $PAGER.")
signals.status_message.send(message="Error! Set $EDITOR or $PAGER.")
elif key == "|":
self.master.path_prompt(
"Send flow to script: ", self.state.last_script,
@ -785,7 +785,7 @@ class FlowView(urwid.WidgetWrap):
e = conn.headers.get_first("content-encoding", "identity")
if e != "identity":
if not conn.decode():
self.master.statusbar.message("Could not decode - invalid data?")
signals.status_message.send(message="Could not decode - invalid data?")
else:
self.master.prompt_onekey(
"Select encoding: ",

View File

@ -5,7 +5,7 @@ import re
import os
import urwid
from . import common
from . import common, signals
from .. import utils, filt, script
from netlib import http_uastrings
@ -125,14 +125,14 @@ class GridWalker(urwid.ListWalker):
try:
val = val.decode("string-escape")
except ValueError:
self.editor.master.statusbar.message(
"Invalid Python-style string encoding.", 1000
signals.status_message.send(
self, message = "Invalid Python-style string encoding.", expure = 1000
)
return
errors = self.lst[self.focus][1]
emsg = self.editor.is_error(self.focus_col, val)
if emsg:
self.editor.master.statusbar.message(emsg, 1000)
signals.status_message.send(message = emsg, expire = 1000)
errors.add(self.focus_col)
else:
errors.discard(self.focus_col)

View File

@ -0,0 +1,4 @@
import blinker
status_message = blinker.Signal()

View File

@ -3,26 +3,26 @@ import time
import urwid
from . import pathedit
from . import pathedit, signals
from .. import utils
class ActionBar(urwid.WidgetWrap):
def __init__(self):
self.message("")
urwid.WidgetWrap.__init__(self, urwid.Text(""))
signals.status_message.connect(self.message)
def selectable(self):
return True
def path_prompt(self, prompt, text):
self.expire = None
self._w = pathedit.PathEdit(prompt, text)
def prompt(self, prompt, text = ""):
self.expire = None
self._w = urwid.Edit(prompt, text or "")
def message(self, message, expire=None):
def message(self, sender, message, expire=None):
self.expire = expire
self._w = urwid.Text(message)
@ -127,9 +127,6 @@ class StatusBar(urwid.WidgetWrap):
return r
def redraw(self):
if self.ab.expire and time.time() > self.ab.expire:
self.message("")
fc = self.master.state.flow_count()
if self.master.state.focus is None:
offset = 0
@ -175,9 +172,3 @@ class StatusBar(urwid.WidgetWrap):
def prompt(self, prompt, text = ""):
self.ab.prompt(prompt, text)
def message(self, msg, expire=None):
if expire:
expire = time.time() + float(expire)/1000
self.ab.message(msg, expire)
self.master.loop.draw_screen()

View File

@ -1,5 +1,5 @@
import urwid
from . import common
from . import common, grideditor
class Window(urwid.Frame):
def __init__(self, master, body, header, footer):

View File

@ -21,7 +21,8 @@ deps = {
"pyOpenSSL>=0.14",
"tornado>=4.0.2",
"configargparse>=0.9.3",
"pyperclip>=1.5.8"
"pyperclip>=1.5.8",
"blinker>=1.3"
}
script_deps = {
"mitmproxy": {