Smartplaylists: improve tests & code modularization

This commit is contained in:
Bruno Cauet 2015-03-25 10:38:46 +01:00
parent adec09de96
commit 8f5bae26fd
3 changed files with 101 additions and 39 deletions

54
beetsplug/cue.py Normal file
View file

@ -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

View file

@ -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)

View file

@ -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()