From ce8bed300627b6db2cc8ea4ad363e1b6b5dcd63e Mon Sep 17 00:00:00 2001 From: "brian m. carlson" Date: Thu, 22 Jan 2015 15:15:32 +0000 Subject: [PATCH 1/6] Add tests for pluggable hooks. Signed-off-by: brian m. carlson --- test/testfilemanip.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/testfilemanip.py b/test/testfilemanip.py index d9adc2a..9551169 100755 --- a/test/testfilemanip.py +++ b/test/testfilemanip.py @@ -253,6 +253,10 @@ class ExampleFile(newfol.filemanip.FileFormat): return [Record(['a', 'b'])] +class ExampleHook(newfol.filemanip.Hook): + pass + + class PluggableBackendsTest(unittest.TestCase): def test_adding_backend(self): FileStorage.register_backend('example', ExampleFile) @@ -269,5 +273,18 @@ class PluggableBackendsTest(unittest.TestCase): with self.assertRaises(KeyError): FileStorage.BACKENDS['example'] + +class PluggableHooksTest(unittest.TestCase): + def test_adding_hook(self): + FileStorage.register_hook('example', ExampleHook) + self.assertEqual(FileStorage.HOOKS['example'], ExampleHook) + + def test_removing_hook(self): + FileStorage.register_hook('example', ExampleFile) + self.assertEqual(FileStorage.HOOKS['example'], ExampleFile) + FileStorage.unregister_hook('example') + with self.assertRaises(KeyError): + FileStorage.HOOKS['example'] + if __name__ == '__main__': unittest.main() From 0c7f4e79908e7ab3ed84cdec656f46074f75ccf5 Mon Sep 17 00:00:00 2001 From: "brian m. carlson" Date: Sun, 15 Nov 2015 16:19:28 +0000 Subject: [PATCH 2/6] Add a header to record views. If one is using shortcut keys, it can be hard to determine if one is adding a record or searching. Add a header to make it easier to distinguish between the two. Signed-off-by: brian m. carlson --- lib/newfol/main.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/newfol/main.py b/lib/newfol/main.py index 4e4645f..88083ef 100644 --- a/lib/newfol/main.py +++ b/lib/newfol/main.py @@ -380,13 +380,14 @@ class AboutView(StandardView): class RecordView(StandardView): - def __init__(self, button, record=None): + def __init__(self, title, button, record=None): dbd = DatabaseData() if record is None: self.rec = filemanip.Record([None] * dbd.schema().nfields()) else: self.rec = record self.button_name = button + self.title = title def _compute_titles_from_table(self, table): titles = [] @@ -467,15 +468,19 @@ class RecordView(StandardView): def _render_standard(self, loop): self.loop = loop + head = self.text(self.title, "header") # We need a box widget for the frame, but GridFlow is a flow widget. pile = urwid.Pile([self._render_record(self.rec), self._render_buttons()]) - return urwid.Filler(pile, valign="top") + filler = urwid.Filler(pile, valign="top") + return urwid.Frame(filler, head) class DisplayRecordView(RecordView): - def __init__(self, record=None): - super().__init__(_("Commit"), record) + def __init__(self, title=None, record=None): + if title is None: + title = _("Add Record") + super().__init__(title, _("Commit"), record) def _build_record(self): fields = [i.widget_list[1].get_edit_text() for i in self.cells] @@ -543,7 +548,8 @@ class DisplayRecordView(RecordView): class SearchRecordView(RecordView): def __init__(self, record=None): - super().__init__(_("Select Display Template"), record) + super().__init__(_("Search Records"), _("Select Display Template"), + record) def _get_fields(self): return [i.widget_list[1].get_edit_text() for i in self.cells] @@ -591,7 +597,7 @@ class SearchRecordView(RecordView): class DisplayTemplateRecordView(RecordView): def __init__(self, table, records): - super().__init__(_("Search")) + super().__init__(_("Display Template"), _("Search")) self.records = records self.table = table @@ -652,7 +658,7 @@ class DisplayTemplateRecordView(RecordView): class SortingTemplateRecordView(RecordView): def __init__(self, table, records, selected): - super().__init__(_("Search")) + super().__init__(_("Sorting Template"), _("Search")) self.records = records self.table = table self.selected = selected @@ -868,7 +874,7 @@ class RecordListView(ListView): cur = self._current_item() if cur is None: return - self.session.render_view(DisplayRecordView(cur)) + self.session.render_view(DisplayRecordView(_("Current Record"), cur)) class TableContentsListView(RecordListView): From 9fa8f2246ead361141242e61abc88fa0e0abd990 Mon Sep 17 00:00:00 2001 From: "brian m. carlson" Date: Sun, 15 Nov 2015 16:21:35 +0000 Subject: [PATCH 3/6] main: clean up PEP 8 warnings. Signed-off-by: brian m. carlson --- lib/newfol/main.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/newfol/main.py b/lib/newfol/main.py index 88083ef..70a3bcf 100644 --- a/lib/newfol/main.py +++ b/lib/newfol/main.py @@ -1134,11 +1134,14 @@ def import_into(db, dtbname, dbtype, minfields=0, strict=False, def export_from(db, table, dbtype): vault = filemanip.FileStorage(dbtype, sys.stdout) - f = lambda x: True + + def f(x): + return True if table is None and dbtype == "csv": raise newfol.exception.NewfolError(_("A table is required for csv")) if table is not None: - f = lambda x: x.table == table + def f(x): + x.table == table vault.store(db.records(f)) From 819cf4f8f18dfd5cb34a9335585d83d4568767ce Mon Sep 17 00:00:00 2001 From: "brian m. carlson" Date: Sun, 15 Nov 2015 16:22:41 +0000 Subject: [PATCH 4/6] database: clean up PEP 8 warnings. Turn a lambda into a def. Signed-off-by: brian m. carlson --- lib/newfol/database.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/newfol/database.py b/lib/newfol/database.py index 85d6c1a..1f6d7d1 100644 --- a/lib/newfol/database.py +++ b/lib/newfol/database.py @@ -562,7 +562,9 @@ class Database: def upgrade(self, txntype=None, notify=None, version=None): if notify is None: - notify = lambda x: x + + def notify(x): + x if txntype is None: txntype = list(self._schema.transaction_types()) elif isinstance(txntype, str): From 0d9604b987d933c291573c1ba597fe4b7fc1a4b4 Mon Sep 17 00:00:00 2001 From: "brian m. carlson" Date: Sun, 15 Nov 2015 16:24:14 +0000 Subject: [PATCH 5/6] filemanip: don't break line before binary operator. Signed-off-by: brian m. carlson --- lib/newfol/filemanip.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/newfol/filemanip.py b/lib/newfol/filemanip.py index 2c64cd6..e345c29 100644 --- a/lib/newfol/filemanip.py +++ b/lib/newfol/filemanip.py @@ -249,8 +249,9 @@ class HashHook(Hook): line) except (IOError, FileNotFoundError): if not self._options["forgiving"]: - raise newfol.exception.UpgradeNeededError("dtb is missing" - + " checksum") + raise newfol.exception.UpgradeNeededError("dtb is " + + "missing " + + "checksum") def commit_close(self): if "w" in self._mode: From 87106988803e4f5f4b18616fd477a43febaa3dce Mon Sep 17 00:00:00 2001 From: "brian m. carlson" Date: Sun, 15 Nov 2015 16:44:37 +0000 Subject: [PATCH 6/6] main: fix pyflakes warning. pep8 wants the functions written as defs, not lambdas, but pyflakes complains if we redefine the same function. Change the code to define two functions and use a ternary expression to select the one we want. Signed-off-by: brian m. carlson --- lib/newfol/main.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/newfol/main.py b/lib/newfol/main.py index 70a3bcf..b2156d7 100644 --- a/lib/newfol/main.py +++ b/lib/newfol/main.py @@ -1137,12 +1137,13 @@ def export_from(db, table, dbtype): def f(x): return True + + def g(x): + return x.table == table if table is None and dbtype == "csv": raise newfol.exception.NewfolError(_("A table is required for csv")) - if table is not None: - def f(x): - x.table == table - vault.store(db.records(f)) + func = f if table is None else g + vault.store(db.records(func)) def parse_args(args):