mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 08:39:17 +01:00
Leave a single source of truth for importer setup
This commit is contained in:
parent
8065ff0461
commit
f042f5ad32
13 changed files with 212 additions and 251 deletions
|
|
@ -53,6 +53,7 @@ import beets
|
|||
import beets.plugins
|
||||
from beets import autotag, config, importer, logging, util
|
||||
from beets.autotag.hooks import AlbumInfo, TrackInfo
|
||||
from beets.importer import ImportSession
|
||||
from beets.library import Album, Item, Library
|
||||
from beets.test import _common
|
||||
from beets.ui.commands import TerminalImportSession
|
||||
|
|
@ -498,13 +499,26 @@ class PluginTestCase(PluginMixin, BeetsTestCase):
|
|||
pass
|
||||
|
||||
|
||||
class ImportHelper:
|
||||
class ImportHelper(TestHelper):
|
||||
"""Provides tools to setup a library, a directory containing files that are
|
||||
to be imported and an import session. The class also provides stubs for the
|
||||
autotagging library and several assertions for the library.
|
||||
"""
|
||||
|
||||
importer: importer.ImportSession
|
||||
resource_path = syspath(os.path.join(_common.RSRC, b"full.mp3"))
|
||||
default_import_config = {
|
||||
"autotag": True,
|
||||
"copy": True,
|
||||
"hardlink": False,
|
||||
"link": False,
|
||||
"move": False,
|
||||
"resume": False,
|
||||
"singletons": False,
|
||||
"timid": True,
|
||||
}
|
||||
|
||||
lib: Library
|
||||
importer: ImportSession
|
||||
|
||||
@cached_property
|
||||
def import_dir(self):
|
||||
|
|
@ -512,130 +526,87 @@ class ImportHelper:
|
|||
os.makedirs(syspath(import_dir), exist_ok=True)
|
||||
return import_dir
|
||||
|
||||
def setup_beets(self):
|
||||
super().setup_beets()
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.import_media = []
|
||||
self.lib.path_formats = [
|
||||
("default", os.path.join("$artist", "$album", "$title")),
|
||||
("singleton:true", os.path.join("singletons", "$title")),
|
||||
("comp:true", os.path.join("compilations", "$album", "$title")),
|
||||
]
|
||||
|
||||
def prepare_album_for_import(self, count=3):
|
||||
"""Creates a directory with media files to import.
|
||||
Sets ``self.import_dir`` to the path of the directory. Also sets
|
||||
``self.import_media`` to a list :class:`MediaFile` for all the files in
|
||||
the directory.
|
||||
def prepare_track_for_import(
|
||||
self,
|
||||
track_id: int,
|
||||
album_path: bytes,
|
||||
album_id: int | None = None,
|
||||
) -> MediaFile:
|
||||
filename = bytestring_path(f"track_{track_id}.mp3")
|
||||
medium_path = os.path.join(album_path, filename)
|
||||
shutil.copy(self.resource_path, syspath(medium_path))
|
||||
medium = MediaFile(medium_path)
|
||||
medium.update(
|
||||
{
|
||||
"album": "Tag Album" + (f" {album_id}" if album_id else ""),
|
||||
"albumartist": None,
|
||||
"mb_albumid": None,
|
||||
"comp": None,
|
||||
"artist": "Tag Artist",
|
||||
"title": f"Tag Track {track_id}",
|
||||
"track": track_id,
|
||||
"mb_trackid": None,
|
||||
}
|
||||
)
|
||||
medium.save()
|
||||
return medium
|
||||
|
||||
def prepare_album_for_import(
|
||||
self, item_count: int, album_id: int | None = None
|
||||
) -> None:
|
||||
"""Create an album directory with media files to import.
|
||||
|
||||
The directory has following layout
|
||||
the_album/
|
||||
album/
|
||||
track_1.mp3
|
||||
track_2.mp3
|
||||
track_3.mp3
|
||||
|
||||
:param count: Number of files to create
|
||||
"""
|
||||
album_path = os.path.join(self.import_dir, b"the_album")
|
||||
album_path = os.path.join(
|
||||
self.import_dir,
|
||||
bytestring_path(f"album_{album_id}" if album_id else "album"),
|
||||
)
|
||||
os.makedirs(syspath(album_path), exist_ok=True)
|
||||
|
||||
resource_path = os.path.join(_common.RSRC, b"full.mp3")
|
||||
mediums = [
|
||||
self.prepare_track_for_import(tid, album_path, album_id=album_id)
|
||||
for tid in range(1, item_count + 1)
|
||||
]
|
||||
self.import_media.extend(mediums)
|
||||
|
||||
album = bytestring_path("album")
|
||||
album_path = os.path.join(self.import_dir, album)
|
||||
os.makedirs(syspath(album_path), exist_ok=True)
|
||||
def prepare_albums_for_import(self, count: int = 1) -> None:
|
||||
album_dirs = Path(os.fsdecode(self.import_dir)).glob("album_*")
|
||||
base_idx = int(str(max(album_dirs, default="0")).split("_")[-1]) + 1
|
||||
|
||||
self.import_media = []
|
||||
for track_id in range(1, count + 1):
|
||||
medium_path = os.path.join(
|
||||
album_path, bytestring_path(f"track_{track_id}.mp3")
|
||||
)
|
||||
shutil.copy(syspath(resource_path), syspath(medium_path))
|
||||
medium = MediaFile(medium_path)
|
||||
medium.update(
|
||||
{
|
||||
"album": "Tag Album",
|
||||
"albumartist": None,
|
||||
"mb_albumid": None,
|
||||
"comp": None,
|
||||
"artist": "Tag Artist",
|
||||
"title": f"Tag Track {track_id}",
|
||||
"track": track_id,
|
||||
"mb_trackid": None,
|
||||
}
|
||||
)
|
||||
medium.save()
|
||||
self.import_media.append(medium)
|
||||
for album_id in range(base_idx, count + base_idx):
|
||||
self.prepare_album_for_import(1, album_id=album_id)
|
||||
|
||||
def _get_import_session(self, import_dir: str) -> None:
|
||||
self.importer = ImportSessionFixture(
|
||||
def _get_import_session(self, import_dir: str) -> ImportSession:
|
||||
return ImportSessionFixture(
|
||||
self.lib,
|
||||
loghandler=None,
|
||||
query=None,
|
||||
paths=[import_dir],
|
||||
)
|
||||
|
||||
def _setup_import_session(
|
||||
self,
|
||||
import_dir=None,
|
||||
singletons=False,
|
||||
move=False,
|
||||
autotag=True,
|
||||
):
|
||||
config["import"]["copy"] = True
|
||||
config["import"]["delete"] = False
|
||||
config["import"]["timid"] = True
|
||||
config["threaded"] = False
|
||||
config["import"]["singletons"] = singletons
|
||||
config["import"]["move"] = move
|
||||
config["import"]["autotag"] = autotag
|
||||
config["import"]["resume"] = False
|
||||
config["import"]["link"] = False
|
||||
config["import"]["hardlink"] = False
|
||||
def setup_importer(
|
||||
self, import_dir: str | None = None, **kwargs
|
||||
) -> ImportSession:
|
||||
config["import"].set_args({**self.default_import_config, **kwargs})
|
||||
self.importer = self._get_import_session(import_dir or self.import_dir)
|
||||
return self.importer
|
||||
|
||||
self._get_import_session(import_dir or self.import_dir)
|
||||
|
||||
def create_importer(self, item_count=1, album_count=1):
|
||||
"""Create files to import and return corresponding session.
|
||||
|
||||
Copies the specified number of files to a subdirectory of
|
||||
`self.temp_dir` and creates a `ImportSessionFixture` for this path.
|
||||
"""
|
||||
resource_path = os.path.join(_common.RSRC, b"full.mp3")
|
||||
|
||||
album_dirs = Path(os.fsdecode(self.import_dir)).glob("album_*")
|
||||
base_idx = int(str(max(album_dirs, default="0")).split("_")[-1]) + 1
|
||||
|
||||
for album_id in range(base_idx, album_count + base_idx):
|
||||
album = bytestring_path(f"album_{album_id}")
|
||||
album_path = os.path.join(self.import_dir, album)
|
||||
os.makedirs(syspath(album_path), exist_ok=True)
|
||||
|
||||
for track_id in range(1, item_count + 1):
|
||||
medium_path = os.path.join(
|
||||
album_path, bytestring_path(f"track_{track_id}.mp3")
|
||||
)
|
||||
shutil.copy(syspath(resource_path), syspath(medium_path))
|
||||
medium = MediaFile(medium_path)
|
||||
medium.update(
|
||||
{
|
||||
"album": f"Tag Album {album_id}",
|
||||
"albumartist": None,
|
||||
"mb_albumid": None,
|
||||
"comp": None,
|
||||
"artist": "Tag Artist",
|
||||
"title": f"Tag Track {track_id}",
|
||||
"track": track_id,
|
||||
"mb_trackid": None,
|
||||
}
|
||||
)
|
||||
medium.save()
|
||||
|
||||
config["import"]["quiet"] = True
|
||||
config["import"]["autotag"] = False
|
||||
config["import"]["resume"] = False
|
||||
|
||||
return ImportSessionFixture(
|
||||
self.lib, loghandler=None, query=None, paths=[self.import_dir]
|
||||
)
|
||||
def setup_singleton_importer(self, **kwargs) -> ImportSession:
|
||||
return self.setup_importer(singletons=True, **kwargs)
|
||||
|
||||
def assert_file_in_lib(self, *segments):
|
||||
"""Join the ``segments`` and assert that this path exists in the
|
||||
|
|
@ -657,7 +628,7 @@ class ImportTestCase(ImportHelper, BeetsTestCase):
|
|||
pass
|
||||
|
||||
|
||||
class ImportSessionFixture(importer.ImportSession):
|
||||
class ImportSessionFixture(ImportSession):
|
||||
"""ImportSession that can be controlled programaticaly.
|
||||
|
||||
>>> lib = Library(':memory:')
|
||||
|
|
@ -771,9 +742,11 @@ class TerminalImportSessionFixture(TerminalImportSession):
|
|||
class TerminalImportMixin(ImportHelper):
|
||||
"""Provides_a terminal importer for the import session."""
|
||||
|
||||
def _get_import_session(self, import_dir: str) -> None:
|
||||
io: _common.DummyIO
|
||||
|
||||
def _get_import_session(self, import_dir: str) -> importer.ImportSession:
|
||||
self.io.install()
|
||||
self.importer = TerminalImportSessionFixture(
|
||||
return TerminalImportSessionFixture(
|
||||
self.lib,
|
||||
loghandler=None,
|
||||
query=None,
|
||||
|
|
|
|||
|
|
@ -434,7 +434,7 @@ def displayable_path(
|
|||
return path.decode("utf-8", "ignore")
|
||||
|
||||
|
||||
def syspath(path: Bytes_or_String, prefix: bool = True) -> Bytes_or_String:
|
||||
def syspath(path: Bytes_or_String, prefix: bool = True) -> str:
|
||||
"""Convert a path for use by the operating system. In particular,
|
||||
paths on Windows must receive a magic prefix and must be converted
|
||||
to Unicode before they are sent to the OS. To disable the magic
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ class ConvertTestCase(ConvertMixin, PluginTestCase):
|
|||
class ImportConvertTest(ImportHelper, ConvertTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.importer = self.create_importer()
|
||||
self.prepare_album_for_import(1)
|
||||
self.importer = self.setup_importer(autotag=False)
|
||||
|
||||
self.config["convert"] = {
|
||||
"dest": os.path.join(self.temp_dir, b"convert"),
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
# included in all copies or substantial portions of the Software.
|
||||
|
||||
import codecs
|
||||
from typing import ClassVar
|
||||
from unittest.mock import patch
|
||||
|
||||
from beets.dbcore.query import TrueQuery
|
||||
|
|
@ -329,17 +328,14 @@ class EditDuringImporterTestCase(
|
|||
"""TODO"""
|
||||
|
||||
IGNORED = ["added", "album_id", "id", "mtime", "path"]
|
||||
singletons: ClassVar[bool]
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
# Create some mediafiles, and store them for comparison.
|
||||
self.prepare_album_for_import()
|
||||
self._setup_import_session(singletons=self.singletons)
|
||||
self.prepare_album_for_import(1)
|
||||
self.items_orig = [Item.from_path(f.path) for f in self.import_media]
|
||||
self.matcher = AutotagStub().install()
|
||||
self.matcher.matching = AutotagStub.GOOD
|
||||
self.config["import"]["timid"] = True
|
||||
|
||||
def tearDown(self):
|
||||
EditPlugin.listeners = None
|
||||
|
|
@ -349,7 +345,9 @@ class EditDuringImporterTestCase(
|
|||
|
||||
@_common.slow_test()
|
||||
class EditDuringImporterNonSingletonTest(EditDuringImporterTestCase):
|
||||
singletons = False
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.importer = self.setup_importer()
|
||||
|
||||
def test_edit_apply_asis(self):
|
||||
"""Edit the album field for all items in the library, apply changes,
|
||||
|
|
@ -497,7 +495,9 @@ class EditDuringImporterNonSingletonTest(EditDuringImporterTestCase):
|
|||
|
||||
@_common.slow_test()
|
||||
class EditDuringImporterSingletonTest(EditDuringImporterTestCase):
|
||||
singletons = True
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.importer = self.setup_singleton_importer()
|
||||
|
||||
def test_edit_apply_asis_singleton(self):
|
||||
"""Edit the album field for all items in the library, apply changes,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
import os
|
||||
import shutil
|
||||
from typing import ClassVar
|
||||
|
||||
from mediafile import MediaFile
|
||||
|
||||
|
|
@ -30,17 +29,9 @@ from beetsplug.filefilter import FileFilterPlugin
|
|||
|
||||
|
||||
class FileFilterPluginMixin(ImportTestCase):
|
||||
singletons: ClassVar[bool]
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.__create_import_dir(2)
|
||||
self._setup_import_session()
|
||||
config["import"]["pretend"] = True
|
||||
|
||||
import_files = [self.import_dir]
|
||||
self._setup_import_session(singletons=self.singletons)
|
||||
self.importer.paths = import_files
|
||||
|
||||
def tearDown(self):
|
||||
self.unload_plugins()
|
||||
|
|
@ -112,7 +103,9 @@ class FileFilterPluginMixin(ImportTestCase):
|
|||
|
||||
|
||||
class FileFilterPluginNonSingletonTest(FileFilterPluginMixin):
|
||||
singletons = False
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.importer = self.setup_importer(pretend=True)
|
||||
|
||||
def test_import_default(self):
|
||||
"""The default configuration should import everything."""
|
||||
|
|
@ -189,7 +182,9 @@ class FileFilterPluginNonSingletonTest(FileFilterPluginMixin):
|
|||
|
||||
|
||||
class FileFilterPluginSingletonTest(FileFilterPluginMixin):
|
||||
singletons = True
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.importer = self.setup_singleton_importer(pretend=True)
|
||||
|
||||
def test_import_global(self):
|
||||
config["filefilter"]["path"] = ".*track_1.*\\.mp3"
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class ImportAddedTest(PluginMixin, ImportTestCase):
|
|||
)
|
||||
self.matcher = AutotagStub().install()
|
||||
self.matcher.macthin = AutotagStub.GOOD
|
||||
self._setup_import_session()
|
||||
self.importer = self.setup_importer()
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
|
||||
def tearDown(self):
|
||||
|
|
@ -113,7 +113,7 @@ class ImportAddedTest(PluginMixin, ImportTestCase):
|
|||
# Newer Item path mtimes as if Beets had modified them
|
||||
modify_mtimes(items_added_before.keys(), offset=10000)
|
||||
# Reimport
|
||||
self._setup_import_session(import_dir=album.path)
|
||||
self.setup_importer(import_dir=self.libdir)
|
||||
self.importer.run()
|
||||
# Verify the reimported items
|
||||
album = self.lib.albums().get()
|
||||
|
|
@ -154,8 +154,7 @@ class ImportAddedTest(PluginMixin, ImportTestCase):
|
|||
# Newer Item path mtimes as if Beets had modified them
|
||||
modify_mtimes(items_added_before.keys(), offset=10000)
|
||||
# Reimport
|
||||
import_dir = os.path.dirname(list(items_added_before.keys())[0])
|
||||
self._setup_import_session(import_dir=import_dir, singletons=True)
|
||||
self.setup_importer(import_dir=self.libdir, singletons=True)
|
||||
self.importer.run()
|
||||
# Verify the reimported items
|
||||
items_added_after = {item.path: item.added for item in self.lib.items()}
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ class KeyFinderTest(PluginMixin, ImportTestCase):
|
|||
|
||||
def test_add_key_on_import(self, command_output):
|
||||
command_output.return_value = util.CommandOutput(b"dbm", b"")
|
||||
importer = self.create_importer()
|
||||
importer.run()
|
||||
self.prepare_album_for_import(1)
|
||||
self.setup_importer(autotag=False).run()
|
||||
|
||||
item = self.lib.items().get()
|
||||
self.assertEqual(item["initial_key"], "C#m")
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class MBSubmitPluginTest(PluginMixin, TerminalImportMixin, ImportTestCase):
|
|||
def setUp(self):
|
||||
super().setUp()
|
||||
self.prepare_album_for_import(2)
|
||||
self._setup_import_session()
|
||||
self.setup_importer()
|
||||
self.matcher = AutotagStub().install()
|
||||
|
||||
def tearDown(self):
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ class PermissionsPluginTest(PluginMixin, ImportTestCase):
|
|||
super().setUp()
|
||||
|
||||
self.config["permissions"] = {"file": "777", "dir": "777"}
|
||||
self.prepare_album_for_import(1)
|
||||
|
||||
def test_permissions_on_album_imported(self):
|
||||
self.do_thing(True)
|
||||
|
|
@ -44,10 +45,10 @@ class PermissionsPluginTest(PluginMixin, ImportTestCase):
|
|||
& 0o777
|
||||
)
|
||||
|
||||
self.importer = self.create_importer()
|
||||
self.importer = self.setup_importer(autotag=False)
|
||||
typs = ["file", "dir"]
|
||||
|
||||
track_file = (b"album_1", b"track_1.mp3")
|
||||
track_file = (b"album", b"track_1.mp3")
|
||||
self.exp_perms = {
|
||||
True: {
|
||||
k: convert_perm(self.config["permissions"][k].get())
|
||||
|
|
@ -93,8 +94,7 @@ class PermissionsPluginTest(PluginMixin, ImportTestCase):
|
|||
def do_set_art(self, expect_success):
|
||||
if platform.system() == "Windows":
|
||||
self.skipTest("permissions not available on Windows")
|
||||
self.importer = self.create_importer()
|
||||
self.importer.run()
|
||||
self.setup_importer(autotag=False).run()
|
||||
album = self.lib.albums().get()
|
||||
artpath = os.path.join(self.temp_dir, b"cover.jpg")
|
||||
touch(artpath)
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ class ReplayGainTestCase(ImportTestCase):
|
|||
except Exception:
|
||||
self.tearDown()
|
||||
|
||||
self.importer = self.create_importer()
|
||||
self.prepare_album_for_import(1)
|
||||
self.importer = self.setup_importer(autotag=False)
|
||||
|
||||
def tearDown(self):
|
||||
self.unload_plugins()
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ class ScrubbedImportTest(PluginMixin, ImportTestCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.prepare_album_for_import(2)
|
||||
self._setup_import_session(autotag=False)
|
||||
self.prepare_album_for_import(1)
|
||||
self.setup_importer(autotag=False)
|
||||
|
||||
def test_tags_not_scrubbed(self):
|
||||
config["plugins"] = ["scrub"]
|
||||
|
|
@ -103,8 +103,8 @@ class NonAutotaggedImportTest(ImportTestCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.prepare_album_for_import(2)
|
||||
self._setup_import_session(autotag=False)
|
||||
self.prepare_album_for_import(1)
|
||||
self.setup_importer(autotag=False)
|
||||
|
||||
def test_album_created_with_track_artist(self):
|
||||
self.importer.run()
|
||||
|
|
@ -285,7 +285,7 @@ class RmTempTest(ImportTestCase):
|
|||
archive_task = importer.ArchiveImportTask(zip_path)
|
||||
archive_task.extract()
|
||||
tmp_path = archive_task.toppath
|
||||
self._setup_import_session(autotag=False, import_dir=tmp_path)
|
||||
self.setup_importer(autotag=False, import_dir=tmp_path)
|
||||
self.assertExists(tmp_path)
|
||||
archive_task.finalize(self)
|
||||
self.assertNotExists(tmp_path)
|
||||
|
|
@ -297,7 +297,7 @@ class ImportZipTest(ImportTestCase):
|
|||
self.assertEqual(len(self.lib.items()), 0)
|
||||
self.assertEqual(len(self.lib.albums()), 0)
|
||||
|
||||
self._setup_import_session(autotag=False, import_dir=zip_path)
|
||||
self.setup_importer(autotag=False, import_dir=zip_path)
|
||||
self.importer.run()
|
||||
self.assertEqual(len(self.lib.items()), 1)
|
||||
self.assertEqual(len(self.lib.albums()), 1)
|
||||
|
|
@ -341,8 +341,7 @@ class ImportSingletonTest(ImportTestCase):
|
|||
def setUp(self):
|
||||
super().setUp()
|
||||
self.prepare_album_for_import(1)
|
||||
self._setup_import_session()
|
||||
config["import"]["singletons"] = True
|
||||
self.setup_importer(singletons=True)
|
||||
self.matcher = AutotagStub().install()
|
||||
|
||||
def tearDown(self):
|
||||
|
|
@ -410,7 +409,7 @@ class ImportSingletonTest(ImportTestCase):
|
|||
os.path.join(self.import_dir, b"album"),
|
||||
single_path,
|
||||
]
|
||||
self._setup_import_session(singletons=False)
|
||||
self.setup_importer()
|
||||
self.importer.paths = import_files
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
|
|
@ -462,7 +461,7 @@ class ImportTest(ImportTestCase):
|
|||
def setUp(self):
|
||||
super().setUp()
|
||||
self.prepare_album_for_import(1)
|
||||
self._setup_import_session()
|
||||
self.setup_importer()
|
||||
self.matcher = AutotagStub().install()
|
||||
self.matcher.macthin = AutotagStub.GOOD
|
||||
|
||||
|
|
@ -581,7 +580,7 @@ class ImportTest(ImportTestCase):
|
|||
def test_empty_directory_warning(self):
|
||||
import_dir = os.path.join(self.temp_dir, b"empty")
|
||||
self.touch(b"non-audio", dir=import_dir)
|
||||
self._setup_import_session(import_dir=import_dir)
|
||||
self.setup_importer(import_dir=import_dir)
|
||||
with capture_log() as logs:
|
||||
self.importer.run()
|
||||
|
||||
|
|
@ -591,7 +590,7 @@ class ImportTest(ImportTestCase):
|
|||
def test_empty_directory_singleton_warning(self):
|
||||
import_dir = os.path.join(self.temp_dir, b"empty")
|
||||
self.touch(b"non-audio", dir=import_dir)
|
||||
self._setup_import_session(import_dir=import_dir, singletons=True)
|
||||
self.setup_importer(import_dir=import_dir, singletons=True)
|
||||
with capture_log() as logs:
|
||||
self.importer.run()
|
||||
|
||||
|
|
@ -672,7 +671,7 @@ class ImportTracksTest(ImportTestCase):
|
|||
def setUp(self):
|
||||
super().setUp()
|
||||
self.prepare_album_for_import(1)
|
||||
self._setup_import_session()
|
||||
self.setup_importer()
|
||||
self.matcher = AutotagStub().install()
|
||||
|
||||
def tearDown(self):
|
||||
|
|
@ -706,7 +705,7 @@ class ImportCompilationTest(ImportTestCase):
|
|||
def setUp(self):
|
||||
super().setUp()
|
||||
self.prepare_album_for_import(3)
|
||||
self._setup_import_session()
|
||||
self.setup_importer()
|
||||
self.matcher = AutotagStub().install()
|
||||
|
||||
def tearDown(self):
|
||||
|
|
@ -827,55 +826,52 @@ class ImportExistingTest(ImportTestCase):
|
|||
self.prepare_album_for_import(1)
|
||||
self.matcher = AutotagStub().install()
|
||||
|
||||
self._setup_import_session()
|
||||
self.setup_importer = self.importer
|
||||
self.setup_importer.default_choice = importer.action.APPLY
|
||||
|
||||
self._setup_import_session(import_dir=self.libdir)
|
||||
self.reimporter = self.setup_importer(import_dir=self.libdir)
|
||||
self.importer = self.setup_importer()
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
self.matcher.restore()
|
||||
|
||||
def test_does_not_duplicate_item(self):
|
||||
self.setup_importer.run()
|
||||
self.importer.run()
|
||||
self.assertEqual(len(self.lib.items()), 1)
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.run()
|
||||
self.reimporter.add_choice(importer.action.APPLY)
|
||||
self.reimporter.run()
|
||||
self.assertEqual(len(self.lib.items()), 1)
|
||||
|
||||
def test_does_not_duplicate_album(self):
|
||||
self.setup_importer.run()
|
||||
self.assertEqual(len(self.lib.albums()), 1)
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.run()
|
||||
self.assertEqual(len(self.lib.albums()), 1)
|
||||
|
||||
def test_does_not_duplicate_singleton_track(self):
|
||||
self.setup_importer.add_choice(importer.action.TRACKS)
|
||||
self.setup_importer.add_choice(importer.action.APPLY)
|
||||
self.setup_importer.run()
|
||||
self.assertEqual(len(self.lib.items()), 1)
|
||||
self.reimporter.add_choice(importer.action.APPLY)
|
||||
self.reimporter.run()
|
||||
self.assertEqual(len(self.lib.albums()), 1)
|
||||
|
||||
def test_does_not_duplicate_singleton_track(self):
|
||||
self.importer.add_choice(importer.action.TRACKS)
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.run()
|
||||
self.assertEqual(len(self.lib.items()), 1)
|
||||
|
||||
self.reimporter.add_choice(importer.action.TRACKS)
|
||||
self.reimporter.add_choice(importer.action.APPLY)
|
||||
self.reimporter.run()
|
||||
self.assertEqual(len(self.lib.items()), 1)
|
||||
|
||||
def test_asis_updates_metadata(self):
|
||||
self.setup_importer.run()
|
||||
self.importer.run()
|
||||
medium = MediaFile(self.lib.items().get().path)
|
||||
medium.title = "New Title"
|
||||
medium.save()
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.run()
|
||||
self.reimporter.add_choice(importer.action.ASIS)
|
||||
self.reimporter.run()
|
||||
self.assertEqual(self.lib.items().get().title, "New Title")
|
||||
|
||||
def test_asis_updated_moves_file(self):
|
||||
self.setup_importer.run()
|
||||
self.importer.run()
|
||||
medium = MediaFile(self.lib.items().get().path)
|
||||
medium.title = "New Title"
|
||||
medium.save()
|
||||
|
|
@ -885,15 +881,15 @@ class ImportExistingTest(ImportTestCase):
|
|||
)
|
||||
self.assert_file_in_lib(old_path)
|
||||
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.run()
|
||||
self.reimporter.add_choice(importer.action.ASIS)
|
||||
self.reimporter.run()
|
||||
self.assert_file_in_lib(
|
||||
b"Applied Artist", b"Applied Album", b"New Title.mp3"
|
||||
)
|
||||
self.assert_file_not_in_lib(old_path)
|
||||
|
||||
def test_asis_updated_without_copy_does_not_move_file(self):
|
||||
self.setup_importer.run()
|
||||
self.importer.run()
|
||||
medium = MediaFile(self.lib.items().get().path)
|
||||
medium.title = "New Title"
|
||||
medium.save()
|
||||
|
|
@ -904,8 +900,8 @@ class ImportExistingTest(ImportTestCase):
|
|||
self.assert_file_in_lib(old_path)
|
||||
|
||||
config["import"]["copy"] = False
|
||||
self.importer.add_choice(importer.action.ASIS)
|
||||
self.importer.run()
|
||||
self.reimporter.add_choice(importer.action.ASIS)
|
||||
self.reimporter.run()
|
||||
self.assert_file_not_in_lib(
|
||||
b"Applied Artist", b"Applied Album", b"New Title.mp3"
|
||||
)
|
||||
|
|
@ -913,15 +909,14 @@ class ImportExistingTest(ImportTestCase):
|
|||
|
||||
def test_outside_file_is_copied(self):
|
||||
config["import"]["copy"] = False
|
||||
self.setup_importer.run()
|
||||
self.importer.run()
|
||||
self.assert_equal_path(
|
||||
self.lib.items().get().path, self.import_media[0].path
|
||||
)
|
||||
|
||||
config["import"]["copy"] = True
|
||||
self._setup_import_session()
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.run()
|
||||
self.reimporter = self.setup_importer()
|
||||
self.reimporter.add_choice(importer.action.APPLY)
|
||||
self.reimporter.run()
|
||||
new_path = os.path.join(
|
||||
b"Applied Artist", b"Applied Album", b"Applied Track 1.mp3"
|
||||
)
|
||||
|
|
@ -933,14 +928,14 @@ class ImportExistingTest(ImportTestCase):
|
|||
|
||||
def test_outside_file_is_moved(self):
|
||||
config["import"]["copy"] = False
|
||||
self.setup_importer.run()
|
||||
self.importer.run()
|
||||
self.assert_equal_path(
|
||||
self.lib.items().get().path, self.import_media[0].path
|
||||
)
|
||||
|
||||
self._setup_import_session(move=True)
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.run()
|
||||
self.reimporter = self.setup_importer(move=True)
|
||||
self.reimporter.add_choice(importer.action.APPLY)
|
||||
self.reimporter.run()
|
||||
self.assertNotExists(self.import_media[0].path)
|
||||
|
||||
|
||||
|
|
@ -950,7 +945,7 @@ class GroupAlbumsImportTest(ImportTestCase):
|
|||
self.prepare_album_for_import(3)
|
||||
self.matcher = AutotagStub().install()
|
||||
self.matcher.matching = AutotagStub.NONE
|
||||
self._setup_import_session()
|
||||
self.setup_importer()
|
||||
|
||||
# Split tracks into two albums and use both as-is
|
||||
self.importer.add_choice(importer.action.ALBUMS)
|
||||
|
|
@ -1020,7 +1015,7 @@ class ChooseCandidateTest(ImportTestCase):
|
|||
def setUp(self):
|
||||
super().setUp()
|
||||
self.prepare_album_for_import(1)
|
||||
self._setup_import_session()
|
||||
self.setup_importer()
|
||||
self.matcher = AutotagStub().install()
|
||||
self.matcher.matching = AutotagStub.BAD
|
||||
|
||||
|
|
@ -1163,9 +1158,10 @@ class ImportDuplicateAlbumTest(ImportTestCase):
|
|||
self.add_album_fixture(albumartist="artist", album="album")
|
||||
|
||||
# Create import session
|
||||
self.importer = self.create_importer()
|
||||
config["import"]["autotag"] = True
|
||||
config["import"]["duplicate_keys"]["album"] = "albumartist album"
|
||||
self.prepare_album_for_import(1)
|
||||
self.importer = self.setup_importer(
|
||||
duplicate_keys={"album": "albumartist album"}
|
||||
)
|
||||
|
||||
def test_remove_duplicate_album(self):
|
||||
item = self.lib.items().get()
|
||||
|
|
@ -1190,7 +1186,7 @@ class ImportDuplicateAlbumTest(ImportTestCase):
|
|||
# Imported item has the same artist and album as the one in the
|
||||
# library.
|
||||
import_file = os.path.join(
|
||||
self.importer.paths[0], b"album_1", b"track_1.mp3"
|
||||
self.importer.paths[0], b"album", b"track_1.mp3"
|
||||
)
|
||||
import_file = MediaFile(import_file)
|
||||
import_file.artist = item["artist"]
|
||||
|
|
@ -1238,7 +1234,7 @@ class ImportDuplicateAlbumTest(ImportTestCase):
|
|||
|
||||
item = self.lib.items().get()
|
||||
import_file = MediaFile(
|
||||
os.path.join(self.importer.paths[0], b"album_1", b"track_1.mp3")
|
||||
os.path.join(self.importer.paths[0], b"album", b"track_1.mp3")
|
||||
)
|
||||
import_file.artist = item["artist"]
|
||||
import_file.albumartist = item["artist"]
|
||||
|
|
@ -1284,10 +1280,10 @@ class ImportDuplicateSingletonTest(ImportTestCase):
|
|||
)
|
||||
|
||||
# Import session
|
||||
self.importer = self.create_importer()
|
||||
config["import"]["autotag"] = True
|
||||
config["import"]["singletons"] = True
|
||||
config["import"]["duplicate_keys"]["item"] = "artist title"
|
||||
self.prepare_album_for_import(1)
|
||||
self.importer = self.setup_importer(
|
||||
duplicate_keys={"album": "artist title"}, singletons=True
|
||||
)
|
||||
|
||||
def test_remove_duplicate(self):
|
||||
item = self.lib.items().get()
|
||||
|
|
@ -1363,8 +1359,8 @@ class TagLogTest(BeetsTestCase):
|
|||
class ResumeImportTest(ImportTestCase):
|
||||
@patch("beets.plugins.send")
|
||||
def test_resume_album(self, plugins_send):
|
||||
self.importer = self.create_importer(album_count=2)
|
||||
self.config["import"]["resume"] = True
|
||||
self.prepare_albums_for_import(2)
|
||||
self.importer = self.setup_importer(autotag=False, resume=True)
|
||||
|
||||
# Aborts import after one album. This also ensures that we skip
|
||||
# the first album in the second try.
|
||||
|
|
@ -1384,9 +1380,10 @@ class ResumeImportTest(ImportTestCase):
|
|||
|
||||
@patch("beets.plugins.send")
|
||||
def test_resume_singleton(self, plugins_send):
|
||||
self.importer = self.create_importer(item_count=2)
|
||||
self.config["import"]["resume"] = True
|
||||
self.config["import"]["singletons"] = True
|
||||
self.prepare_album_for_import(2)
|
||||
self.importer = self.setup_importer(
|
||||
autotag=False, resume=True, singletons=True
|
||||
)
|
||||
|
||||
# Aborts import after one track. This also ensures that we skip
|
||||
# the first album in the second try.
|
||||
|
|
@ -1408,10 +1405,10 @@ class ResumeImportTest(ImportTestCase):
|
|||
class IncrementalImportTest(ImportTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.config["import"]["incremental"] = True
|
||||
self.prepare_album_for_import(1)
|
||||
|
||||
def test_incremental_album(self):
|
||||
importer = self.create_importer(album_count=1)
|
||||
importer = self.setup_importer(autotag=False, incremental=True)
|
||||
importer.run()
|
||||
|
||||
# Change album name so the original file would be imported again
|
||||
|
|
@ -1420,13 +1417,13 @@ class IncrementalImportTest(ImportTestCase):
|
|||
album["album"] = "edited album"
|
||||
album.store()
|
||||
|
||||
importer = self.create_importer(album_count=1)
|
||||
importer.run()
|
||||
self.assertEqual(len(self.lib.albums()), 2)
|
||||
|
||||
def test_incremental_item(self):
|
||||
self.config["import"]["singletons"] = True
|
||||
importer = self.create_importer(item_count=1)
|
||||
importer = self.setup_importer(
|
||||
autotag=False, incremental=True, singletons=True
|
||||
)
|
||||
importer.run()
|
||||
|
||||
# Change track name so the original file would be imported again
|
||||
|
|
@ -1435,12 +1432,11 @@ class IncrementalImportTest(ImportTestCase):
|
|||
item["artist"] = "edited artist"
|
||||
item.store()
|
||||
|
||||
importer = self.create_importer(item_count=1)
|
||||
importer.run()
|
||||
self.assertEqual(len(self.lib.items()), 2)
|
||||
|
||||
def test_invalid_state_file(self):
|
||||
importer = self.create_importer()
|
||||
importer = self.setup_importer(autotag=False, incremental=True)
|
||||
with open(self.config["statefile"].as_filename(), "wb") as f:
|
||||
f.write(b"000")
|
||||
importer.run()
|
||||
|
|
@ -1648,7 +1644,7 @@ class ReimportTest(ImportTestCase):
|
|||
self.matcher.restore()
|
||||
|
||||
def _setup_session(self, singletons=False):
|
||||
self._setup_import_session(self._album().path, singletons=singletons)
|
||||
self.setup_importer(import_dir=self.libdir, singletons=singletons)
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
|
||||
def _album(self):
|
||||
|
|
@ -1732,8 +1728,7 @@ class ImportPretendTest(ImportTestCase):
|
|||
super().setUp()
|
||||
self.__create_import_dir()
|
||||
self.__create_empty_import_dir()
|
||||
self._setup_import_session()
|
||||
config["import"]["pretend"] = True
|
||||
self.setup_importer(pretend=True)
|
||||
self.matcher = AutotagStub().install()
|
||||
self.io.install()
|
||||
|
||||
|
|
@ -1763,7 +1758,7 @@ class ImportPretendTest(ImportTestCase):
|
|||
self.empty_path = path
|
||||
|
||||
def __run(self, import_paths, singletons=True):
|
||||
self._setup_import_session(singletons=singletons)
|
||||
self.setup_importer(singletons=singletons)
|
||||
self.importer.paths = import_paths
|
||||
|
||||
with capture_log() as logs:
|
||||
|
|
@ -1929,21 +1924,21 @@ class ImportMusicBrainzIdTest(ImportTestCase):
|
|||
self.prepare_album_for_import(1)
|
||||
|
||||
def test_one_mbid_one_album(self):
|
||||
self.config["import"]["search_ids"] = [
|
||||
self.MB_RELEASE_PREFIX + self.ID_RELEASE_0
|
||||
]
|
||||
self._setup_import_session()
|
||||
self.setup_importer(
|
||||
search_ids=[self.MB_RELEASE_PREFIX + self.ID_RELEASE_0]
|
||||
)
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.run()
|
||||
self.assertEqual(self.lib.albums().get().album, "VALID_RELEASE_0")
|
||||
|
||||
def test_several_mbid_one_album(self):
|
||||
self.config["import"]["search_ids"] = [
|
||||
self.MB_RELEASE_PREFIX + self.ID_RELEASE_0,
|
||||
self.MB_RELEASE_PREFIX + self.ID_RELEASE_1,
|
||||
]
|
||||
self._setup_import_session()
|
||||
self.setup_importer(
|
||||
search_ids=[
|
||||
self.MB_RELEASE_PREFIX + self.ID_RELEASE_0,
|
||||
self.MB_RELEASE_PREFIX + self.ID_RELEASE_1,
|
||||
]
|
||||
)
|
||||
|
||||
self.importer.add_choice(2) # Pick the 2nd best match (release 1).
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
|
|
@ -1951,21 +1946,23 @@ class ImportMusicBrainzIdTest(ImportTestCase):
|
|||
self.assertEqual(self.lib.albums().get().album, "VALID_RELEASE_1")
|
||||
|
||||
def test_one_mbid_one_singleton(self):
|
||||
self.config["import"]["search_ids"] = [
|
||||
self.MB_RECORDING_PREFIX + self.ID_RECORDING_0
|
||||
]
|
||||
self._setup_import_session(singletons=True)
|
||||
self.setup_importer(
|
||||
search_ids=[self.MB_RECORDING_PREFIX + self.ID_RECORDING_0],
|
||||
singletons=True,
|
||||
)
|
||||
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
self.importer.run()
|
||||
self.assertEqual(self.lib.items().get().title, "VALID_RECORDING_0")
|
||||
|
||||
def test_several_mbid_one_singleton(self):
|
||||
self.config["import"]["search_ids"] = [
|
||||
self.MB_RECORDING_PREFIX + self.ID_RECORDING_0,
|
||||
self.MB_RECORDING_PREFIX + self.ID_RECORDING_1,
|
||||
]
|
||||
self._setup_import_session(singletons=True)
|
||||
self.setup_importer(
|
||||
search_ids=[
|
||||
self.MB_RECORDING_PREFIX + self.ID_RECORDING_0,
|
||||
self.MB_RECORDING_PREFIX + self.ID_RECORDING_1,
|
||||
],
|
||||
singletons=True,
|
||||
)
|
||||
|
||||
self.importer.add_choice(2) # Pick the 2nd best match (recording 1).
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
|
|
|
|||
|
|
@ -135,8 +135,8 @@ class LoggingLevelTest(PluginMixin, ImportTestCase):
|
|||
def test_import_stage_level0(self):
|
||||
self.config["verbose"] = 0
|
||||
with helper.capture_log() as logs:
|
||||
importer = self.create_importer()
|
||||
importer.run()
|
||||
self.prepare_album_for_import(1)
|
||||
self.setup_importer(autotag=False).run()
|
||||
self.assertIn("dummy: warning import_stage", logs)
|
||||
self.assertNotIn("dummy: info import_stage", logs)
|
||||
self.assertNotIn("dummy: debug import_stage", logs)
|
||||
|
|
@ -144,8 +144,8 @@ class LoggingLevelTest(PluginMixin, ImportTestCase):
|
|||
def test_import_stage_level1(self):
|
||||
self.config["verbose"] = 1
|
||||
with helper.capture_log() as logs:
|
||||
importer = self.create_importer()
|
||||
importer.run()
|
||||
self.prepare_album_for_import(1)
|
||||
self.setup_importer(autotag=False).run()
|
||||
self.assertIn("dummy: warning import_stage", logs)
|
||||
self.assertIn("dummy: info import_stage", logs)
|
||||
self.assertNotIn("dummy: debug import_stage", logs)
|
||||
|
|
@ -153,8 +153,8 @@ class LoggingLevelTest(PluginMixin, ImportTestCase):
|
|||
def test_import_stage_level2(self):
|
||||
self.config["verbose"] = 2
|
||||
with helper.capture_log() as logs:
|
||||
importer = self.create_importer()
|
||||
importer.run()
|
||||
self.prepare_album_for_import(1)
|
||||
self.setup_importer(autotag=False).run()
|
||||
self.assertIn("dummy: warning import_stage", logs)
|
||||
self.assertIn("dummy: info import_stage", logs)
|
||||
self.assertIn("dummy: debug import_stage", logs)
|
||||
|
|
@ -264,20 +264,20 @@ class ConcurrentEventsTest(ImportTestCase):
|
|||
|
||||
blog.getLogger("beets").set_global_level(blog.WARNING)
|
||||
with helper.capture_log() as logs:
|
||||
importer = self.create_importer()
|
||||
importer.run()
|
||||
self.prepare_album_for_import(1)
|
||||
self.setup_importer(autotag=False).run()
|
||||
self.assertEqual(logs, [])
|
||||
|
||||
blog.getLogger("beets").set_global_level(blog.INFO)
|
||||
with helper.capture_log() as logs:
|
||||
importer = self.create_importer()
|
||||
importer.run()
|
||||
self.prepare_album_for_import(1)
|
||||
self.setup_importer(autotag=False).run()
|
||||
for l in logs:
|
||||
self.assertIn("import", l)
|
||||
self.assertIn("album", l)
|
||||
|
||||
blog.getLogger("beets").set_global_level(blog.DEBUG)
|
||||
with helper.capture_log() as logs:
|
||||
importer = self.create_importer()
|
||||
importer.run()
|
||||
self.prepare_album_for_import(1)
|
||||
self.setup_importer(autotag=False).run()
|
||||
self.assertIn("Sending event: database_change", logs)
|
||||
|
|
|
|||
|
|
@ -160,12 +160,9 @@ class ItemTypeConflictTest(PluginLoaderTestCase):
|
|||
class EventsTest(PluginImportTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
config["import"]["pretend"] = True
|
||||
|
||||
def test_import_task_created(self):
|
||||
import_files = [self.import_dir]
|
||||
self._setup_import_session(singletons=False)
|
||||
self.importer.paths = import_files
|
||||
self.importer = self.setup_importer(pretend=True)
|
||||
|
||||
with helper.capture_log() as logs:
|
||||
self.importer.run()
|
||||
|
|
@ -212,9 +209,7 @@ class EventsTest(PluginImportTestCase):
|
|||
to_singleton_plugin = ToSingletonPlugin
|
||||
self.register_plugin(to_singleton_plugin)
|
||||
|
||||
import_files = [self.import_dir]
|
||||
self._setup_import_session(singletons=False)
|
||||
self.importer.paths = import_files
|
||||
self.importer = self.setup_importer(pretend=True)
|
||||
|
||||
with helper.capture_log() as logs:
|
||||
self.importer.run()
|
||||
|
|
@ -371,7 +366,7 @@ class ListenersTest(PluginLoaderTestCase):
|
|||
class PromptChoicesTest(TerminalImportMixin, PluginImportTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self._setup_import_session()
|
||||
self.setup_importer()
|
||||
self.matcher = AutotagStub().install()
|
||||
# keep track of ui.input_option() calls
|
||||
self.input_options_patcher = patch(
|
||||
|
|
|
|||
Loading…
Reference in a new issue