From df1820f0a7a4a614412a5aa0ec1de68bf50f55d5 Mon Sep 17 00:00:00 2001 From: Lasse Bigum Date: Sat, 2 Nov 2013 02:29:37 +0100 Subject: [PATCH] Add genre, composer, and performer tags and use them --- mopidy/backends/local/library.py | 32 +++++++ mopidy/backends/local/translator.py | 9 ++ mopidy/frontends/mpd/protocol/music_db.py | 48 ++++++++-- mopidy/frontends/mpd/translator.py | 35 ++++++- mopidy/models.py | 22 +++++ mopidy/scanner.py | 36 +++++--- tests/backends/local/library_test.py | 107 +++++++++++++++++++++- tests/data/library_tag_cache | 14 +++ tests/models_test.py | 13 ++- 9 files changed, 288 insertions(+), 28 deletions(-) diff --git a/mopidy/backends/local/library.py b/mopidy/backends/local/library.py index 2ff0e6d1..dc699853 100644 --- a/mopidy/backends/local/library.py +++ b/mopidy/backends/local/library.py @@ -73,7 +73,14 @@ class LocalLibraryProvider(base.BaseLibraryProvider): albumartist_filter = lambda t: any([ q == a.name for a in getattr(t.album, 'artists', [])]) + composer_filter = lambda t: any([ + q == a.name + for a in getattr(t, 'composers', [])]) + performer_filter = lambda t: any([ + q == a.name + for a in getattr(t, 'performers', [])]) track_no_filter = lambda t: q == t.track_no + genre_filter = lambda t: t.genre and q == t.genre date_filter = lambda t: q == t.date any_filter = lambda t: ( uri_filter(t) or @@ -81,7 +88,10 @@ class LocalLibraryProvider(base.BaseLibraryProvider): album_filter(t) or artist_filter(t) or albumartist_filter(t) or + composer_filter(t) or + performer_filter(t) or track_no_filter(t) or + genre_filter(t) or date_filter(t)) if field == 'uri': @@ -94,8 +104,14 @@ class LocalLibraryProvider(base.BaseLibraryProvider): result_tracks = filter(artist_filter, result_tracks) elif field == 'albumartist': result_tracks = filter(albumartist_filter, result_tracks) + elif field == 'composer': + result_tracks = filter(composer_filter, result_tracks) + elif field == 'performer': + result_tracks = filter(performer_filter, result_tracks) elif field == 'track_no': result_tracks = filter(track_no_filter, result_tracks) + elif field == 'genre': + result_tracks = filter(genre_filter, result_tracks) elif field == 'date': result_tracks = filter(date_filter, result_tracks) elif field == 'any': @@ -132,7 +148,14 @@ class LocalLibraryProvider(base.BaseLibraryProvider): albumartist_filter = lambda t: any([ q in a.name.lower() for a in getattr(t.album, 'artists', [])]) + composer_filter = lambda t: any([ + q in a.name.lower() + for a in getattr(t, 'composers', [])]) + performer_filter = lambda t: any([ + q in a.name.lower() + for a in getattr(t, 'performers', [])]) track_no_filter = lambda t: q == t.track_no + genre_filter = lambda t: t.genre and q in t.genre.lower() date_filter = lambda t: t.date and t.date.startswith(q) any_filter = lambda t: ( uri_filter(t) or @@ -140,7 +163,10 @@ class LocalLibraryProvider(base.BaseLibraryProvider): album_filter(t) or artist_filter(t) or albumartist_filter(t) or + composer_filter(t) or + performer_filter(t) or track_no_filter(t) or + genre_filter(t) or date_filter(t)) if field == 'uri': @@ -153,8 +179,14 @@ class LocalLibraryProvider(base.BaseLibraryProvider): result_tracks = filter(artist_filter, result_tracks) elif field == 'albumartist': result_tracks = filter(albumartist_filter, result_tracks) + elif field == 'composer': + result_tracks = filter(composer_filter, result_tracks) + elif field == 'performer': + result_tracks = filter(performer_filter, result_tracks) elif field == 'track_no': result_tracks = filter(track_no_filter, result_tracks) + elif field == 'genre': + result_tracks = filter(genre_filter, result_tracks) elif field == 'date': result_tracks = filter(date_filter, result_tracks) elif field == 'any': diff --git a/mopidy/backends/local/translator.py b/mopidy/backends/local/translator.py index 7cd46fbb..59b849ef 100644 --- a/mopidy/backends/local/translator.py +++ b/mopidy/backends/local/translator.py @@ -125,12 +125,21 @@ def _convert_mpd_data(data, tracks): if 'albumartist' in data: albumartist_kwargs['name'] = data['albumartist'] + if 'composer' in data: + track_kwargs['composers'] = [Artist(name=data['composer'])] + + if 'performer' in data: + track_kwargs['performers'] = [Artist(name=data['performer'])] + if 'album' in data: album_kwargs['name'] = data['album'] if 'title' in data: track_kwargs['name'] = data['title'] + if 'genre' in data: + track_kwargs['genre'] = data['genre'] + if 'date' in data: track_kwargs['date'] = data['date'] diff --git a/mopidy/frontends/mpd/protocol/music_db.py b/mopidy/frontends/mpd/protocol/music_db.py index 6dd43d68..b35aff14 100644 --- a/mopidy/frontends/mpd/protocol/music_db.py +++ b/mopidy/frontends/mpd/protocol/music_db.py @@ -10,8 +10,9 @@ from mopidy.frontends.mpd.protocol import handle_request, stored_playlists QUERY_RE = ( - r'(?P("?([Aa]lbum|[Aa]rtist|[Aa]lbumartist|[Dd]ate|[Ff]ile|' - r'[Ff]ilename|[Tt]itle|[Tt]rack|[Aa]ny)"? "[^"]*"\s?)+)$') + r'(?P("?([Aa]lbum|[Aa]rtist|[Aa]lbumartist|[Cc]omment|' + r'[Cc]omposer|[Dd]ate|[Ff]ile|[Ff]ilename|[Gg]enre|[Pp]erformer|' + r'[Tt]itle|[Tt]rack|[Aa]ny)"? "[^"]*"\s?)+)$') def _get_field(field, search_results): @@ -100,9 +101,12 @@ def find(context, mpd_query): return results = context.core.library.find_exact(**query).get() result_tracks = [] - if 'artist' not in query and 'albumartist' not in query: + if ('artist' not in query and + 'albumartist' not in query and + 'composer' not in query and + 'performer' not in query): result_tracks += [_artist_as_track(a) for a in _get_artists(results)] - if 'album' not in query: + if 'album' not in query and 'genre' not in query: result_tracks += [_album_as_track(a) for a in _get_albums(results)] result_tracks += _get_tracks(results) return translator.tracks_to_mpd_format(result_tracks) @@ -127,7 +131,8 @@ def findadd(context, mpd_query): @handle_request( - r'^list "?(?P([Aa]rtist|[Aa]lbum|[Dd]ate|[Gg]enre))"?' + r'^list "?(?P([Aa]rtist|[Aa]lbum|[Cc]omposer|[Dd]ate|[Gg]enre|' + r'[Pp]erformer))"?' r'( (?P.*))?$') def list_(context, field, mpd_query=None): """ @@ -220,10 +225,14 @@ def list_(context, field, mpd_query=None): return _list_artist(context, query) elif field == 'album': return _list_album(context, query) + elif field == 'composer': + return _list_composer(context, query) + elif field == 'performer': + return _list_performer(context, query) elif field == 'date': return _list_date(context, query) elif field == 'genre': - pass # TODO We don't have genre in our internal data structures yet + return _list_genre(context, query) def _list_artist(context, query): @@ -245,6 +254,24 @@ def _list_album(context, query): return albums +def _list_composer(context, query): + composers = set() + results = context.core.library.find_exact(**query).get() + for track in _get_tracks(results): + if track.composer and track.composer.name: + composers.add(('Composer', track.composer.name)) + return composers + + +def _list_performer(context, query): + performers = set() + results = context.core.library.find_exact(**query).get() + for track in _get_tracks(results): + if track.performer and track.performer.name: + performers.add(('Performer', track.performer.name)) + return performers + + def _list_date(context, query): dates = set() results = context.core.library.find_exact(**query).get() @@ -254,6 +281,15 @@ def _list_date(context, query): return dates +def _list_genre(context, query): + genres = set() + results = context.core.library.find_exact(**query).get() + for track in _get_tracks(results): + if track.genre: + genres.add(('Genre', track.genre)) + return genres + + @handle_request(r'^listall$') @handle_request(r'^listall "(?P[^"]+)"$') def listall(context, uri=None): diff --git a/mopidy/frontends/mpd/translator.py b/mopidy/frontends/mpd/translator.py index 9b331395..a60dfd20 100644 --- a/mopidy/frontends/mpd/translator.py +++ b/mopidy/frontends/mpd/translator.py @@ -37,8 +37,11 @@ def track_to_mpd_format(track, position=None): ('Artist', artists_to_mpd_format(track.artists)), ('Title', track.name or ''), ('Album', track.album and track.album.name or ''), - ('Date', track.date or ''), ] + + if track.date: + result.append(('Date', track.date)) + if track.album is not None and track.album.num_tracks != 0: result.append(('Track', '%d/%d' % ( track.track_no, track.album.num_tracks))) @@ -64,14 +67,31 @@ def track_to_mpd_format(track, position=None): artists = filter(lambda a: a.musicbrainz_id is not None, track.artists) if artists: result.append(('MUSICBRAINZ_ARTISTID', artists[0].musicbrainz_id)) + + if track.composers: + result.append(('Composer', artists_to_mpd_format(track.composers))) + + if track.performers: + result.append(('Performer', artists_to_mpd_format(track.performers))) + + if track.genre: + result.append(('Genre', track.genre)) + + if track.disc_no: + result.append(('Disc', track.disc_no)) + + if track.comment: + result.append(('Comment', track.comment)) + if track.musicbrainz_id is not None: result.append(('MUSICBRAINZ_TRACKID', track.musicbrainz_id)) return result MPD_KEY_ORDER = ''' - key file Time Artist AlbumArtist Title Album Track Date MUSICBRAINZ_ALBUMID - MUSICBRAINZ_ALBUMARTISTID MUSICBRAINZ_ARTISTID MUSICBRAINZ_TRACKID mtime + key file Time Artist Album AlbumArtist Title Track Genre Date Composer + Performer Comment Disc MUSICBRAINZ_ALBUMID MUSICBRAINZ_ALBUMARTISTID + MUSICBRAINZ_ARTISTID MUSICBRAINZ_TRACKID mtime '''.split() @@ -166,7 +186,8 @@ 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', 'albumartist', 'date', 'genre'): + if key not in ('artist', 'album', 'albumartist', 'composer', + 'date', 'genre', 'performer'): raise MpdArgError('not able to parse args', command='list') if not value: raise ValueError @@ -189,9 +210,12 @@ MPD_SEARCH_QUERY_RE = re.compile(r""" [Aa]lbum | [Aa]rtist | [Aa]lbumartist + | [Cc]omposer | [Dd]ate | [Ff]ile | [Ff]ilename + | [Gg]enre + | [Pp]erformer | [Tt]itle | [Tt]rack | [Aa]ny @@ -208,9 +232,12 @@ MPD_SEARCH_QUERY_PART_RE = re.compile(r""" [Aa]lbum | [Aa]rtist | [Aa]lbumartist + | [Cc]omposer | [Dd]ate | [Ff]ile | [Ff]ilename + | [Gg]enre + | [Pp]erformer | [Tt]itle | [Tt]rack | [Aa]ny diff --git a/mopidy/models.py b/mopidy/models.py index 3fc92bb4..5ab2ed92 100644 --- a/mopidy/models.py +++ b/mopidy/models.py @@ -219,6 +219,12 @@ class Track(ImmutableObject): :type artists: list of :class:`Artist` :param album: track album :type album: :class:`Album` + :param composer: track composer + :type composer: string + :param performer: track performer + :type performer: string + :param genre: track genre + :type genre: string :param track_no: track number in album :type track_no: integer :param disc_no: disc number in album @@ -229,6 +235,8 @@ class Track(ImmutableObject): :type length: integer :param bitrate: bitrate in kbit/s :type bitrate: integer + :param comment: track comment + :type comment: string :param musicbrainz_id: MusicBrainz ID :type musicbrainz_id: string :param last_modified: Represents last modification time @@ -247,6 +255,15 @@ class Track(ImmutableObject): #: The track :class:`Album`. Read-only. album = None + #: A set of track composers. Read-only. + composers = frozenset() + + #: A set of track performers`. Read-only. + performers = frozenset() + + #: The track genre. Read-only. + genre = None + #: The track number in the album. Read-only. track_no = 0 @@ -262,6 +279,9 @@ class Track(ImmutableObject): #: The track's bitrate in kbit/s. Read-only. bitrate = None + #: The track comment. Read-only. + comment = None + #: The MusicBrainz ID of the track. Read-only. musicbrainz_id = None @@ -272,6 +292,8 @@ class Track(ImmutableObject): def __init__(self, *args, **kwargs): self.__dict__['artists'] = frozenset(kwargs.pop('artists', [])) + self.__dict__['composers'] = frozenset(kwargs.pop('composers', [])) + self.__dict__['performers'] = frozenset(kwargs.pop('performers', [])) super(Track, self).__init__(*args, **kwargs) diff --git a/mopidy/scanner.py b/mopidy/scanner.py index dd21fdb4..9f4f36e4 100644 --- a/mopidy/scanner.py +++ b/mopidy/scanner.py @@ -139,6 +139,8 @@ def translator(data): albumartist_kwargs = {} album_kwargs = {} artist_kwargs = {} + composer_kwargs = {} + performer_kwargs = {} track_kwargs = {} def _retrieve(source_key, target_key, target): @@ -149,6 +151,22 @@ def translator(data): _retrieve(gst.TAG_TRACK_COUNT, 'num_tracks', album_kwargs) _retrieve(gst.TAG_ALBUM_VOLUME_COUNT, 'num_discs', album_kwargs) _retrieve(gst.TAG_ARTIST, 'name', artist_kwargs) + _retrieve(gst.TAG_COMPOSER, 'name', composer_kwargs) + _retrieve(gst.TAG_PERFORMER, 'name', performer_kwargs) + _retrieve(gst.TAG_ALBUM_ARTIST, 'name', albumartist_kwargs) + _retrieve(gst.TAG_TITLE, 'name', track_kwargs) + _retrieve(gst.TAG_TRACK_NUMBER, 'track_no', track_kwargs) + _retrieve(gst.TAG_ALBUM_VOLUME_NUMBER, 'disc_no', track_kwargs) + _retrieve(gst.TAG_GENRE, 'genre', track_kwargs) + _retrieve(gst.TAG_BITRATE, 'bitrate', track_kwargs) + + # Following keys don't seem to have TAG_* constant. + _retrieve('comment', 'comment', track_kwargs) + _retrieve('musicbrainz-trackid', 'musicbrainz_id', track_kwargs) + _retrieve('musicbrainz-artistid', 'musicbrainz_id', artist_kwargs) + _retrieve('musicbrainz-albumid', 'musicbrainz_id', album_kwargs) + _retrieve( + 'musicbrainz-albumartistid', 'musicbrainz_id', albumartist_kwargs) if gst.TAG_DATE in data and data[gst.TAG_DATE]: date = data[gst.TAG_DATE] @@ -159,18 +177,6 @@ def translator(data): else: track_kwargs['date'] = date.isoformat() - _retrieve(gst.TAG_TITLE, 'name', track_kwargs) - _retrieve(gst.TAG_TRACK_NUMBER, 'track_no', track_kwargs) - _retrieve(gst.TAG_ALBUM_VOLUME_NUMBER, 'disc_no', track_kwargs) - - # Following keys don't seem to have TAG_* constant. - _retrieve('album-artist', 'name', albumartist_kwargs) - _retrieve('musicbrainz-trackid', 'musicbrainz_id', track_kwargs) - _retrieve('musicbrainz-artistid', 'musicbrainz_id', artist_kwargs) - _retrieve('musicbrainz-albumid', 'musicbrainz_id', album_kwargs) - _retrieve( - 'musicbrainz-albumartistid', 'musicbrainz_id', albumartist_kwargs) - if albumartist_kwargs: album_kwargs['artists'] = [Artist(**albumartist_kwargs)] @@ -180,6 +186,12 @@ def translator(data): track_kwargs['album'] = Album(**album_kwargs) track_kwargs['artists'] = [Artist(**artist_kwargs)] + if composer_kwargs: + track_kwargs['composers'] = [Artist(**composer_kwargs)] + + if performer_kwargs: + track_kwargs['performers'] = [Artist(**performer_kwargs)] + return Track(**track_kwargs) diff --git a/tests/backends/local/library_test.py b/tests/backends/local/library_test.py index 1cb07451..532008a6 100644 --- a/tests/backends/local/library_test.py +++ b/tests/backends/local/library_test.py @@ -20,12 +20,15 @@ class LocalLibraryProviderTest(unittest.TestCase): Artist(name='artist2'), Artist(name='artist3'), Artist(name='artist4'), + Artist(name='artist5'), + Artist(name='artist6'), ] albums = [ Album(name='album1', artists=[artists[0]]), Album(name='album2', artists=[artists[1]]), Album(name='album3', artists=[artists[2]]), + Album(name='album4'), ] tracks = [ @@ -41,6 +44,12 @@ class LocalLibraryProviderTest(unittest.TestCase): uri='local:track:path3', name='track3', artists=[artists[3]], album=albums[2], date='2003', length=4000, track_no=3), + Track( + uri='local:track:path4', name='track4', genre='genre1', + album=albums[3], length=4000, composers=[artists[4]]), + Track( + uri='local:track:path5', name='track5', genre='genre2', + album=albums[3], length=4000, performers=[artists[5]]), ] config = { @@ -108,12 +117,21 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.find_exact(artist=['unknown artist']) self.assertEqual(list(result[0].tracks), []) - result = self.library.find_exact(album=['unknown artist']) + result = self.library.find_exact(composer=['unknown composer']) + self.assertEqual(list(result[0].tracks), []) + + result = self.library.find_exact(performer=['unknown performer']) + self.assertEqual(list(result[0].tracks), []) + + result = self.library.find_exact(album=['unknown album']) self.assertEqual(list(result[0].tracks), []) result = self.library.find_exact(date=['1990']) self.assertEqual(list(result[0].tracks), []) + result = self.library.find_exact(genre=['unknown genre']) + self.assertEqual(list(result[0].tracks), []) + result = self.library.find_exact(track_no=[9]) self.assertEqual(list(result[0].tracks), []) @@ -146,6 +164,14 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.find_exact(artist=['artist2']) self.assertEqual(list(result[0].tracks), self.tracks[1:2]) + def test_find_exact_composer(self): + result = self.library.find_exact(composer=['artist5']) + self.assertEqual(list(result[0].tracks), self.tracks[3:4]) + + def test_find_exact_performer(self): + result = self.library.find_exact(performer=['artist6']) + self.assertEqual(list(result[0].tracks), self.tracks[4:5]) + def test_find_exact_album(self): result = self.library.find_exact(album=['album1']) self.assertEqual(list(result[0].tracks), self.tracks[:1]) @@ -173,6 +199,13 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.find_exact(track_no=[2]) self.assertEqual(list(result[0].tracks), self.tracks[1:2]) + def test_find_exact_genre(self): + result = self.library.find_exact(genre=['genre1']) + self.assertEqual(list(result[0].tracks), self.tracks[3:4]) + + result = self.library.find_exact(genre=['genre2']) + self.assertEqual(list(result[0].tracks), self.tracks[4:5]) + def test_find_exact_date(self): result = self.library.find_exact(date=['2001']) self.assertEqual(list(result[0].tracks), []) @@ -206,6 +239,21 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.find_exact(any=['artist3']) self.assertEqual(list(result[0].tracks), self.tracks[2:3]) + # Matches on track composer + result = self.library.find_exact(any=['artist5']) + self.assertEqual(list(result[0].tracks), self.tracks[3:4]) + + # Matches on track performer + result = self.library.find_exact(any=['artist6']) + self.assertEqual(list(result[0].tracks), self.tracks[4:5]) + + # Matches on track genre + result = self.library.find_exact(any=['genre1']) + self.assertEqual(list(result[0].tracks), self.tracks[3:4]) + + result = self.library.find_exact(any=['genre2']) + self.assertEqual(list(result[0].tracks), self.tracks[4:5]) + # Matches on track year result = self.library.find_exact(any=['2002']) self.assertEqual(list(result[0].tracks), self.tracks[1:2]) @@ -222,6 +270,12 @@ class LocalLibraryProviderTest(unittest.TestCase): test = lambda: self.library.find_exact(artist=['']) self.assertRaises(LookupError, test) + test = lambda: self.library.find_exact(composer=['']) + self.assertRaises(LookupError, test) + + test = lambda: self.library.find_exact(performer=['']) + self.assertRaises(LookupError, test) + test = lambda: self.library.find_exact(track=['']) self.assertRaises(LookupError, test) @@ -231,6 +285,9 @@ class LocalLibraryProviderTest(unittest.TestCase): test = lambda: self.library.find_exact(track_no=[]) self.assertRaises(LookupError, test) + test = lambda: self.library.find_exact(genre=['']) + self.assertRaises(LookupError, test) + test = lambda: self.library.find_exact(date=['']) self.assertRaises(LookupError, test) @@ -244,12 +301,21 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.search(artist=['unknown artist']) self.assertEqual(list(result[0].tracks), []) + result = self.library.search(composer=['unknown composer']) + self.assertEqual(list(result[0].tracks), []) + + result = self.library.search(performer=['unknown performer']) + self.assertEqual(list(result[0].tracks), []) + result = self.library.search(album=['unknown artist']) self.assertEqual(list(result[0].tracks), []) result = self.library.search(track_no=[9]) self.assertEqual(list(result[0].tracks), []) + result = self.library.search(genre=['unknown genre']) + self.assertEqual(list(result[0].tracks), []) + result = self.library.search(date=['unknown date']) self.assertEqual(list(result[0].tracks), []) @@ -293,6 +359,14 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.search(albumartist=['Tist3']) self.assertEqual(list(result[0].tracks), [self.tracks[2]]) + def test_search_composer(self): + result = self.library.search(composer=['Tist5']) + self.assertEqual(list(result[0].tracks), self.tracks[3:4]) + + def test_search_performer(self): + result = self.library.search(performer=['Tist6']) + self.assertEqual(list(result[0].tracks), self.tracks[4:5]) + def test_search_album(self): result = self.library.search(album=['Bum1']) self.assertEqual(list(result[0].tracks), self.tracks[:1]) @@ -300,6 +374,13 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.search(album=['Bum2']) self.assertEqual(list(result[0].tracks), self.tracks[1:2]) + def test_search_genre(self): + result = self.library.search(genre=['Enre1']) + self.assertEqual(list(result[0].tracks), self.tracks[3:4]) + + result = self.library.search(genre=['Enre2']) + self.assertEqual(list(result[0].tracks), self.tracks[4:5]) + def test_search_date(self): result = self.library.search(date=['2001']) self.assertEqual(list(result[0].tracks), self.tracks[:1]) @@ -325,6 +406,14 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.search(any=['Tist1']) self.assertEqual(list(result[0].tracks), self.tracks[:1]) + # Matches on track composer + result = self.library.search(any=['Tist5']) + self.assertEqual(list(result[0].tracks), self.tracks[3:4]) + + # Matches on track performer + result = self.library.search(any=['Tist6']) + self.assertEqual(list(result[0].tracks), self.tracks[4:5]) + # Matches on track result = self.library.search(any=['Rack1']) self.assertEqual(list(result[0].tracks), self.tracks[:1]) @@ -340,6 +429,13 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.search(any=['Tist3']) self.assertEqual(list(result[0].tracks), self.tracks[2:3]) + # Matches on track genre + result = self.library.search(any=['Enre1']) + self.assertEqual(list(result[0].tracks), self.tracks[3:4]) + + result = self.library.search(any=['Enre2']) + self.assertEqual(list(result[0].tracks), self.tracks[4:5]) + # Matches on URI result = self.library.search(any=['TH1']) self.assertEqual(list(result[0].tracks), self.tracks[:1]) @@ -352,12 +448,21 @@ class LocalLibraryProviderTest(unittest.TestCase): test = lambda: self.library.search(artist=['']) self.assertRaises(LookupError, test) + test = lambda: self.library.search(composer=['']) + self.assertRaises(LookupError, test) + + test = lambda: self.library.search(performer=['']) + self.assertRaises(LookupError, test) + test = lambda: self.library.search(track=['']) self.assertRaises(LookupError, test) test = lambda: self.library.search(album=['']) self.assertRaises(LookupError, test) + test = lambda: self.library.search(genre=['']) + self.assertRaises(LookupError, test) + test = lambda: self.library.search(date=['']) self.assertRaises(LookupError, test) diff --git a/tests/data/library_tag_cache b/tests/data/library_tag_cache index e9e87c1b..02cbf927 100644 --- a/tests/data/library_tag_cache +++ b/tests/data/library_tag_cache @@ -28,4 +28,18 @@ Album: album3 Date: 2003 Track: 3 Time: 4 +key: key4 +file: /path4 +Composer: artist5 +Title: track4 +Album: album4 +Genre: genre1 +Time: 4 +key: key5 +file: /path5 +Performer: artist6 +Title: track5 +Album: album4 +Genre: genre2 +Time: 4 songList end diff --git a/tests/models_test.py b/tests/models_test.py index afd1858b..9f43e624 100644 --- a/tests/models_test.py +++ b/tests/models_test.py @@ -450,12 +450,14 @@ class TrackTest(unittest.TestCase): def test_repr_without_artists(self): self.assertEquals( - "Track(artists=[], name=u'name', uri=u'uri')", + "Track(artists=[], composers=[], name=u'name', " + "performers=[], uri=u'uri')", repr(Track(uri='uri', name='name'))) def test_repr_with_artists(self): self.assertEquals( - "Track(artists=[Artist(name=u'foo')], name=u'name', uri=u'uri')", + "Track(artists=[Artist(name=u'foo')], composers=[], name=u'name', " + "performers=[], uri=u'uri')", repr(Track(uri='uri', name='name', artists=[Artist(name='foo')]))) def test_serialize_without_artists(self): @@ -670,7 +672,8 @@ class TlTrackTest(unittest.TestCase): def test_repr(self): self.assertEquals( - "TlTrack(tlid=123, track=Track(artists=[], uri=u'uri'))", + "TlTrack(tlid=123, track=Track(artists=[], composers=[], " + "performers=[], uri=u'uri'))", repr(TlTrack(tlid=123, track=Track(uri='uri')))) def test_serialize(self): @@ -804,8 +807,8 @@ class PlaylistTest(unittest.TestCase): def test_repr_with_tracks(self): self.assertEquals( - "Playlist(name=u'name', tracks=[Track(artists=[], name=u'foo')], " - "uri=u'uri')", + "Playlist(name=u'name', tracks=[Track(artists=[], composers=[], " + "name=u'foo', performers=[])], uri=u'uri')", repr(Playlist(uri='uri', name='name', tracks=[Track(name='foo')]))) def test_serialize_without_tracks(self):