From 04d9fa667b2493eb198762850a2017e89f52f043 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 2 Nov 2013 19:25:06 +0100 Subject: [PATCH 01/17] deps: Don't strip last dir from dependency path --- mopidy/utils/deps.py | 6 +++--- tests/utils/deps_test.py | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/mopidy/utils/deps.py b/mopidy/utils/deps.py index 99a22d3c..a1adf0a7 100644 --- a/mopidy/utils/deps.py +++ b/mopidy/utils/deps.py @@ -41,7 +41,7 @@ def _format_dependency(dep_info): lines.append('%s: not found' % dep_info['name']) else: if 'path' in dep_info: - source = ' from %s' % os.path.dirname(dep_info['path']) + source = ' from %s' % dep_info['path'] else: source = '' lines.append('%s: %s%s' % ( @@ -75,7 +75,7 @@ def python_info(): 'name': 'Python', 'version': '%s %s' % ( platform.python_implementation(), platform.python_version()), - 'path': platform.__file__, + 'path': os.path.dirname(platform.__file__), } @@ -127,7 +127,7 @@ def gstreamer_info(): return { 'name': 'GStreamer', 'version': '.'.join(map(str, gst.get_gst_version())), - 'path': gst.__file__, + 'path': os.path.dirname(gst.__file__), 'other': '\n'.join(other), } diff --git a/tests/utils/deps_test.py b/tests/utils/deps_test.py index 4ad04ed7..2a25c095 100644 --- a/tests/utils/deps_test.py +++ b/tests/utils/deps_test.py @@ -20,7 +20,7 @@ class DepsTest(unittest.TestCase): lambda: dict(name='Platform', version='Loonix 4.0.1'), lambda: dict( name='Pykka', version='1.1', - path='/foo/bar/baz.py', other='Quux'), + path='/foo/bar', other='Quux'), lambda: dict(name='Foo'), lambda: dict(name='Mopidy', version='0.13', dependencies=[ dict(name='pylast', version='0.5', dependencies=[ @@ -58,6 +58,7 @@ class DepsTest(unittest.TestCase): self.assertIn(platform.python_implementation(), result['version']) self.assertIn(platform.python_version(), result['version']) self.assertIn('python', result['path']) + self.assertNotIn('platform.py', result['path']) def test_gstreamer_info(self): result = deps.gstreamer_info() @@ -66,6 +67,7 @@ class DepsTest(unittest.TestCase): self.assertEquals( '.'.join(map(str, gst.get_gst_version())), result['version']) self.assertIn('gst', result['path']) + self.assertNotIn('__init__.py', result['path']) self.assertIn('Python wrapper: gst-python', result['other']) self.assertIn( '.'.join(map(str, gst.get_pygst_version())), result['other']) From efc9fc75b5e6179d9712653c15aeb6f67b753174 Mon Sep 17 00:00:00 2001 From: Lasse Bigum Date: Thu, 31 Oct 2013 21:45:02 +0100 Subject: [PATCH 02/17] Fix track_no --- mopidy/backends/local/library.py | 22 ++++++++++------------ tests/backends/local/library_test.py | 14 +++++++------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/mopidy/backends/local/library.py b/mopidy/backends/local/library.py index 2ff0e6d1..2a56098d 100644 --- a/mopidy/backends/local/library.py +++ b/mopidy/backends/local/library.py @@ -60,10 +60,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): values = [values] # FIXME this is bound to be slow for large libraries for value in values: - if field == 'track_no': - q = value - else: - q = value.strip() + q = value.strip() uri_filter = lambda t: q == t.uri track_filter = lambda t: q == t.name @@ -73,7 +70,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): albumartist_filter = lambda t: any([ q == a.name for a in getattr(t.album, 'artists', [])]) - track_no_filter = lambda t: q == t.track_no + track_no_filter = lambda t: int(q) == t.track_no date_filter = lambda t: q == t.date any_filter = lambda t: ( uri_filter(t) or @@ -81,7 +78,6 @@ class LocalLibraryProvider(base.BaseLibraryProvider): album_filter(t) or artist_filter(t) or albumartist_filter(t) or - track_no_filter(t) or date_filter(t)) if field == 'uri': @@ -92,8 +88,14 @@ class LocalLibraryProvider(base.BaseLibraryProvider): result_tracks = filter(album_filter, result_tracks) elif field == 'artist': result_tracks = filter(artist_filter, result_tracks) + #import logging + #logger = logging.getLogger('mopidy.backends.local') + #logger.debug("==find_exact=artist - q: {} - tracks: {}".format(q, result_tracks)) elif field == 'albumartist': result_tracks = filter(albumartist_filter, result_tracks) + #import logging + #logger = logging.getLogger('mopidy.backends.local') + #logger.debug("==find_exact=albumartist - q: {} - tracks: {}".format(q, result_tracks)) elif field == 'track_no': result_tracks = filter(track_no_filter, result_tracks) elif field == 'date': @@ -118,10 +120,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): values = [values] # FIXME this is bound to be slow for large libraries for value in values: - if field == 'track_no': - q = value - else: - q = value.strip().lower() + q = value.strip().lower() uri_filter = lambda t: q in t.uri.lower() track_filter = lambda t: q in t.name.lower() @@ -132,7 +131,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): albumartist_filter = lambda t: any([ q in a.name.lower() for a in getattr(t.album, 'artists', [])]) - track_no_filter = lambda t: q == t.track_no + track_no_filter = lambda t: int(q) == t.track_no date_filter = lambda t: t.date and t.date.startswith(q) any_filter = lambda t: ( uri_filter(t) or @@ -140,7 +139,6 @@ class LocalLibraryProvider(base.BaseLibraryProvider): album_filter(t) or artist_filter(t) or albumartist_filter(t) or - track_no_filter(t) or date_filter(t)) if field == 'uri': diff --git a/tests/backends/local/library_test.py b/tests/backends/local/library_test.py index 1cb07451..9067c134 100644 --- a/tests/backends/local/library_test.py +++ b/tests/backends/local/library_test.py @@ -114,7 +114,7 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.find_exact(date=['1990']) self.assertEqual(list(result[0].tracks), []) - result = self.library.find_exact(track_no=[9]) + result = self.library.find_exact(track_no=['9']) self.assertEqual(list(result[0].tracks), []) result = self.library.find_exact(uri=['fake uri']) @@ -167,10 +167,10 @@ class LocalLibraryProviderTest(unittest.TestCase): self.assertEqual(list(result[0].tracks), [self.tracks[2]]) def test_find_exact_track_no(self): - result = self.library.find_exact(track_no=[1]) + result = self.library.find_exact(track_no=['1']) self.assertEqual(list(result[0].tracks), self.tracks[:1]) - result = self.library.find_exact(track_no=[2]) + result = self.library.find_exact(track_no=['2']) self.assertEqual(list(result[0].tracks), self.tracks[1:2]) def test_find_exact_date(self): @@ -228,7 +228,7 @@ class LocalLibraryProviderTest(unittest.TestCase): test = lambda: self.library.find_exact(album=['']) self.assertRaises(LookupError, test) - test = lambda: self.library.find_exact(track_no=[]) + test = lambda: self.library.find_exact(track_no=['']) self.assertRaises(LookupError, test) test = lambda: self.library.find_exact(date=['']) @@ -247,7 +247,7 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.search(album=['unknown artist']) self.assertEqual(list(result[0].tracks), []) - result = self.library.search(track_no=[9]) + result = self.library.search(track_no=['9']) self.assertEqual(list(result[0].tracks), []) result = self.library.search(date=['unknown date']) @@ -314,10 +314,10 @@ class LocalLibraryProviderTest(unittest.TestCase): self.assertEqual(list(result[0].tracks), self.tracks[1:2]) def test_search_track_no(self): - result = self.library.search(track_no=[1]) + result = self.library.search(track_no=['1']) self.assertEqual(list(result[0].tracks), self.tracks[:1]) - result = self.library.search(track_no=[2]) + result = self.library.search(track_no=['2']) self.assertEqual(list(result[0].tracks), self.tracks[1:2]) def test_search_any(self): From e7746dac1b5d6a536755cad32e0a2a277f207217 Mon Sep 17 00:00:00 2001 From: Lasse Bigum Date: Sat, 2 Nov 2013 03:25:57 +0100 Subject: [PATCH 03/17] Remove debug, make track_no more robust --- mopidy/backends/local/library.py | 26 ++++++++++++++++---------- tests/backends/local/library_test.py | 6 ++++++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/mopidy/backends/local/library.py b/mopidy/backends/local/library.py index 2a56098d..d2af41fc 100644 --- a/mopidy/backends/local/library.py +++ b/mopidy/backends/local/library.py @@ -21,6 +21,12 @@ class LocalLibraryProvider(base.BaseLibraryProvider): self._tag_cache_file = self.backend.config['local']['tag_cache_file'] self.refresh() + def _convert_to_int(self, string): + try: + return int(string) + except ValueError: + return object() + def refresh(self, uri=None): logger.debug( 'Loading local tracks from %s using %s', @@ -60,7 +66,10 @@ class LocalLibraryProvider(base.BaseLibraryProvider): values = [values] # FIXME this is bound to be slow for large libraries for value in values: - q = value.strip() + if field == 'track_no': + q = self._convert_to_int(value) + else: + q = value.strip() uri_filter = lambda t: q == t.uri track_filter = lambda t: q == t.name @@ -70,7 +79,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): albumartist_filter = lambda t: any([ q == a.name for a in getattr(t.album, 'artists', [])]) - track_no_filter = lambda t: int(q) == t.track_no + track_no_filter = lambda t: q == t.track_no date_filter = lambda t: q == t.date any_filter = lambda t: ( uri_filter(t) or @@ -88,14 +97,8 @@ class LocalLibraryProvider(base.BaseLibraryProvider): result_tracks = filter(album_filter, result_tracks) elif field == 'artist': result_tracks = filter(artist_filter, result_tracks) - #import logging - #logger = logging.getLogger('mopidy.backends.local') - #logger.debug("==find_exact=artist - q: {} - tracks: {}".format(q, result_tracks)) elif field == 'albumartist': result_tracks = filter(albumartist_filter, result_tracks) - #import logging - #logger = logging.getLogger('mopidy.backends.local') - #logger.debug("==find_exact=albumartist - q: {} - tracks: {}".format(q, result_tracks)) elif field == 'track_no': result_tracks = filter(track_no_filter, result_tracks) elif field == 'date': @@ -120,7 +123,10 @@ class LocalLibraryProvider(base.BaseLibraryProvider): values = [values] # FIXME this is bound to be slow for large libraries for value in values: - q = value.strip().lower() + if field == 'track_no': + q = self._convert_to_int(value) + else: + q = value.strip().lower() uri_filter = lambda t: q in t.uri.lower() track_filter = lambda t: q in t.name.lower() @@ -131,7 +137,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): albumartist_filter = lambda t: any([ q in a.name.lower() for a in getattr(t.album, 'artists', [])]) - track_no_filter = lambda t: int(q) == t.track_no + track_no_filter = lambda t: q == t.track_no date_filter = lambda t: t.date and t.date.startswith(q) any_filter = lambda t: ( uri_filter(t) or diff --git a/tests/backends/local/library_test.py b/tests/backends/local/library_test.py index 9067c134..061895d8 100644 --- a/tests/backends/local/library_test.py +++ b/tests/backends/local/library_test.py @@ -117,6 +117,9 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.find_exact(track_no=['9']) self.assertEqual(list(result[0].tracks), []) + result = self.library.find_exact(track_no=['no_match']) + self.assertEqual(list(result[0].tracks), []) + result = self.library.find_exact(uri=['fake uri']) self.assertEqual(list(result[0].tracks), []) @@ -250,6 +253,9 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.search(track_no=['9']) self.assertEqual(list(result[0].tracks), []) + result = self.library.search(track_no=['no_match']) + self.assertEqual(list(result[0].tracks), []) + result = self.library.search(date=['unknown date']) self.assertEqual(list(result[0].tracks), []) From 7c414d4abc7a4478ccaddc092e1039c779de6e79 Mon Sep 17 00:00:00 2001 From: Lasse Bigum Date: Thu, 31 Oct 2013 20:15:13 +0100 Subject: [PATCH 04/17] Support 'list albumartist' --- mopidy/frontends/mpd/protocol/music_db.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/mopidy/frontends/mpd/protocol/music_db.py b/mopidy/frontends/mpd/protocol/music_db.py index 6dd43d68..1c737520 100644 --- a/mopidy/frontends/mpd/protocol/music_db.py +++ b/mopidy/frontends/mpd/protocol/music_db.py @@ -127,7 +127,7 @@ def findadd(context, mpd_query): @handle_request( - r'^list "?(?P([Aa]rtist|[Aa]lbum|[Dd]ate|[Gg]enre))"?' + r'^list "?(?P([Aa]rtist|[Aa]lbumartist|[Aa]lbum|[Dd]ate|[Gg]enre))"?' r'( (?P.*))?$') def list_(context, field, mpd_query=None): """ @@ -136,7 +136,7 @@ def list_(context, field, mpd_query=None): ``list {TYPE} [ARTIST]`` Lists all tags of the specified type. ``TYPE`` should be ``album``, - ``artist``, ``date``, or ``genre``. + ``artist``, ``albumartist``, ``date``, or ``genre``. ``ARTIST`` is an optional parameter when type is ``album``, ``date``, or ``genre``. This filters the result list by an artist. @@ -218,6 +218,8 @@ def list_(context, field, mpd_query=None): return if field == 'artist': return _list_artist(context, query) + if field == 'albumartist': + return _list_albumartist(context, query) elif field == 'album': return _list_album(context, query) elif field == 'date': @@ -236,6 +238,18 @@ def _list_artist(context, query): return artists +def _list_albumartist(context, query): + import logging + logger = logging.getLogger('mopidy.backends.local') + albumartists = set() + results = context.core.library.find_exact(**query).get() + for track in _get_tracks(results): + for artist in track.album.artists: + if artist.name: + albumartists.add(('AlbumArtist', artist.name)) + return albumartists + + def _list_album(context, query): albums = set() results = context.core.library.find_exact(**query).get() From fd213f2d785f22958dedebe6a046757cf38269e2 Mon Sep 17 00:00:00 2001 From: Lasse Bigum Date: Thu, 31 Oct 2013 22:00:43 +0100 Subject: [PATCH 05/17] Add tests for albumartist --- tests/frontends/mpd/protocol/music_db_test.py | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tests/frontends/mpd/protocol/music_db_test.py b/tests/frontends/mpd/protocol/music_db_test.py index 0114340b..60c30372 100644 --- a/tests/frontends/mpd/protocol/music_db_test.py +++ b/tests/frontends/mpd/protocol/music_db_test.py @@ -398,6 +398,66 @@ class MusicDatabaseListTest(protocol.BaseTestCase): self.assertNotInResponse('Artist: ') self.assertInResponse('OK') + ### Albumartist + + def test_list_albumartist_with_quotes(self): + self.sendRequest('list "albumartist"') + self.assertInResponse('OK') + + def test_list_albumartist_without_quotes(self): + self.sendRequest('list albumartist') + self.assertInResponse('OK') + + def test_list_albumartist_without_quotes_and_capitalized(self): + self.sendRequest('list Albumartist') + self.assertInResponse('OK') + + def test_list_albumartist_with_query_of_one_token(self): + self.sendRequest('list "albumartist" "anartist"') + self.assertEqualResponse( + 'ACK [2@0] {list} should be "Album" for 3 arguments') + + def test_list_albumartist_with_unknown_field_in_query_returns_ack(self): + self.sendRequest('list "albumartist" "foo" "bar"') + self.assertEqualResponse('ACK [2@0] {list} not able to parse args') + + def test_list_albumartist_by_artist(self): + self.sendRequest('list "albumartist" "artist" "anartist"') + self.assertInResponse('OK') + + def test_list_albumartist_by_album(self): + self.sendRequest('list "albumartist" "album" "analbum"') + self.assertInResponse('OK') + + def test_list_albumartist_by_full_date(self): + self.sendRequest('list "albumartist" "date" "2001-01-01"') + self.assertInResponse('OK') + + def test_list_albumartist_by_year(self): + self.sendRequest('list "albumartist" "date" "2001"') + self.assertInResponse('OK') + + def test_list_albumartist_by_genre(self): + self.sendRequest('list "albumartist" "genre" "agenre"') + self.assertInResponse('OK') + + def test_list_albumartist_by_artist_and_album(self): + self.sendRequest( + 'list "albumartist" "artist" "anartist" "album" "analbum"') + self.assertInResponse('OK') + + def test_list_albumartist_without_filter_value(self): + self.sendRequest('list "albumartist" "artist" ""') + self.assertInResponse('OK') + + def test_list_albumartist_should_not_return_artists_without_names(self): + self.backend.library.dummy_find_exact_result = SearchResult( + tracks=[Track(album=Album(artists=[Artist(name='')]))]) + + self.sendRequest('list "albumartist"') + self.assertNotInResponse('Artist: ') + self.assertInResponse('OK') + ### Album def test_list_album_with_quotes(self): From 86f18935fe8ef5e6592e072e19c1aa644fb2c916 Mon Sep 17 00:00:00 2001 From: Lasse Bigum Date: Sat, 2 Nov 2013 02:43:12 +0100 Subject: [PATCH 06/17] Fix flake8 errors and add a few more tests --- mopidy/frontends/mpd/protocol/music_db.py | 6 ++---- tests/backends/local/library_test.py | 12 ++++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/mopidy/frontends/mpd/protocol/music_db.py b/mopidy/frontends/mpd/protocol/music_db.py index 1c737520..972f5840 100644 --- a/mopidy/frontends/mpd/protocol/music_db.py +++ b/mopidy/frontends/mpd/protocol/music_db.py @@ -127,8 +127,8 @@ def findadd(context, mpd_query): @handle_request( - r'^list "?(?P([Aa]rtist|[Aa]lbumartist|[Aa]lbum|[Dd]ate|[Gg]enre))"?' - r'( (?P.*))?$') + r'^list "?(?P([Aa]rtist|[Aa]lbumartist|[Aa]lbum|[Dd]ate|' + r'[Gg]enre))"?( (?P.*))?$') def list_(context, field, mpd_query=None): """ *musicpd.org, music database section:* @@ -239,8 +239,6 @@ def _list_artist(context, query): def _list_albumartist(context, query): - import logging - logger = logging.getLogger('mopidy.backends.local') albumartists = set() results = context.core.library.find_exact(**query).get() for track in _get_tracks(results): diff --git a/tests/backends/local/library_test.py b/tests/backends/local/library_test.py index 061895d8..0e33b412 100644 --- a/tests/backends/local/library_test.py +++ b/tests/backends/local/library_test.py @@ -108,6 +108,9 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.find_exact(artist=['unknown artist']) self.assertEqual(list(result[0].tracks), []) + result = self.library.find_exact(albumartist=['unknown albumartist']) + self.assertEqual(list(result[0].tracks), []) + result = self.library.find_exact(album=['unknown artist']) self.assertEqual(list(result[0].tracks), []) @@ -225,6 +228,9 @@ class LocalLibraryProviderTest(unittest.TestCase): test = lambda: self.library.find_exact(artist=['']) self.assertRaises(LookupError, test) + test = lambda: self.library.find_exact(albumartist=['']) + self.assertRaises(LookupError, test) + test = lambda: self.library.find_exact(track=['']) self.assertRaises(LookupError, test) @@ -247,6 +253,9 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.search(artist=['unknown artist']) self.assertEqual(list(result[0].tracks), []) + result = self.library.search(albumartist=['unknown albumartist']) + self.assertEqual(list(result[0].tracks), []) + result = self.library.search(album=['unknown artist']) self.assertEqual(list(result[0].tracks), []) @@ -358,6 +367,9 @@ class LocalLibraryProviderTest(unittest.TestCase): test = lambda: self.library.search(artist=['']) self.assertRaises(LookupError, test) + test = lambda: self.library.search(albumartist=['']) + self.assertRaises(LookupError, test) + test = lambda: self.library.search(track=['']) self.assertRaises(LookupError, test) From 0df84b85d085f4220ccd3d1aaff3b6e1f21e240a Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 2 Nov 2013 22:00:35 +0100 Subject: [PATCH 07/17] mpd: Check if track.album exists before using it --- mopidy/frontends/mpd/protocol/music_db.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mopidy/frontends/mpd/protocol/music_db.py b/mopidy/frontends/mpd/protocol/music_db.py index 972f5840..e70815f8 100644 --- a/mopidy/frontends/mpd/protocol/music_db.py +++ b/mopidy/frontends/mpd/protocol/music_db.py @@ -242,9 +242,10 @@ def _list_albumartist(context, query): albumartists = set() results = context.core.library.find_exact(**query).get() for track in _get_tracks(results): - for artist in track.album.artists: - if artist.name: - albumartists.add(('AlbumArtist', artist.name)) + if track.album: + for artist in track.album.artists: + if artist.name: + albumartists.add(('AlbumArtist', artist.name)) return albumartists From f2384252a21c06dce15ac27e208ad3a34324fcac Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 2 Nov 2013 22:05:27 +0100 Subject: [PATCH 08/17] travis: Ignore in apt-cache output --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b793e530..8e991c3e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ install: - "wget -O - http://apt.mopidy.com/mopidy.gpg | sudo apt-key add -" - "sudo wget -O /etc/apt/sources.list.d/mopidy.list http://apt.mopidy.com/mopidy.list" - "sudo apt-get update || true" - - "sudo apt-get install $(apt-cache depends mopidy | awk '$2 !~ /mopidy/ {print $2}')" + - "sudo apt-get install $(apt-cache depends mopidy | awk '$2 !~ /mopidy|python:any/ {print $2}')" - "pip install coveralls flake8" before_script: From 51ffcb8609daec4651e83cc381e788fd7d5541c1 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 2 Nov 2013 22:07:03 +0100 Subject: [PATCH 09/17] docs: Update changelog --- docs/changelog.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index e45381a7..0e560f3d 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,6 +4,18 @@ Changelog This changelog is used to track all major changes to Mopidy. +v0.17.0 (UNRELEASED) +==================== + +**Local backend** + +- Fix search filtering by track number. + +**MPD frontend** + +- Add support for ``list "albumartist" ...``. + + v0.16.0 (2013-10-27) ==================== From 24944bd8e3ebf91a7adc7d582f1f44dc65f9c358 Mon Sep 17 00:00:00 2001 From: Lasse Bigum Date: Thu, 31 Oct 2013 22:33:48 +0100 Subject: [PATCH 10/17] Split artist and albumartist dependency, update tests based on this --- mopidy/backends/local/translator.py | 1 - mopidy/frontends/mpd/translator.py | 5 ++--- tests/backends/local/library_test.py | 15 ++++++++++++-- tests/backends/local/translator_test.py | 26 +++++++++++++------------ tests/data/advanced_tag_cache | 5 +++++ tests/data/library_tag_cache | 10 ++++++++++ tests/data/simple_tag_cache | 1 + tests/data/utf8_tag_cache | 1 + 8 files changed, 46 insertions(+), 18 deletions(-) diff --git a/mopidy/backends/local/translator.py b/mopidy/backends/local/translator.py index 7cd46fbb..3a02a8af 100644 --- a/mopidy/backends/local/translator.py +++ b/mopidy/backends/local/translator.py @@ -120,7 +120,6 @@ def _convert_mpd_data(data, tracks): if 'artist' in data: artist_kwargs['name'] = data['artist'] - albumartist_kwargs['name'] = data['artist'] if 'albumartist' in data: albumartist_kwargs['name'] = data['albumartist'] diff --git a/mopidy/frontends/mpd/translator.py b/mopidy/frontends/mpd/translator.py index 9b331395..d25cad44 100644 --- a/mopidy/frontends/mpd/translator.py +++ b/mopidy/frontends/mpd/translator.py @@ -44,9 +44,6 @@ def track_to_mpd_format(track, position=None): track.track_no, track.album.num_tracks))) else: result.append(('Track', track.track_no)) - if track.album is not None and track.album.artists: - artists = artists_to_mpd_format(track.album.artists) - result.append(('AlbumArtist', artists)) if position is not None and tlid is not None: result.append(('Pos', position)) result.append(('Id', tlid)) @@ -55,6 +52,8 @@ def track_to_mpd_format(track, position=None): # FIXME don't use first and best artist? # FIXME don't duplicate following code? if track.album is not None and track.album.artists: + artists = artists_to_mpd_format(track.album.artists) + result.append(('AlbumArtist', artists)) artists = filter( lambda a: a.musicbrainz_id is not None, track.album.artists) if artists: diff --git a/tests/backends/local/library_test.py b/tests/backends/local/library_test.py index 0e33b412..af09b4bb 100644 --- a/tests/backends/local/library_test.py +++ b/tests/backends/local/library_test.py @@ -26,6 +26,7 @@ class LocalLibraryProviderTest(unittest.TestCase): Album(name='album1', artists=[artists[0]]), Album(name='album2', artists=[artists[1]]), Album(name='album3', artists=[artists[2]]), + Album(name='album4'), ] tracks = [ @@ -41,6 +42,10 @@ 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', + artists=[artists[2]], album=albums[3], + date='2004', length=60000, track_no=4), ] config = { @@ -152,6 +157,12 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.find_exact(artist=['artist2']) self.assertEqual(list(result[0].tracks), self.tracks[1:2]) + import logging + logger = logging.getLogger('mopidy.backends.local') + logger.debug("==TEST= tracks: {}".format(self.tracks[2:3])) + result = self.library.find_exact(artist=['artist3']) + self.assertEqual(list(result[0].tracks), self.tracks[3:4]) + def test_find_exact_album(self): result = self.library.find_exact(album=['album1']) self.assertEqual(list(result[0].tracks), self.tracks[:1]) @@ -210,7 +221,7 @@ class LocalLibraryProviderTest(unittest.TestCase): # Matches on track album artists result = self.library.find_exact(any=['artist3']) - self.assertEqual(list(result[0].tracks), self.tracks[2:3]) + self.assertEqual(list(result[0].tracks), [self.tracks[3], self.tracks[2]]) # Matches on track year result = self.library.find_exact(any=['2002']) @@ -353,7 +364,7 @@ class LocalLibraryProviderTest(unittest.TestCase): # Matches on track album artists result = self.library.search(any=['Tist3']) - self.assertEqual(list(result[0].tracks), self.tracks[2:3]) + self.assertEqual(list(result[0].tracks), [self.tracks[3], self.tracks[2]]) # Matches on URI result = self.library.search(any=['TH1']) diff --git a/tests/backends/local/translator_test.py b/tests/backends/local/translator_test.py index 5ed07fca..1719500c 100644 --- a/tests/backends/local/translator_test.py +++ b/tests/backends/local/translator_test.py @@ -93,28 +93,30 @@ class URItoM3UTest(unittest.TestCase): expected_artists = [Artist(name='name')] expected_albums = [ - Album(name='albumname', artists=expected_artists, num_tracks=2)] + Album(name='albumname', artists=expected_artists, num_tracks=2), + Album(name='albumname', num_tracks=2) + ] expected_tracks = [] -def generate_track(path, ident): +def generate_track(path, ident, album_id): uri = 'local:track:%s' % path track = Track( uri=uri, name='trackname', artists=expected_artists, - album=expected_albums[0], track_no=1, date='2006', length=4000, + album=expected_albums[album_id], track_no=1, date='2006', length=4000, last_modified=1272319626) expected_tracks.append(track) -generate_track('song1.mp3', 6) -generate_track('song2.mp3', 7) -generate_track('song3.mp3', 8) -generate_track('subdir1/song4.mp3', 2) -generate_track('subdir1/song5.mp3', 3) -generate_track('subdir2/song6.mp3', 4) -generate_track('subdir2/song7.mp3', 5) -generate_track('subdir1/subsubdir/song8.mp3', 0) -generate_track('subdir1/subsubdir/song9.mp3', 1) +generate_track('song1.mp3', 6, 0) +generate_track('song2.mp3', 7, 0) +generate_track('song3.mp3', 8, 1) +generate_track('subdir1/song4.mp3', 2, 0) +generate_track('subdir1/song5.mp3', 3, 0) +generate_track('subdir2/song6.mp3', 4, 1) +generate_track('subdir2/song7.mp3', 5, 1) +generate_track('subdir1/subsubdir/song8.mp3', 0, 0) +generate_track('subdir1/subsubdir/song9.mp3', 1, 1) class MPDTagCacheToTracksTest(unittest.TestCase): diff --git a/tests/data/advanced_tag_cache b/tests/data/advanced_tag_cache index 3288275f..be299fb6 100644 --- a/tests/data/advanced_tag_cache +++ b/tests/data/advanced_tag_cache @@ -11,6 +11,7 @@ key: song8.mp3 file: subdir1/subsubdir/song8.mp3 Time: 4 Artist: name +AlbumArtist: name Title: trackname Album: albumname Track: 1/2 @@ -32,6 +33,7 @@ key: song4.mp3 file: subdir1/song4.mp3 Time: 4 Artist: name +AlbumArtist: name Title: trackname Album: albumname Track: 1/2 @@ -41,6 +43,7 @@ key: song5.mp3 file: subdir1/song5.mp3 Time: 4 Artist: name +AlbumArtist: name Title: trackname Album: albumname Track: 1/2 @@ -76,6 +79,7 @@ key: song1.mp3 file: /song1.mp3 Time: 4 Artist: name +AlbumArtist: name Title: trackname Album: albumname Track: 1/2 @@ -85,6 +89,7 @@ key: song2.mp3 file: /song2.mp3 Time: 4 Artist: name +AlbumArtist: name Title: trackname Album: albumname Track: 1/2 diff --git a/tests/data/library_tag_cache b/tests/data/library_tag_cache index e9e87c1b..904c5e57 100644 --- a/tests/data/library_tag_cache +++ b/tests/data/library_tag_cache @@ -6,6 +6,7 @@ songList begin key: key1 file: /path1 Artist: artist1 +AlbumArtist: artist1 Title: track1 Album: album1 Date: 2001-02-03 @@ -14,6 +15,7 @@ Time: 4 key: key2 file: /path2 Artist: artist2 +AlbumArtist: artist2 Title: track2 Album: album2 Date: 2002 @@ -28,4 +30,12 @@ Album: album3 Date: 2003 Track: 3 Time: 4 +key: key4 +file: /path4 +Artist: artist3 +Title: track4 +Album: album4 +Date: 2004 +Track: 4 +Time: 60 songList end diff --git a/tests/data/simple_tag_cache b/tests/data/simple_tag_cache index cc71ac6d..07a474b3 100644 --- a/tests/data/simple_tag_cache +++ b/tests/data/simple_tag_cache @@ -7,6 +7,7 @@ key: song1.mp3 file: /song1.mp3 Time: 4 Artist: name +AlbumArtist: name Title: trackname Album: albumname Track: 1/2 diff --git a/tests/data/utf8_tag_cache b/tests/data/utf8_tag_cache index 6642ec77..6f6abe60 100644 --- a/tests/data/utf8_tag_cache +++ b/tests/data/utf8_tag_cache @@ -7,6 +7,7 @@ key: song1.mp3 file: /song1.mp3 Time: 4 Artist: æøå +AlbumArtist: æøå Title: æøå Album: æøå mtime: 1272319626 From f295cbd3cbd68cdcf1e494407549297d8d08cf2f Mon Sep 17 00:00:00 2001 From: Lasse Bigum Date: Sat, 2 Nov 2013 02:51:06 +0100 Subject: [PATCH 11/17] Fix flake8 issues --- tests/backends/local/library_test.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/backends/local/library_test.py b/tests/backends/local/library_test.py index af09b4bb..90002c69 100644 --- a/tests/backends/local/library_test.py +++ b/tests/backends/local/library_test.py @@ -221,7 +221,8 @@ class LocalLibraryProviderTest(unittest.TestCase): # Matches on track album artists result = self.library.find_exact(any=['artist3']) - self.assertEqual(list(result[0].tracks), [self.tracks[3], self.tracks[2]]) + self.assertEqual(list(result[0].tracks), [self.tracks[3], + self.tracks[2]]) # Matches on track year result = self.library.find_exact(any=['2002']) @@ -364,7 +365,8 @@ class LocalLibraryProviderTest(unittest.TestCase): # Matches on track album artists result = self.library.search(any=['Tist3']) - self.assertEqual(list(result[0].tracks), [self.tracks[3], self.tracks[2]]) + self.assertEqual(list(result[0].tracks), [self.tracks[3], + self.tracks[2]]) # Matches on URI result = self.library.search(any=['TH1']) From b0d43444c254acd75a5ca65add7e2871b318c5c0 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 2 Nov 2013 22:18:26 +0100 Subject: [PATCH 12/17] local: Remove debug logging in tests --- tests/backends/local/library_test.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/backends/local/library_test.py b/tests/backends/local/library_test.py index 90002c69..9206b3b4 100644 --- a/tests/backends/local/library_test.py +++ b/tests/backends/local/library_test.py @@ -157,9 +157,6 @@ class LocalLibraryProviderTest(unittest.TestCase): result = self.library.find_exact(artist=['artist2']) self.assertEqual(list(result[0].tracks), self.tracks[1:2]) - import logging - logger = logging.getLogger('mopidy.backends.local') - logger.debug("==TEST= tracks: {}".format(self.tracks[2:3])) result = self.library.find_exact(artist=['artist3']) self.assertEqual(list(result[0].tracks), self.tracks[3:4]) From 838f584e2b7b2c35f7efe8d48f31b5c1d9770687 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 2 Nov 2013 22:18:37 +0100 Subject: [PATCH 13/17] local: Formatting --- tests/backends/local/library_test.py | 8 ++++---- tests/backends/local/translator_test.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/backends/local/library_test.py b/tests/backends/local/library_test.py index 9206b3b4..ab95d4de 100644 --- a/tests/backends/local/library_test.py +++ b/tests/backends/local/library_test.py @@ -218,8 +218,8 @@ class LocalLibraryProviderTest(unittest.TestCase): # Matches on track album artists result = self.library.find_exact(any=['artist3']) - self.assertEqual(list(result[0].tracks), [self.tracks[3], - self.tracks[2]]) + self.assertEqual( + list(result[0].tracks), [self.tracks[3], self.tracks[2]]) # Matches on track year result = self.library.find_exact(any=['2002']) @@ -362,8 +362,8 @@ class LocalLibraryProviderTest(unittest.TestCase): # Matches on track album artists result = self.library.search(any=['Tist3']) - self.assertEqual(list(result[0].tracks), [self.tracks[3], - self.tracks[2]]) + self.assertEqual( + list(result[0].tracks), [self.tracks[3], self.tracks[2]]) # Matches on URI result = self.library.search(any=['TH1']) diff --git a/tests/backends/local/translator_test.py b/tests/backends/local/translator_test.py index 1719500c..07990e47 100644 --- a/tests/backends/local/translator_test.py +++ b/tests/backends/local/translator_test.py @@ -94,8 +94,8 @@ class URItoM3UTest(unittest.TestCase): expected_artists = [Artist(name='name')] expected_albums = [ Album(name='albumname', artists=expected_artists, num_tracks=2), - Album(name='albumname', num_tracks=2) - ] + Album(name='albumname', num_tracks=2), +] expected_tracks = [] From a44b7c06a59aaf26eefd78d320887832ab714ad1 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 2 Nov 2013 22:20:02 +0100 Subject: [PATCH 14/17] docs: Update changelog --- docs/changelog.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 0e560f3d..d98e7867 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -11,6 +11,10 @@ v0.17.0 (UNRELEASED) - Fix search filtering by track number. +- When scanning, we no longer default the album artist to be the same as the + track artist. Album artist is now only populated if the scanned file got an + explicit album artist set. + **MPD frontend** - Add support for ``list "albumartist" ...``. From 9593da08b6d9b5be71b9bcdfc2325b4e25e0d877 Mon Sep 17 00:00:00 2001 From: Lasse Bigum Date: Thu, 31 Oct 2013 22:47:33 +0100 Subject: [PATCH 15/17] Rename track in MPD to track_name to avoid confusion --- mopidy/backends/local/library.py | 4 ++-- mopidy/frontends/mpd/translator.py | 2 +- tests/backends/local/library_test.py | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/mopidy/backends/local/library.py b/mopidy/backends/local/library.py index d2af41fc..3afbd184 100644 --- a/mopidy/backends/local/library.py +++ b/mopidy/backends/local/library.py @@ -91,7 +91,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): if field == 'uri': result_tracks = filter(uri_filter, result_tracks) - elif field == 'track': + elif field == 'track_name': result_tracks = filter(track_filter, result_tracks) elif field == 'album': result_tracks = filter(album_filter, result_tracks) @@ -149,7 +149,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): if field == 'uri': result_tracks = filter(uri_filter, result_tracks) - elif field == 'track': + elif field == 'track_name': result_tracks = filter(track_filter, result_tracks) elif field == 'album': result_tracks = filter(album_filter, result_tracks) diff --git a/mopidy/frontends/mpd/translator.py b/mopidy/frontends/mpd/translator.py index d25cad44..880d1411 100644 --- a/mopidy/frontends/mpd/translator.py +++ b/mopidy/frontends/mpd/translator.py @@ -234,7 +234,7 @@ def query_from_mpd_search_format(mpd_query): m = MPD_SEARCH_QUERY_PART_RE.match(query_part) field = m.groupdict()['field'].lower() if field == 'title': - field = 'track' + field = 'track_name' elif field == 'track': field = 'track_no' elif field in ('file', 'filename'): diff --git a/tests/backends/local/library_test.py b/tests/backends/local/library_test.py index ab95d4de..56afc4ea 100644 --- a/tests/backends/local/library_test.py +++ b/tests/backends/local/library_test.py @@ -107,7 +107,7 @@ class LocalLibraryProviderTest(unittest.TestCase): self.assertEqual(tracks, []) def test_find_exact_no_hits(self): - result = self.library.find_exact(track=['unknown track']) + result = self.library.find_exact(track_name=['unknown track']) self.assertEqual(list(result[0].tracks), []) result = self.library.find_exact(artist=['unknown artist']) @@ -144,10 +144,10 @@ class LocalLibraryProviderTest(unittest.TestCase): self.assertEqual(list(result[0].tracks), self.tracks[1:2]) def test_find_exact_track(self): - result = self.library.find_exact(track=['track1']) + result = self.library.find_exact(track_name=['track1']) self.assertEqual(list(result[0].tracks), self.tracks[:1]) - result = self.library.find_exact(track=['track2']) + result = self.library.find_exact(track_name=['track2']) self.assertEqual(list(result[0].tracks), self.tracks[1:2]) def test_find_exact_artist(self): @@ -240,7 +240,7 @@ class LocalLibraryProviderTest(unittest.TestCase): test = lambda: self.library.find_exact(albumartist=['']) self.assertRaises(LookupError, test) - test = lambda: self.library.find_exact(track=['']) + test = lambda: self.library.find_exact(track_name=['']) self.assertRaises(LookupError, test) test = lambda: self.library.find_exact(album=['']) @@ -256,7 +256,7 @@ class LocalLibraryProviderTest(unittest.TestCase): self.assertRaises(LookupError, test) def test_search_no_hits(self): - result = self.library.search(track=['unknown track']) + result = self.library.search(track_name=['unknown track']) self.assertEqual(list(result[0].tracks), []) result = self.library.search(artist=['unknown artist']) @@ -291,10 +291,10 @@ class LocalLibraryProviderTest(unittest.TestCase): self.assertEqual(list(result[0].tracks), self.tracks[1:2]) def test_search_track(self): - result = self.library.search(track=['Rack1']) + result = self.library.search(track_name=['Rack1']) self.assertEqual(list(result[0].tracks), self.tracks[:1]) - result = self.library.search(track=['Rack2']) + result = self.library.search(track_name=['Rack2']) self.assertEqual(list(result[0].tracks), self.tracks[1:2]) def test_search_artist(self): @@ -380,7 +380,7 @@ class LocalLibraryProviderTest(unittest.TestCase): test = lambda: self.library.search(albumartist=['']) self.assertRaises(LookupError, test) - test = lambda: self.library.search(track=['']) + test = lambda: self.library.search(track_name=['']) self.assertRaises(LookupError, test) test = lambda: self.library.search(album=['']) From 7339d4839c83c0157d6c8cd4304cb7b72491539e Mon Sep 17 00:00:00 2001 From: Lasse Bigum Date: Sat, 2 Nov 2013 02:56:33 +0100 Subject: [PATCH 16/17] Update filter name to match track_name change --- mopidy/backends/local/library.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mopidy/backends/local/library.py b/mopidy/backends/local/library.py index 3afbd184..86d960c1 100644 --- a/mopidy/backends/local/library.py +++ b/mopidy/backends/local/library.py @@ -72,7 +72,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): q = value.strip() uri_filter = lambda t: q == t.uri - track_filter = lambda t: q == t.name + track_name_filter = lambda t: q == t.name album_filter = lambda t: q == getattr(t, 'album', Album()).name artist_filter = lambda t: filter( lambda a: q == a.name, t.artists) @@ -83,7 +83,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): date_filter = lambda t: q == t.date any_filter = lambda t: ( uri_filter(t) or - track_filter(t) or + track_name_filter(t) or album_filter(t) or artist_filter(t) or albumartist_filter(t) or @@ -92,7 +92,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): if field == 'uri': result_tracks = filter(uri_filter, result_tracks) elif field == 'track_name': - result_tracks = filter(track_filter, result_tracks) + result_tracks = filter(track_name_filter, result_tracks) elif field == 'album': result_tracks = filter(album_filter, result_tracks) elif field == 'artist': @@ -129,7 +129,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): q = value.strip().lower() uri_filter = lambda t: q in t.uri.lower() - track_filter = lambda t: q in t.name.lower() + track_name_filter = lambda t: q in t.name.lower() album_filter = lambda t: q in getattr( t, 'album', Album()).name.lower() artist_filter = lambda t: filter( @@ -141,7 +141,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): date_filter = lambda t: t.date and t.date.startswith(q) any_filter = lambda t: ( uri_filter(t) or - track_filter(t) or + track_name_filter(t) or album_filter(t) or artist_filter(t) or albumartist_filter(t) or @@ -150,7 +150,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): if field == 'uri': result_tracks = filter(uri_filter, result_tracks) elif field == 'track_name': - result_tracks = filter(track_filter, result_tracks) + result_tracks = filter(track_name_filter, result_tracks) elif field == 'album': result_tracks = filter(album_filter, result_tracks) elif field == 'artist': From 640337bc680cf3cce498ac7f9314c0e2faf75c25 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 2 Nov 2013 22:38:20 +0100 Subject: [PATCH 17/17] docs: Update changelog --- docs/changelog.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index d98e7867..12a19057 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -7,6 +7,11 @@ This changelog is used to track all major changes to Mopidy. v0.17.0 (UNRELEASED) ==================== +**Core** + +- The search field ``track`` has been renamed to ``track_name`` to avoid + confusion with ``track_no``. + **Local backend** - Fix search filtering by track number.