From 7df556c9b30160d7747c5d9deb9861994855a803 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Mon, 19 Nov 2012 18:13:14 +0100 Subject: [PATCH] Return lists of tracks from search() and find_exact() --- docs/changes.rst | 4 ++ mopidy/backends/dummy.py | 4 +- mopidy/backends/local/library.py | 6 +-- mopidy/backends/spotify/library.py | 8 ++-- mopidy/core/library.py | 13 ++--- mopidy/frontends/mpd/protocol/music_db.py | 18 +++---- tests/backends/base/library.py | 58 +++++++++++------------ tests/core/library_test.py | 18 +++---- 8 files changed, 64 insertions(+), 65 deletions(-) diff --git a/docs/changes.rst b/docs/changes.rst index 4317e4ef..6e9a8f66 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -128,6 +128,10 @@ backends: means that you now can select playlists to queue and play from the Ubuntu Sound Menu. +- :meth:`mopidy.core.LibraryController.find_exact` and + :meth:`mopidy.core.LibraryController.search` now returns plain lists of + tracks instead of playlist objects. + **Bug fixes** - :issue:`218`: The MPD commands ``listplaylist`` and ``listplaylistinfo`` now diff --git a/mopidy/backends/dummy.py b/mopidy/backends/dummy.py index d3239b34..1d561bda 100644 --- a/mopidy/backends/dummy.py +++ b/mopidy/backends/dummy.py @@ -39,7 +39,7 @@ class DummyLibraryProvider(base.BaseLibraryProvider): self.dummy_library = [] def find_exact(self, **query): - return Playlist() + return [] def lookup(self, uri): matches = filter(lambda t: uri == t.uri, self.dummy_library) @@ -50,7 +50,7 @@ class DummyLibraryProvider(base.BaseLibraryProvider): pass def search(self, **query): - return Playlist() + return [] class DummyPlaybackProvider(base.BasePlaybackProvider): diff --git a/mopidy/backends/local/library.py b/mopidy/backends/local/library.py index 3454ca76..1b406f84 100644 --- a/mopidy/backends/local/library.py +++ b/mopidy/backends/local/library.py @@ -4,7 +4,7 @@ import logging from mopidy import settings from mopidy.backends import base -from mopidy.models import Playlist, Album +from mopidy.models import Album from .translator import parse_mpd_tag_cache @@ -67,7 +67,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): result_tracks = filter(any_filter, result_tracks) else: raise LookupError('Invalid lookup field: %s' % field) - return Playlist(tracks=result_tracks) + return result_tracks def search(self, **query): self._validate_query(query) @@ -101,7 +101,7 @@ class LocalLibraryProvider(base.BaseLibraryProvider): result_tracks = filter(any_filter, result_tracks) else: raise LookupError('Invalid lookup field: %s' % field) - return Playlist(tracks=result_tracks) + return result_tracks def _validate_query(self, query): for (_, values) in query.iteritems(): diff --git a/mopidy/backends/spotify/library.py b/mopidy/backends/spotify/library.py index 67c390fc..5d80bc8d 100644 --- a/mopidy/backends/spotify/library.py +++ b/mopidy/backends/spotify/library.py @@ -6,7 +6,7 @@ import Queue from spotify import Link, SpotifyError from mopidy.backends import base -from mopidy.models import Track, Playlist +from mopidy.models import Track from . import translator @@ -72,7 +72,7 @@ class SpotifyLibraryProvider(base.BaseLibraryProvider): tracks = [] for playlist in self.backend.playlists.playlists: tracks += playlist.tracks - return Playlist(tracks=tracks) + return tracks spotify_query = [] for (field, values) in query.iteritems(): if field == 'uri': @@ -81,7 +81,7 @@ class SpotifyLibraryProvider(base.BaseLibraryProvider): track = self.lookup(value) if track: tracks.append(track) - return Playlist(tracks=tracks) + return tracks elif field == 'track': field = 'title' elif field == 'date': @@ -103,4 +103,4 @@ class SpotifyLibraryProvider(base.BaseLibraryProvider): try: return queue.get(timeout=3) # XXX What is an reasonable timeout? except Queue.Empty: - return Playlist(tracks=[]) + return [] diff --git a/mopidy/core/library.py b/mopidy/core/library.py index 6e421595..ccd4e92b 100644 --- a/mopidy/core/library.py +++ b/mopidy/core/library.py @@ -5,8 +5,6 @@ import urlparse import pykka -from mopidy.models import Playlist - class LibraryController(object): pykka_traversable = True @@ -34,13 +32,12 @@ class LibraryController(object): :param query: one or more queries to search for :type query: dict - :rtype: :class:`mopidy.models.Playlist` + :rtype: list of :class:`mopidy.models.Track` """ futures = [ b.library.find_exact(**query) for b in self.backends.with_library] results = pykka.get_all(futures) - return Playlist(tracks=[ - track for playlist in results for track in playlist.tracks]) + return list(itertools.chain(*results)) def lookup(self, uri): """ @@ -87,11 +84,9 @@ class LibraryController(object): :param query: one or more queries to search for :type query: dict - :rtype: :class:`mopidy.models.Playlist` + :rtype: list of :class:`mopidy.models.Track` """ futures = [ b.library.search(**query) for b in self.backends.with_library] results = pykka.get_all(futures) - track_lists = [playlist.tracks for playlist in results] - tracks = list(itertools.chain(*track_lists)) - return Playlist(tracks=tracks) + return list(itertools.chain(*results)) diff --git a/mopidy/frontends/mpd/protocol/music_db.py b/mopidy/frontends/mpd/protocol/music_db.py index bea57198..08ba8b19 100644 --- a/mopidy/frontends/mpd/protocol/music_db.py +++ b/mopidy/frontends/mpd/protocol/music_db.py @@ -5,7 +5,7 @@ import shlex from mopidy.frontends.mpd.exceptions import MpdArgError, MpdNotImplemented from mopidy.frontends.mpd.protocol import handle_request, stored_playlists -from mopidy.frontends.mpd.translator import playlist_to_mpd_format +from mopidy.frontends.mpd.translator import tracks_to_mpd_format def _build_query(mpd_query): @@ -77,7 +77,7 @@ def find(context, mpd_query): - uses "file" instead of "filename". """ query = _build_query(mpd_query) - return playlist_to_mpd_format( + return tracks_to_mpd_format( context.core.library.find_exact(**query).get()) @@ -235,8 +235,8 @@ def _list_build_query(field, mpd_query): def _list_artist(context, query): artists = set() - playlist = context.core.library.find_exact(**query).get() - for track in playlist.tracks: + tracks = context.core.library.find_exact(**query).get() + for track in tracks: for artist in track.artists: artists.add(('Artist', artist.name)) return artists @@ -244,8 +244,8 @@ def _list_artist(context, query): def _list_album(context, query): albums = set() - playlist = context.core.library.find_exact(**query).get() - for track in playlist.tracks: + tracks = context.core.library.find_exact(**query).get() + for track in tracks: if track.album is not None: albums.add(('Album', track.album.name)) return albums @@ -253,8 +253,8 @@ def _list_album(context, query): def _list_date(context, query): dates = set() - playlist = context.core.library.find_exact(**query).get() - for track in playlist.tracks: + tracks = context.core.library.find_exact(**query).get() + for track in tracks: if track.date is not None: dates.add(('Date', track.date)) return dates @@ -352,7 +352,7 @@ def search(context, mpd_query): - uses "file" instead of "filename". """ query = _build_query(mpd_query) - return playlist_to_mpd_format( + return tracks_to_mpd_format( context.core.library.search(**query).get()) diff --git a/tests/backends/base/library.py b/tests/backends/base/library.py index 0b32186f..50b73040 100644 --- a/tests/backends/base/library.py +++ b/tests/backends/base/library.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import pykka from mopidy import core -from mopidy.models import Playlist, Track, Album, Artist +from mopidy.models import Track, Album, Artist from tests import unittest, path_to_data_dir @@ -52,43 +52,43 @@ class LibraryControllerTest(object): def test_find_exact_no_hits(self): result = self.library.find_exact(track=['unknown track']) - self.assertEqual(result, Playlist()) + self.assertEqual(result, []) result = self.library.find_exact(artist=['unknown artist']) - self.assertEqual(result, Playlist()) + self.assertEqual(result, []) result = self.library.find_exact(album=['unknown artist']) - self.assertEqual(result, Playlist()) + self.assertEqual(result, []) def test_find_exact_artist(self): result = self.library.find_exact(artist=['artist1']) - self.assertEqual(result, Playlist(tracks=self.tracks[:1])) + self.assertEqual(result, self.tracks[:1]) result = self.library.find_exact(artist=['artist2']) - self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) + self.assertEqual(result, self.tracks[1:2]) def test_find_exact_track(self): result = self.library.find_exact(track=['track1']) - self.assertEqual(result, Playlist(tracks=self.tracks[:1])) + self.assertEqual(result, self.tracks[:1]) result = self.library.find_exact(track=['track2']) - self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) + self.assertEqual(result, self.tracks[1:2]) def test_find_exact_album(self): result = self.library.find_exact(album=['album1']) - self.assertEqual(result, Playlist(tracks=self.tracks[:1])) + self.assertEqual(result, self.tracks[:1]) result = self.library.find_exact(album=['album2']) - self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) + self.assertEqual(result, self.tracks[1:2]) def test_find_exact_uri(self): track_1_uri = 'file://' + path_to_data_dir('uri1') result = self.library.find_exact(uri=track_1_uri) - self.assertEqual(result, Playlist(tracks=self.tracks[:1])) + self.assertEqual(result, self.tracks[:1]) track_2_uri = 'file://' + path_to_data_dir('uri2') result = self.library.find_exact(uri=track_2_uri) - self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) + self.assertEqual(result, self.tracks[1:2]) def test_find_exact_wrong_type(self): test = lambda: self.library.find_exact(wrong=['test']) @@ -106,57 +106,57 @@ class LibraryControllerTest(object): def test_search_no_hits(self): result = self.library.search(track=['unknown track']) - self.assertEqual(result, Playlist()) + self.assertEqual(result, []) result = self.library.search(artist=['unknown artist']) - self.assertEqual(result, Playlist()) + self.assertEqual(result, []) result = self.library.search(album=['unknown artist']) - self.assertEqual(result, Playlist()) + self.assertEqual(result, []) result = self.library.search(uri=['unknown']) - self.assertEqual(result, Playlist()) + self.assertEqual(result, []) result = self.library.search(any=['unknown']) - self.assertEqual(result, Playlist()) + self.assertEqual(result, []) def test_search_artist(self): result = self.library.search(artist=['Tist1']) - self.assertEqual(result, Playlist(tracks=self.tracks[:1])) + self.assertEqual(result, self.tracks[:1]) result = self.library.search(artist=['Tist2']) - self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) + self.assertEqual(result, self.tracks[1:2]) def test_search_track(self): result = self.library.search(track=['Rack1']) - self.assertEqual(result, Playlist(tracks=self.tracks[:1])) + self.assertEqual(result, self.tracks[:1]) result = self.library.search(track=['Rack2']) - self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) + self.assertEqual(result, self.tracks[1:2]) def test_search_album(self): result = self.library.search(album=['Bum1']) - self.assertEqual(result, Playlist(tracks=self.tracks[:1])) + self.assertEqual(result, self.tracks[:1]) result = self.library.search(album=['Bum2']) - self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) + self.assertEqual(result, self.tracks[1:2]) def test_search_uri(self): result = self.library.search(uri=['RI1']) - self.assertEqual(result, Playlist(tracks=self.tracks[:1])) + self.assertEqual(result, self.tracks[:1]) result = self.library.search(uri=['RI2']) - self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) + self.assertEqual(result, self.tracks[1:2]) def test_search_any(self): result = self.library.search(any=['Tist1']) - self.assertEqual(result, Playlist(tracks=self.tracks[:1])) + self.assertEqual(result, self.tracks[:1]) result = self.library.search(any=['Rack1']) - self.assertEqual(result, Playlist(tracks=self.tracks[:1])) + self.assertEqual(result, self.tracks[:1]) result = self.library.search(any=['Bum1']) - self.assertEqual(result, Playlist(tracks=self.tracks[:1])) + self.assertEqual(result, self.tracks[:1]) result = self.library.search(any=['RI1']) - self.assertEqual(result, Playlist(tracks=self.tracks[:1])) + self.assertEqual(result, self.tracks[:1]) def test_search_wrong_type(self): test = lambda: self.library.search(wrong=['test']) diff --git a/tests/core/library_test.py b/tests/core/library_test.py index 7886b85c..40b928d8 100644 --- a/tests/core/library_test.py +++ b/tests/core/library_test.py @@ -4,7 +4,7 @@ import mock from mopidy.backends import base from mopidy.core import Core -from mopidy.models import Playlist, Track +from mopidy.models import Track from tests import unittest @@ -75,29 +75,29 @@ class CoreLibraryTest(unittest.TestCase): def test_find_exact_combines_results_from_all_backends(self): track1 = Track(uri='dummy1:a') track2 = Track(uri='dummy2:a') - self.library1.find_exact().get.return_value = Playlist(tracks=[track1]) + self.library1.find_exact().get.return_value = [track1] self.library1.find_exact.reset_mock() - self.library2.find_exact().get.return_value = Playlist(tracks=[track2]) + self.library2.find_exact().get.return_value = [track2] self.library2.find_exact.reset_mock() result = self.core.library.find_exact(any=['a']) - self.assertIn(track1, result.tracks) - self.assertIn(track2, result.tracks) + self.assertIn(track1, result) + self.assertIn(track2, result) self.library1.find_exact.assert_called_once_with(any=['a']) self.library2.find_exact.assert_called_once_with(any=['a']) def test_search_combines_results_from_all_backends(self): track1 = Track(uri='dummy1:a') track2 = Track(uri='dummy2:a') - self.library1.search().get.return_value = Playlist(tracks=[track1]) + self.library1.search().get.return_value = [track1] self.library1.search.reset_mock() - self.library2.search().get.return_value = Playlist(tracks=[track2]) + self.library2.search().get.return_value = [track2] self.library2.search.reset_mock() result = self.core.library.search(any=['a']) - self.assertIn(track1, result.tracks) - self.assertIn(track2, result.tracks) + self.assertIn(track1, result) + self.assertIn(track2, result) self.library1.search.assert_called_once_with(any=['a']) self.library2.search.assert_called_once_with(any=['a'])