Merge pull request #532 from jodal/feature/search-by-albumartist

Search filtering by albumartist
This commit is contained in:
Thomas Adamcik 2013-10-19 13:46:58 -07:00
commit e0bfe144f8
5 changed files with 112 additions and 16 deletions

View File

@ -62,10 +62,16 @@ class LocalLibraryProvider(base.BaseLibraryProvider):
album_filter = lambda t: q == getattr(t, 'album', Album()).name
artist_filter = lambda t: filter(
lambda a: q == a.name, t.artists)
albumartist_filter = lambda t: any([
q == a.name
for a in getattr(t.album, 'artists', [])])
date_filter = lambda t: q == t.date
any_filter = lambda t: (
track_filter(t) or album_filter(t) or
artist_filter(t) or uri_filter(t))
track_filter(t) or
album_filter(t) or
artist_filter(t) or
albumartist_filter(t) or
uri_filter(t))
if field == 'uri':
result_tracks = filter(uri_filter, result_tracks)
@ -75,6 +81,8 @@ class LocalLibraryProvider(base.BaseLibraryProvider):
result_tracks = filter(album_filter, result_tracks)
elif field == 'artist':
result_tracks = filter(artist_filter, result_tracks)
elif field == 'albumartist':
result_tracks = filter(albumartist_filter, result_tracks)
elif field == 'date':
result_tracks = filter(date_filter, result_tracks)
elif field == 'any':
@ -105,9 +113,16 @@ class LocalLibraryProvider(base.BaseLibraryProvider):
t, 'album', Album()).name.lower()
artist_filter = lambda t: filter(
lambda a: q in a.name.lower(), t.artists)
albumartist_filter = lambda t: any([
q in a.name.lower()
for a in getattr(t.album, 'artists', [])])
date_filter = lambda t: t.date and t.date.startswith(q)
any_filter = lambda t: track_filter(t) or album_filter(t) or \
artist_filter(t) or uri_filter(t)
any_filter = lambda t: (
track_filter(t) or
album_filter(t) or
artist_filter(t) or
albumartist_filter(t) or
uri_filter(t))
if field == 'uri':
result_tracks = filter(uri_filter, result_tracks)
@ -117,6 +132,8 @@ class LocalLibraryProvider(base.BaseLibraryProvider):
result_tracks = filter(album_filter, result_tracks)
elif field == 'artist':
result_tracks = filter(artist_filter, result_tracks)
elif field == 'albumartist':
result_tracks = filter(albumartist_filter, result_tracks)
elif field == 'date':
result_tracks = filter(date_filter, result_tracks)
elif field == 'any':

View File

@ -166,7 +166,7 @@ def query_from_mpd_list_format(field, mpd_query):
key = tokens[0].lower()
value = tokens[1]
tokens = tokens[2:]
if key not in ('artist', 'album', 'date', 'genre'):
if key not in ('artist', 'album', 'albumartist', 'date', 'genre'):
raise MpdArgError('not able to parse args', command='list')
if not value:
raise ValueError

View File

@ -12,19 +12,33 @@ from tests import path_to_data_dir
class LocalLibraryProviderTest(unittest.TestCase):
artists = [Artist(name='artist1'), Artist(name='artist2'), Artist()]
artists = [
Artist(name='artist1'),
Artist(name='artist2'),
Artist(name='artist3'),
Artist(name='artist4'),
]
albums = [
Album(name='album1', artists=artists[:1]),
Album(name='album2', artists=artists[1:2]),
Album()]
Album(name='album1', artists=[artists[0]]),
Album(name='album2', artists=[artists[1]]),
Album(name='album3', artists=[artists[2]]),
]
tracks = [
Track(uri='local:track:path1', name='track1', artists=artists[:1],
album=albums[0], date='2001-02-03', length=4000),
Track(uri='local:track:path2', name='track2', artists=artists[1:2],
album=albums[1], date='2002', length=4000),
Track()]
Track(
uri='local:track:path1', name='track1',
artists=[artists[0]], album=albums[0],
date='2001-02-03', length=4000),
Track(
uri='local:track:path2', name='track2',
artists=[artists[1]], album=albums[1],
date='2002', length=4000),
Track(
uri='local:track:path3', name='track3',
artists=[artists[3]], album=albums[2],
date='2003', length=4000),
]
config = {
'local': {
@ -35,6 +49,7 @@ class LocalLibraryProviderTest(unittest.TestCase):
}
def setUp(self):
self.backend = actor.LocalBackend.start(
config=self.config, audio=None).proxy()
self.core = core.Core(backends=[self.backend])
@ -102,6 +117,19 @@ class LocalLibraryProviderTest(unittest.TestCase):
result = self.library.find_exact(album=['album2'])
self.assertEqual(list(result[0].tracks), self.tracks[1:2])
def test_find_exact_albumartist(self):
# Artist is both track artist and album artist
result = self.library.find_exact(albumartist=['artist1'])
self.assertEqual(list(result[0].tracks), [self.tracks[0]])
# Artist is both track and album artist
result = self.library.find_exact(albumartist=['artist2'])
self.assertEqual(list(result[0].tracks), [self.tracks[1]])
# Artist is just album artist
result = self.library.find_exact(albumartist=['artist3'])
self.assertEqual(list(result[0].tracks), [self.tracks[2]])
def test_find_exact_date(self):
result = self.library.find_exact(date=['2001'])
self.assertEqual(list(result[0].tracks), [])
@ -112,6 +140,27 @@ class LocalLibraryProviderTest(unittest.TestCase):
result = self.library.find_exact(date=['2002'])
self.assertEqual(list(result[0].tracks), self.tracks[1:2])
def test_find_exact_any(self):
# Matches on track artist
result = self.library.find_exact(any=['artist1'])
self.assertEqual(list(result[0].tracks), self.tracks[:1])
# Matches on track
result = self.library.find_exact(any=['track1'])
self.assertEqual(list(result[0].tracks), self.tracks[:1])
# Matches on track album
result = self.library.find_exact(any=['album1'])
self.assertEqual(list(result[0].tracks), self.tracks[:1])
# Matches on track album artists
result = self.library.find_exact(any=['artist3'])
self.assertEqual(list(result[0].tracks), self.tracks[2:3])
# Matches on URI
result = self.library.find_exact(any=['local:track:path1'])
self.assertEqual(list(result[0].tracks), self.tracks[:1])
def test_find_exact_wrong_type(self):
test = lambda: self.library.find_exact(wrong=['test'])
self.assertRaises(LookupError, test)
@ -163,6 +212,19 @@ class LocalLibraryProviderTest(unittest.TestCase):
result = self.library.search(artist=['Tist2'])
self.assertEqual(list(result[0].tracks), self.tracks[1:2])
def test_search_albumartist(self):
# Artist is both track artist and album artist
result = self.library.search(albumartist=['Tist1'])
self.assertEqual(list(result[0].tracks), [self.tracks[0]])
# Artist is both track artist and album artist
result = self.library.search(albumartist=['Tist2'])
self.assertEqual(list(result[0].tracks), [self.tracks[1]])
# Artist is just album artist
result = self.library.search(albumartist=['Tist3'])
self.assertEqual(list(result[0].tracks), [self.tracks[2]])
def test_search_album(self):
result = self.library.search(album=['Bum1'])
self.assertEqual(list(result[0].tracks), self.tracks[:1])
@ -184,12 +246,23 @@ class LocalLibraryProviderTest(unittest.TestCase):
self.assertEqual(list(result[0].tracks), self.tracks[1:2])
def test_search_any(self):
# Matches on track artist
result = self.library.search(any=['Tist1'])
self.assertEqual(list(result[0].tracks), self.tracks[:1])
# Matches on track
result = self.library.search(any=['Rack1'])
self.assertEqual(list(result[0].tracks), self.tracks[:1])
# Matches on track album
result = self.library.search(any=['Bum1'])
self.assertEqual(list(result[0].tracks), self.tracks[:1])
# Matches on track album artists
result = self.library.search(any=['Tist3'])
self.assertEqual(list(result[0].tracks), self.tracks[2:3])
# Matches on URI
result = self.library.search(any=['TH1'])
self.assertEqual(list(result[0].tracks), self.tracks[:1])

View File

@ -10,7 +10,7 @@ Title: track1
Album: album1
Date: 2001-02-03
Time: 4
key: key1
key: key2
file: /path2
Artist: artist2
Title: track2
@ -19,8 +19,10 @@ Date: 2002
Time: 4
key: key3
file: /path3
Artist: artist3
Artist: artist4
AlbumArtist: artist3
Title: track3
Album: album3
Date: 2003
Time: 4
songList end

View File

@ -366,6 +366,10 @@ class MusicDatabaseListTest(protocol.BaseTestCase):
self.sendRequest('list "album" "album" "analbum"')
self.assertInResponse('OK')
def test_list_album_by_albumartist(self):
self.sendRequest('list "album" "albumartist" "anartist"')
self.assertInResponse('OK')
def test_list_album_by_full_date(self):
self.sendRequest('list "album" "date" "2001-01-01"')
self.assertInResponse('OK')