Return lists of tracks from search() and find_exact()
This commit is contained in:
parent
6f0919bda8
commit
7df556c9b3
@ -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
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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():
|
||||
|
||||
@ -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 []
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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())
|
||||
|
||||
|
||||
|
||||
@ -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'])
|
||||
|
||||
@ -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'])
|
||||
|
||||
Loading…
Reference in New Issue
Block a user