From 8f5bae26fd557dd886f192e90fe0ba3c2c4b739b Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Wed, 25 Mar 2015 10:38:46 +0100 Subject: [PATCH] Smartplaylists: improve tests & code modularization --- beetsplug/cue.py | 54 +++++++++++++++++++++++++++++ beetsplug/smartplaylist.py | 16 ++++----- test/test_smartplaylist.py | 70 +++++++++++++++++++++----------------- 3 files changed, 101 insertions(+), 39 deletions(-) create mode 100644 beetsplug/cue.py diff --git a/beetsplug/cue.py b/beetsplug/cue.py new file mode 100644 index 000000000..25205f8e8 --- /dev/null +++ b/beetsplug/cue.py @@ -0,0 +1,54 @@ +# Copyright 2015 Bruno Cauet +# Split an album-file in tracks thanks a cue file + +import subprocess +from os import path +from glob import glob + +from beets.util import command_output, displayable_path +from beets.plugins import BeetsPlugin +from beets.autotag import TrackInfo + + +class CuePlugin(BeetsPlugin): + def __init__(self): + super(CuePlugin, self).__init__() + # this does not seem supported by shnsplit + self.config.add({ + 'keep_before': .1, + 'keep_after': .9, + }) + + # self.register_listener('import_task_start', self.look_for_cues) + + def candidates(self, items, artist, album, va_likely): + import pdb + pdb.set_trace() + + def item_candidates(self, item, artist, album): + dir = path.dirname(item.path) + cues = glob.glob(path.join(dir, "*.cue")) + if not cues: + return + if len(cues) > 1: + self._log.info(u"Found multiple cue files doing nothing: {0}", + map(displayable_path, cues)) + + cue_file = cues[0] + self._log.info("Found {} for {}", displayable_path(cue_file), item) + + try: + # careful: will ask for input in case of conflicts + command_output(['shnsplit', '-f', cue_file, item.path]) + except (subprocess.CalledProcessError, OSError): + self._log.exception(u'shnsplit execution failed') + return + + tracks = glob(path.join(dir, "*.wav")) + self._log.info("Generated {0} tracks", len(tracks)) + for t in tracks: + title = "dunno lol" + track_id = "wtf" + index = int(path.basename(t)[len("split-track"):-len(".wav")]) + yield TrackInfo(title, track_id, index=index, artist=artist) + # generate TrackInfo instances diff --git a/beetsplug/smartplaylist.py b/beetsplug/smartplaylist.py index 34fa94979..8889a2534 100644 --- a/beetsplug/smartplaylist.py +++ b/beetsplug/smartplaylist.py @@ -126,20 +126,20 @@ class SmartPlaylistPlugin(BeetsPlugin): self._unmatched_playlists.add(playlist_data) + def matches(self, model, query, album_query): + if album_query and isinstance(model, Album): + return album_query.match(model) + if query and isinstance(model, Item): + return query.match(model) + return False + def db_change(self, lib, model): if self._unmatched_playlists is None: self.build_queries() for playlist in self._unmatched_playlists: n, (q, _), (a_q, _) = playlist - if a_q and isinstance(model, Album): - matches = a_q.match(model) - elif q and isinstance(model, Item): - matches = q.match(model) or q.match(model.get_album()) - else: - matches = False - - if matches: + if self.matches(model, q, a_q): self._log.debug("{0} will be updated because of {1}", n, model) self._matched_playlists.add(playlist) self.register_listener('cli_exit', self.update_playlists) diff --git a/test/test_smartplaylist.py b/test/test_smartplaylist.py index 4af1cfeb6..ddfa8a156 100644 --- a/test/test_smartplaylist.py +++ b/test/test_smartplaylist.py @@ -92,45 +92,53 @@ class SmartPlaylistTest(unittest.TestCase): asseq(sorts["mixed"], MultipleSort([S('year'), S('genre'), S('id', False)])) + def test_matches(self): + spl = SmartPlaylistPlugin() + + a = MagicMock(Album) + i = MagicMock(Item) + + self.assertFalse(spl.matches(i, None, None)) + self.assertFalse(spl.matches(a, None, None)) + + query = Mock() + query.match.side_effect = {i: True}.__getitem__ + self.assertTrue(spl.matches(i, query, None)) + self.assertFalse(spl.matches(a, query, None)) + + a_query = Mock() + a_query.match.side_effect = {a: True}.__getitem__ + self.assertFalse(spl.matches(i, None, a_query)) + self.assertTrue(spl.matches(a, None, a_query)) + + self.assertTrue(spl.matches(i, query, a_query)) + self.assertTrue(spl.matches(a, query, a_query)) + def test_db_changes(self): spl = SmartPlaylistPlugin() - i1 = MagicMock(Item) - i2 = MagicMock(Item) - a = MagicMock(Album) - i1.get_album.return_value = a - - q1 = Mock() - q1.matches.side_effect = {i1: False, i2: False}.__getitem__ - a_q1 = Mock() - a_q1.matches.side_effect = {a: True}.__getitem__ - q2 = Mock() - q2.matches.side_effect = {i1: False, i2: True}.__getitem__ - - pl1 = '1', (q1, None), (a_q1, None) - pl2 = '2', (None, None), (a_q1, None) - pl3 = '3', (q2, None), (None, None) + nones = None, None + pl1 = '1', ('q1', None), nones + pl2 = '2', ('q2', None), nones + pl3 = '3', ('q3', None), nones spl._unmatched_playlists = set([pl1, pl2, pl3]) spl._matched_playlists = set() - spl.db_change(None, i1) - self.assertEqual(spl._unmatched_playlists, set([pl2])) + + spl.matches = Mock(return_value=False) + spl.db_change(None, "nothing") + self.assertEqual(spl._unmatched_playlists, set([pl1, pl2, pl3])) + self.assertEqual(spl._matched_playlists, set()) + + spl.matches.side_effect = lambda _, q, __: q == 'q3' + spl.db_change(None, "matches 3") + self.assertEqual(spl._unmatched_playlists, set([pl1, pl2])) + self.assertEqual(spl._matched_playlists, set([pl3])) + + spl.matches.side_effect = lambda _, q, __: q == 'q1' + spl.db_change(None, "matches 3") self.assertEqual(spl._matched_playlists, set([pl1, pl3])) - - spl._unmatched_playlists = set([pl1, pl2, pl3]) - spl._matched_playlists = set() - spl.db_change(None, i2) self.assertEqual(spl._unmatched_playlists, set([pl2])) - self.assertEqual(spl._matched_playlists, set([pl1, pl3])) - - spl._unmatched_playlists = set([pl1, pl2, pl3]) - spl._matched_playlists = set() - spl.db_change(None, a) - self.assertEqual(spl._unmatched_playlists, set([pl3])) - self.assertEqual(spl._matched_playlists, set([pl1, pl2])) - spl.db_change(None, i2) - self.assertEqual(spl._unmatched_playlists, set()) - self.assertEqual(spl._matched_playlists, set([pl1, pl2, pl3])) def test_playlist_update(self): spl = SmartPlaylistPlugin()