feat: add concept of (non-)default importers for handler
i.e. when telling handler to "import all" which should be included vs. excluded by default?
This commit is contained in:
parent
ae282ab468
commit
d7d0768a9c
7 changed files with 148 additions and 15 deletions
|
|
@ -177,7 +177,7 @@ class ImportCommandHandler(GenericHandler):
|
||||||
# sort out which models to process
|
# sort out which models to process
|
||||||
models = kw.pop("models", None)
|
models = kw.pop("models", None)
|
||||||
if not models:
|
if not models:
|
||||||
models = list(self.import_handler.importers)
|
models = self.import_handler.get_default_importer_keys()
|
||||||
log.debug(
|
log.debug(
|
||||||
"%s %s for models: %s",
|
"%s %s for models: %s",
|
||||||
self.import_handler.actioning,
|
self.import_handler.actioning,
|
||||||
|
|
@ -196,13 +196,31 @@ class ImportCommandHandler(GenericHandler):
|
||||||
|
|
||||||
This is what happens when command line has ``--list-models``.
|
This is what happens when command line has ``--list-models``.
|
||||||
"""
|
"""
|
||||||
sys.stdout.write("\nALL MODELS:\n")
|
all_keys = list(self.import_handler.importers)
|
||||||
|
default_keys = [k for k in all_keys if self.import_handler.is_default(k)]
|
||||||
|
extra_keys = [k for k in all_keys if k not in default_keys]
|
||||||
|
|
||||||
|
sys.stdout.write("\n")
|
||||||
sys.stdout.write("==============================\n")
|
sys.stdout.write("==============================\n")
|
||||||
for key in self.import_handler.importers:
|
sys.stdout.write(" DEFAULT MODELS:\n")
|
||||||
sys.stdout.write(key)
|
|
||||||
sys.stdout.write("\n")
|
|
||||||
sys.stdout.write("==============================\n")
|
sys.stdout.write("==============================\n")
|
||||||
sys.stdout.write(f"for {self.import_handler.get_title()}\n\n")
|
if default_keys:
|
||||||
|
for key in default_keys:
|
||||||
|
sys.stdout.write(f"{key}\n")
|
||||||
|
else:
|
||||||
|
sys.stdout.write("(none)\n")
|
||||||
|
|
||||||
|
sys.stdout.write("==============================\n")
|
||||||
|
sys.stdout.write(" EXTRA MODELS:\n")
|
||||||
|
sys.stdout.write("==============================\n")
|
||||||
|
if extra_keys:
|
||||||
|
for key in extra_keys:
|
||||||
|
sys.stdout.write(f"{key}\n")
|
||||||
|
else:
|
||||||
|
sys.stdout.write("(none)\n")
|
||||||
|
|
||||||
|
sys.stdout.write("==============================\n")
|
||||||
|
sys.stdout.write(f" for {self.import_handler.get_title()}\n\n")
|
||||||
|
|
||||||
|
|
||||||
def import_command_template( # pylint: disable=unused-argument,too-many-arguments,too-many-positional-arguments,too-many-locals
|
def import_command_template( # pylint: disable=unused-argument,too-many-arguments,too-many-positional-arguments,too-many-locals
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,14 @@ class ImportExportWarning(EmailSetting):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class export_to_wutta_from_wutta_warning( # pylint: disable=invalid-name
|
||||||
|
ImportExportWarning
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Diff warning for Wutta → Wutta export.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class import_to_versions_from_wutta_warning( # pylint: disable=invalid-name
|
class import_to_versions_from_wutta_warning( # pylint: disable=invalid-name
|
||||||
ImportExportWarning
|
ImportExportWarning
|
||||||
):
|
):
|
||||||
|
|
|
||||||
|
|
@ -371,7 +371,7 @@ class ImportHandler( # pylint: disable=too-many-public-methods,too-many-instanc
|
||||||
changes = OrderedDict()
|
changes = OrderedDict()
|
||||||
|
|
||||||
if not keys:
|
if not keys:
|
||||||
keys = list(self.importers)
|
keys = self.get_default_importer_keys()
|
||||||
|
|
||||||
success = False
|
success = False
|
||||||
try:
|
try:
|
||||||
|
|
@ -655,6 +655,36 @@ class ImportHandler( # pylint: disable=too-many-public-methods,too-many-instanc
|
||||||
"""
|
"""
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
def is_default(self, key):
|
||||||
|
"""
|
||||||
|
Return a boolean indicating whether the importer corresponding
|
||||||
|
to ``key`` should be considered "default" - i.e. included as
|
||||||
|
part of a typical "import all" job.
|
||||||
|
|
||||||
|
The default logic here returns ``True`` in all cases; subclass can
|
||||||
|
override as needed.
|
||||||
|
|
||||||
|
:param key: Key indicating the importer.
|
||||||
|
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_default_importer_keys(self):
|
||||||
|
"""
|
||||||
|
Return the list of importer keys which should be considered
|
||||||
|
"default" - i.e. which should be included as part of a typical
|
||||||
|
"import all" job.
|
||||||
|
|
||||||
|
This inspects :attr:`importers` and calls :meth:`is_default()`
|
||||||
|
for each, to determine the result.
|
||||||
|
|
||||||
|
:returns: List of importer keys (strings).
|
||||||
|
"""
|
||||||
|
keys = list(self.importers)
|
||||||
|
keys = [k for k in keys if self.is_default(k)]
|
||||||
|
return keys
|
||||||
|
|
||||||
def process_changes(self, changes):
|
def process_changes(self, changes):
|
||||||
"""
|
"""
|
||||||
Run post-processing operations on the given changes, if
|
Run post-processing operations on the given changes, if
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,22 @@ class FromWuttaToWuttaBase(FromWuttaHandler, ToWuttaHandler):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def is_default(self, key):
|
||||||
|
""" """
|
||||||
|
special = [
|
||||||
|
"Setting",
|
||||||
|
"Role",
|
||||||
|
"Permission",
|
||||||
|
"User",
|
||||||
|
"UserRole",
|
||||||
|
"UserAPIToken",
|
||||||
|
"Upgrade",
|
||||||
|
]
|
||||||
|
if key in special:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class FromWuttaToWuttaImport(FromWuttaToWuttaBase):
|
class FromWuttaToWuttaImport(FromWuttaToWuttaBase):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
import inspect
|
import inspect
|
||||||
import sys
|
import sys
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from unittest.mock import patch, Mock
|
from unittest.mock import patch, Mock, call
|
||||||
|
|
||||||
from wuttasync.cli import base as mod
|
from wuttasync.cli import base as mod
|
||||||
from wuttjamaican.testing import DataTestCase
|
from wuttjamaican.testing import DataTestCase
|
||||||
|
|
@ -169,22 +169,60 @@ class TestImportCommandHandler(DataTestCase):
|
||||||
params={},
|
params={},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
# self.assertRaises(FileNotFoundError, handler.run, ctx)
|
|
||||||
handler.run(ctx)
|
handler.run(ctx)
|
||||||
exit_.assert_not_called()
|
exit_.assert_not_called()
|
||||||
|
|
||||||
def test_list_models(self):
|
def test_list_models(self):
|
||||||
|
|
||||||
|
# CSV -> Wutta (all importers are default)
|
||||||
handler = self.make_handler(
|
handler = self.make_handler(
|
||||||
import_handler="wuttasync.importing.csv:FromCsvToWutta"
|
import_handler="wuttasync.importing.csv:FromCsvToWutta"
|
||||||
)
|
)
|
||||||
|
|
||||||
with patch.object(mod, "sys") as sys:
|
with patch.object(mod, "sys") as sys:
|
||||||
handler.list_models({})
|
handler.list_models({})
|
||||||
# just test a few random things we expect to see
|
sys.stdout.write.assert_has_calls(
|
||||||
self.assertTrue(sys.stdout.write.has_call("ALL MODELS:\n"))
|
[
|
||||||
self.assertTrue(sys.stdout.write.has_call("Person"))
|
call("==============================\n"),
|
||||||
self.assertTrue(sys.stdout.write.has_call("User"))
|
call(" EXTRA MODELS:\n"),
|
||||||
self.assertTrue(sys.stdout.write.has_call("Upgrade"))
|
call("==============================\n"),
|
||||||
|
call("(none)\n"),
|
||||||
|
call("==============================\n"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Wutta -> Wutta (only Person importer is default)
|
||||||
|
handler = self.make_handler(
|
||||||
|
import_handler="wuttasync.importing.wutta:FromWuttaToWuttaImport"
|
||||||
|
)
|
||||||
|
with patch.object(mod, "sys") as sys:
|
||||||
|
handler.list_models({})
|
||||||
|
sys.stdout.write.assert_has_calls(
|
||||||
|
[
|
||||||
|
call("==============================\n"),
|
||||||
|
call(" DEFAULT MODELS:\n"),
|
||||||
|
call("==============================\n"),
|
||||||
|
call("Person\n"),
|
||||||
|
call("==============================\n"),
|
||||||
|
call(" EXTRA MODELS:\n"),
|
||||||
|
call("==============================\n"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# again, but pretend there are no default importers
|
||||||
|
with patch.object(handler.import_handler, "is_default", return_value=False):
|
||||||
|
with patch.object(mod, "sys") as sys:
|
||||||
|
handler.list_models({})
|
||||||
|
sys.stdout.write.assert_has_calls(
|
||||||
|
[
|
||||||
|
call("==============================\n"),
|
||||||
|
call(" DEFAULT MODELS:\n"),
|
||||||
|
call("==============================\n"),
|
||||||
|
call("(none)\n"),
|
||||||
|
call("==============================\n"),
|
||||||
|
call(" EXTRA MODELS:\n"),
|
||||||
|
call("==============================\n"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestImporterCommand(TestCase):
|
class TestImporterCommand(TestCase):
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ from uuid import UUID
|
||||||
from wuttjamaican.testing import DataTestCase
|
from wuttjamaican.testing import DataTestCase
|
||||||
|
|
||||||
from wuttasync.importing import handlers as mod, Importer, ToSqlalchemy
|
from wuttasync.importing import handlers as mod, Importer, ToSqlalchemy
|
||||||
|
from wuttasync.importing.wutta import FromWuttaToWuttaImport
|
||||||
|
|
||||||
|
|
||||||
class FromFooToBar(mod.ImportHandler):
|
class FromFooToBar(mod.ImportHandler):
|
||||||
|
|
@ -253,6 +254,25 @@ class TestImportHandler(DataTestCase):
|
||||||
KeyError, handler.get_importer, "BunchOfNonsense", model_class=model.Setting
|
KeyError, handler.get_importer, "BunchOfNonsense", model_class=model.Setting
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_is_default(self):
|
||||||
|
handler = self.make_handler()
|
||||||
|
# nb. anything is considered default, by default
|
||||||
|
self.assertTrue(handler.is_default("there_is_no_way_this_is_valid"))
|
||||||
|
|
||||||
|
def test_get_default_importer_keys(self):
|
||||||
|
|
||||||
|
# use handler which already has some non/default keys
|
||||||
|
handler = FromWuttaToWuttaImport(self.config)
|
||||||
|
|
||||||
|
# it supports many importers
|
||||||
|
self.assertIn("Person", handler.importers)
|
||||||
|
self.assertIn("User", handler.importers)
|
||||||
|
self.assertIn("Setting", handler.importers)
|
||||||
|
|
||||||
|
# but only Person is default
|
||||||
|
keys = handler.get_default_importer_keys()
|
||||||
|
self.assertEqual(keys, ["Person"])
|
||||||
|
|
||||||
def test_get_warnings_email_key(self):
|
def test_get_warnings_email_key(self):
|
||||||
handler = FromFooToBar(self.config)
|
handler = FromFooToBar(self.config)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,9 @@ class TestEmailSettings(ImportExportWarningTestCase):
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
def test_export_to_wutta_from_wutta_warning(self):
|
||||||
|
self.do_test_preview("export_to_wutta_from_wutta_warning")
|
||||||
|
|
||||||
def test_import_to_versions_from_wutta_warning(self):
|
def test_import_to_versions_from_wutta_warning(self):
|
||||||
self.do_test_preview("import_to_versions_from_wutta_warning")
|
self.do_test_preview("import_to_versions_from_wutta_warning")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue