From ed74ed24a008ecc866e64c22e0b938d8ee1a4f1c Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Fri, 23 Mar 2012 13:28:33 +1300 Subject: Add error indications to GridEditor. --- libmproxy/console/grideditor.py | 72 +++++++++++++++++++++++++++++------------ libmproxy/console/palettes.py | 2 ++ libmproxy/flow.py | 4 +++ test/test_flow.py | 4 +++ 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/libmproxy/console/grideditor.py b/libmproxy/console/grideditor.py index 12315ddd..22171440 100644 --- a/libmproxy/console/grideditor.py +++ b/libmproxy/console/grideditor.py @@ -13,10 +13,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import copy +import copy, re import urwid import common -from .. import utils +from .. import utils, filt def _mkhelp(): @@ -45,10 +45,15 @@ footer_editing = [ class SText(common.WWrap): - def __init__(self, txt, focused): + def __init__(self, txt, focused, error): w = urwid.Text(txt, wrap="any") if focused: - w = urwid.AttrWrap(w, "focusfield") + if error: + w = urwid.AttrWrap(w, "focusfield_error") + else: + w = urwid.AttrWrap(w, "focusfield") + elif error: + w = urwid.AttrWrap(w, "field_error") common.WWrap.__init__(self, w) def get_text(self): @@ -75,21 +80,22 @@ class SEdit(common.WWrap): class GridRow(common.WWrap): - def __init__(self, focused, editing, first_width, values): - self.focused, self.editing, self.first_width = focused, editing, first_width + def __init__(self, focused, editing, editor, values): + self.focused, self.editing, self.editor = focused, editing, editor + errors = values[1] self.fields = [] - for i, v in enumerate(values): + for i, v in enumerate(values[0]): if focused == i and editing: self.editing = SEdit(v) self.fields.append(self.editing) else: self.fields.append( - SText(v, True if focused == i else False) + SText(v, True if focused == i else False, i in errors) ) fspecs = self.fields[:] - fspecs[0] = ("fixed", first_width + 2, fspecs[0]) + fspecs[0] = ("fixed", self.editor.first_width + 2, fspecs[0]) w = urwid.Columns( fspecs, dividechars = 2 @@ -99,7 +105,14 @@ class GridRow(common.WWrap): common.WWrap.__init__(self, w) def get_value(self): - return [i.get_text() for i in self.fields] + vals = [] + errors = set([]) + for i, f in enumerate(self.fields): + v = f.get_text() + vals.append(v) + if self.editor.is_error(i, v): + errors.add(i) + return [vals, errors] def keypress(self, s, k): if self.editing: @@ -112,8 +125,14 @@ class GridRow(common.WWrap): class GridWalker(urwid.ListWalker): + """ + Stores rows as a list of (rows, errors) tuples, where rows is a list + and errors is a set with an entry of each offset in rows that is an + error. + """ def __init__(self, lst, editor): - self.lst, self.editor = lst, editor + self.lst = [(i, set([])) for i in lst] + self.editor = editor self.focus = 0 self.focus_col = 0 self.editing = False @@ -127,9 +146,9 @@ class GridWalker(urwid.ListWalker): return self.lst[self.focus][self.focus_col] def set_current_value(self, val): - row = list(self.lst[self.focus]) + row = list(self.lst[self.focus][0]) row[self.focus_col] = val - self.lst[self.focus] = tuple(row) + self.lst[self.focus] = [tuple(row), set([])] def delete_focus(self): if self.lst: @@ -139,7 +158,7 @@ class GridWalker(urwid.ListWalker): def _insert(self, pos): self.focus = pos - self.lst.insert(self.focus, [""]*self.editor.columns) + self.lst.insert(self.focus, [[""]*self.editor.columns, set([])]) self.focus_col = 0 self.start_edit() @@ -151,7 +170,7 @@ class GridWalker(urwid.ListWalker): def start_edit(self): if self.lst: - self.editing = GridRow(self.focus_col, True, self.editor.first_width, self.lst[self.focus]) + self.editing = GridRow(self.focus_col, True, self.editor, self.lst[self.focus]) self.editor.master.statusbar.update(footer_editing) self._modified() @@ -183,7 +202,7 @@ class GridWalker(urwid.ListWalker): if self.editing: return self.editing, self.focus elif self.lst: - return GridRow(self.focus_col, False, self.editor.first_width, self.lst[self.focus]), self.focus + return GridRow(self.focus_col, False, self.editor, self.lst[self.focus]), self.focus else: return None, None @@ -194,12 +213,12 @@ class GridWalker(urwid.ListWalker): def get_next(self, pos): if pos+1 >= len(self.lst): return None, None - return GridRow(None, False, self.editor.first_width, self.lst[pos+1]), pos+1 + return GridRow(None, False, self.editor, self.lst[pos+1]), pos+1 def get_prev(self, pos): if pos-1 < 0: return None, None - return GridRow(None, False, self.editor.first_width, self.lst[pos-1]), pos-1 + return GridRow(None, False, self.editor, self.lst[pos-1]), pos-1 class GridListBox(urwid.ListBox): @@ -279,8 +298,8 @@ class GridEditor(common.WWrap): if key in ["q", "esc"]: res = [] for i in self.walker.lst: - if any([x.strip() for x in i]): - res.append(i) + if any([x.strip() for x in i[0]]): + res.append(i[0]) self.callback(res, *self.cb_args, **self.cb_kwargs) self.master.pop_view() elif key in ["h", "left"]: @@ -307,6 +326,9 @@ class GridEditor(common.WWrap): else: return self.w.keypress(size, key) + def is_error(self, col, val): + return False + class QueryEditor(GridEditor): title = "Editing query" @@ -330,4 +352,14 @@ class ReplaceEditor(GridEditor): title = "Editing replacement patterns" columns = 3 headings = ("Filter", "Regex", "Replacement") + def is_error(self, col, val): + if col == 0: + if not filt.parse(val): + return True + elif col == 1: + try: + re.compile(val) + except re.error: + return True + return False diff --git a/libmproxy/console/palettes.py b/libmproxy/console/palettes.py index 78c79629..0b80de21 100644 --- a/libmproxy/console/palettes.py +++ b/libmproxy/console/palettes.py @@ -46,5 +46,7 @@ dark = [ # Grid Editor ('focusfield', 'black', 'light gray'), + ('focusfield_error', 'dark red', 'light gray'), + ('field_error', 'dark red', 'black'), ('editfield', 'black', 'light cyan'), ] diff --git a/libmproxy/flow.py b/libmproxy/flow.py index 59520167..5ff12b5b 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -44,6 +44,10 @@ class ReplaceHooks: cpatt = filt.parse(fpatt) if not cpatt: return False + try: + re.compile(rex) + except re.error: + return False self.lst.append((fpatt, rex, s, cpatt)) return True diff --git a/test/test_flow.py b/test/test_flow.py index 68555bd5..8a7da05c 100644 --- a/test/test_flow.py +++ b/test/test_flow.py @@ -1077,6 +1077,10 @@ class uReplaceHooks(libpry.AutoTree): h.run(f) assert f.request.content == "bar" + assert not h.add("~", "foo", "bar") + assert not h.add("foo", "*", "bar") + + tests = [ uReplaceHooks(), -- cgit v1.2.3