mirror of
https://github.com/beetbox/beets.git
synced 2026-02-21 23:03:26 +01:00
commit
9f5f70aeab
12 changed files with 616 additions and 646 deletions
1118
beets/importer.py
1118
beets/importer.py
File diff suppressed because it is too large
Load diff
|
|
@ -740,7 +740,7 @@ class TerminalImportSession(importer.ImportSession):
|
|||
pass
|
||||
elif sel == 'r':
|
||||
# Remove old.
|
||||
task.remove_duplicates = True
|
||||
task.should_remove_duplicates = True
|
||||
else:
|
||||
assert False
|
||||
|
||||
|
|
|
|||
|
|
@ -137,6 +137,51 @@ def multiple(messages):
|
|||
return MultiMessage(messages)
|
||||
|
||||
|
||||
def stage(func):
|
||||
"""Decorate a function to become a simple stage.
|
||||
|
||||
>>> @stage
|
||||
... def add(n, i):
|
||||
... return i + n
|
||||
>>> pipe = Pipeline([
|
||||
... iter([1, 2, 3]),
|
||||
... add(2),
|
||||
... ])
|
||||
>>> list(pipe.pull())
|
||||
[3, 4, 5]
|
||||
"""
|
||||
|
||||
def coro(*args):
|
||||
task = None
|
||||
while True:
|
||||
task = yield task
|
||||
task = func(*(args + (task,)))
|
||||
return coro
|
||||
|
||||
|
||||
def mutator_stage(func):
|
||||
"""Decorate a function that manipulates items in a coroutine to
|
||||
become a simple stage.
|
||||
|
||||
>>> @mutator_stage
|
||||
... def setkey(key, item):
|
||||
... item[key] = True
|
||||
>>> pipe = Pipeline([
|
||||
... iter([{'x': False}, {'a': False}]),
|
||||
... setkey('x'),
|
||||
... ])
|
||||
>>> list(pipe.pull())
|
||||
[{'x': True}, {'a': False, 'x': True}]
|
||||
"""
|
||||
|
||||
def coro(*args):
|
||||
task = None
|
||||
while True:
|
||||
task = yield task
|
||||
func(*(args + (task,)))
|
||||
return coro
|
||||
|
||||
|
||||
def _allmsgs(obj):
|
||||
"""Returns a list of all the messages encapsulated in obj. If obj
|
||||
is a MultiMessage, returns its enclosed messages. If obj is BUBBLE,
|
||||
|
|
|
|||
|
|
@ -278,8 +278,7 @@ class FetchArtPlugin(BeetsPlugin):
|
|||
# For any other choices (e.g., TRACKS), do nothing.
|
||||
return
|
||||
|
||||
album = session.lib.get_album(task.album_id)
|
||||
path = art_for_album(album, task.paths, self.maxwidth, local)
|
||||
path = art_for_album(task.album, task.paths, self.maxwidth, local)
|
||||
|
||||
if path:
|
||||
self.art_paths[task] = path
|
||||
|
|
@ -290,7 +289,7 @@ class FetchArtPlugin(BeetsPlugin):
|
|||
if task in self.art_paths:
|
||||
path = self.art_paths.pop(task)
|
||||
|
||||
album = session.lib.get_album(task.album_id)
|
||||
album = task.album
|
||||
src_removed = (config['import']['delete'].get(bool) or
|
||||
config['import']['move'].get(bool))
|
||||
album.set_art(path, not src_removed)
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ class LastGenrePlugin(plugins.BeetsPlugin):
|
|||
def imported(self, session, task):
|
||||
"""Event hook called when an import task finishes."""
|
||||
if task.is_album:
|
||||
album = session.lib.get_album(task.album_id)
|
||||
album = task.album
|
||||
album.genre, src = self._get_genre(album)
|
||||
log.debug(u'added last.fm album genre ({0}): {1}'.format(
|
||||
src, album.genre
|
||||
|
|
|
|||
|
|
@ -601,8 +601,7 @@ class ReplayGainPlugin(BeetsPlugin):
|
|||
return
|
||||
|
||||
if task.is_album:
|
||||
album = session.lib.get_album(task.album_id)
|
||||
self.handle_album(album, False)
|
||||
self.handle_album(task.album, False)
|
||||
else:
|
||||
self.handle_track(task.item, False)
|
||||
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ class TestImportSession(importer.ImportSession):
|
|||
if res == self.Resolution.SKIP:
|
||||
task.set_choice(importer.action.SKIP)
|
||||
elif res == self.Resolution.REMOVE:
|
||||
task.remove_duplicates = True
|
||||
task.should_remove_duplicates = True
|
||||
|
||||
|
||||
def generate_album_info(album_id, track_ids):
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ class ArtImporterTest(_common.TestCase):
|
|||
# Import task for the coroutine.
|
||||
self.task = importer.ImportTask(None, None, [self.i])
|
||||
self.task.is_album = True
|
||||
self.task.album_id = self.album.id
|
||||
self.task.album = self.album
|
||||
info = AlbumInfo(
|
||||
album = 'some album',
|
||||
album_id = 'albumid',
|
||||
|
|
|
|||
|
|
@ -15,10 +15,7 @@ class IHatePluginTest(unittest.TestCase):
|
|||
genre='TestGenre',
|
||||
album=u'TestAlbum',
|
||||
artist=u'TestArtist')
|
||||
task = importer.ImportTask()
|
||||
task.items = [test_item]
|
||||
task.item = test_item
|
||||
task.is_album = False
|
||||
task = importer.SingletonImportTask(test_item)
|
||||
|
||||
# Empty query should let it pass.
|
||||
self.assertFalse(IHatePlugin.do_i_hate_this(task, match_pattern))
|
||||
|
|
|
|||
|
|
@ -867,12 +867,9 @@ class InferAlbumDataTest(_common.TestCase):
|
|||
items=self.items)
|
||||
self.task.set_null_candidates()
|
||||
|
||||
def _infer(self):
|
||||
importer._infer_album_fields(self.task)
|
||||
|
||||
def test_asis_homogenous_single_artist(self):
|
||||
self.task.set_choice(importer.action.ASIS)
|
||||
self._infer()
|
||||
self.task.infer_album_fields()
|
||||
self.assertFalse(self.items[0].comp)
|
||||
self.assertEqual(self.items[0].albumartist, self.items[2].artist)
|
||||
|
||||
|
|
@ -881,7 +878,7 @@ class InferAlbumDataTest(_common.TestCase):
|
|||
self.items[1].artist = 'some other artist'
|
||||
self.task.set_choice(importer.action.ASIS)
|
||||
|
||||
self._infer()
|
||||
self.task.infer_album_fields()
|
||||
|
||||
self.assertTrue(self.items[0].comp)
|
||||
self.assertEqual(self.items[0].albumartist, 'Various Artists')
|
||||
|
|
@ -891,7 +888,7 @@ class InferAlbumDataTest(_common.TestCase):
|
|||
self.items[1].artist = 'some other artist'
|
||||
self.task.set_choice(importer.action.ASIS)
|
||||
|
||||
self._infer()
|
||||
self.task.infer_album_fields()
|
||||
|
||||
for item in self.items:
|
||||
self.assertTrue(item.comp)
|
||||
|
|
@ -901,7 +898,7 @@ class InferAlbumDataTest(_common.TestCase):
|
|||
self.items[0].artist = 'another artist'
|
||||
self.task.set_choice(importer.action.ASIS)
|
||||
|
||||
self._infer()
|
||||
self.task.infer_album_fields()
|
||||
|
||||
self.assertFalse(self.items[0].comp)
|
||||
self.assertEqual(self.items[0].albumartist, self.items[2].artist)
|
||||
|
|
@ -914,7 +911,7 @@ class InferAlbumDataTest(_common.TestCase):
|
|||
item.mb_albumartistid = 'some album artist id'
|
||||
self.task.set_choice(importer.action.ASIS)
|
||||
|
||||
self._infer()
|
||||
self.task.infer_album_fields()
|
||||
|
||||
self.assertEqual(self.items[0].albumartist,
|
||||
'some album artist')
|
||||
|
|
@ -924,7 +921,7 @@ class InferAlbumDataTest(_common.TestCase):
|
|||
def test_apply_gets_artist_and_id(self):
|
||||
self.task.set_choice(AlbumMatch(0, None, {}, set(), set())) # APPLY
|
||||
|
||||
self._infer()
|
||||
self.task.infer_album_fields()
|
||||
|
||||
self.assertEqual(self.items[0].albumartist, self.items[0].artist)
|
||||
self.assertEqual(self.items[0].mb_albumartistid,
|
||||
|
|
@ -936,7 +933,7 @@ class InferAlbumDataTest(_common.TestCase):
|
|||
item.mb_albumartistid = 'some album artist id'
|
||||
self.task.set_choice(AlbumMatch(0, None, {}, set(), set())) # APPLY
|
||||
|
||||
self._infer()
|
||||
self.task.infer_album_fields()
|
||||
|
||||
self.assertEqual(self.items[0].albumartist,
|
||||
'some album artist')
|
||||
|
|
@ -947,16 +944,9 @@ class InferAlbumDataTest(_common.TestCase):
|
|||
self.items = [self.items[0]]
|
||||
self.task.items = self.items
|
||||
self.task.set_choice(importer.action.ASIS)
|
||||
self._infer()
|
||||
self.task.infer_album_fields()
|
||||
self.assertFalse(self.items[0].comp)
|
||||
|
||||
def test_first_item_null_apply(self):
|
||||
self.items[0] = None
|
||||
self.task.set_choice(AlbumMatch(0, None, {}, set(), set())) # APPLY
|
||||
self._infer()
|
||||
self.assertFalse(self.items[1].comp)
|
||||
self.assertEqual(self.items[1].albumartist, self.items[2].artist)
|
||||
|
||||
|
||||
class ImportDuplicateAlbumTest(unittest.TestCase, TestHelper):
|
||||
|
||||
|
|
|
|||
|
|
@ -208,6 +208,32 @@ class MultiMessageTest(unittest.TestCase):
|
|||
self.assertEqual(list(pl.pull()), [0, 0, 1, -1, 2, -2, 3, -3, 4, -4])
|
||||
|
||||
|
||||
class StageDecoratorTest(unittest.TestCase):
|
||||
|
||||
def test_stage_decorator(self):
|
||||
@pipeline.stage
|
||||
def add(n, i):
|
||||
return i + n
|
||||
|
||||
pl = pipeline.Pipeline([
|
||||
iter([1, 2, 3]),
|
||||
add(2)
|
||||
])
|
||||
self.assertEqual(list(pl.pull()), [3, 4, 5])
|
||||
|
||||
def test_mutator_stage_decorator(self):
|
||||
@pipeline.mutator_stage
|
||||
def setkey(key, item):
|
||||
item[key] = True
|
||||
|
||||
pl = pipeline.Pipeline([
|
||||
iter([{'x': False}, {'a': False}]),
|
||||
setkey('x'),
|
||||
])
|
||||
self.assertEqual(list(pl.pull()),
|
||||
[{'x': True}, {'a': False, 'x': True}])
|
||||
|
||||
|
||||
def suite():
|
||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||
|
||||
|
|
|
|||
|
|
@ -473,32 +473,6 @@ class PrintTest(_common.TestCase):
|
|||
del os.environ['LC_CTYPE']
|
||||
|
||||
|
||||
class AutotagTest(_common.TestCase):
|
||||
def setUp(self):
|
||||
super(AutotagTest, self).setUp()
|
||||
self.io.install()
|
||||
|
||||
def _no_candidates_test(self, result):
|
||||
task = importer.ImportTask(
|
||||
'toppath',
|
||||
'path',
|
||||
[_common.item()],
|
||||
)
|
||||
task.set_candidates('artist', 'album', [], autotag.Recommendation.none)
|
||||
session = _common.import_session(cli=True)
|
||||
res = session.choose_match(task)
|
||||
self.assertEqual(res, result)
|
||||
self.assertTrue('No match' in self.io.getoutput())
|
||||
|
||||
def test_choose_match_with_no_candidates_skip(self):
|
||||
self.io.addinput('s')
|
||||
self._no_candidates_test(importer.action.SKIP)
|
||||
|
||||
def test_choose_match_with_no_candidates_asis(self):
|
||||
self.io.addinput('u')
|
||||
self._no_candidates_test(importer.action.ASIS)
|
||||
|
||||
|
||||
class ImportTest(_common.TestCase):
|
||||
def test_quiet_timid_disallowed(self):
|
||||
config['import']['quiet'] = True
|
||||
|
|
|
|||
Loading…
Reference in a new issue