Merge pull request #365 from jodal/feature/tracklist-add-by-uri

Add to tracklist by URI
This commit is contained in:
Thomas Adamcik 2013-03-31 00:31:02 -07:00
commit 2845f9cf8b
5 changed files with 52 additions and 17 deletions

View File

@ -24,6 +24,12 @@ v0.13.0 (in development)
the Mopidy process will now always make it log tracebacks for all alive
threads.
- :meth:`mopidy.core.TracklistController.add` now accepts an ``uri`` which it
will lookup in the libraries and then add to the tracklist. This is helpful
for e.g. web clients that doesn't want to transfer all track meta data back
to the server just to add it to the tracklist when the server already got all
the needed information easily available. (Fixes: :issue:`325`)
**Audio sub-system**
- Make audio error logging handle log messages with non-ASCII chars. (Fixes:

View File

@ -62,10 +62,13 @@ class TracklistController(object):
Is not reset before Mopidy is restarted.
"""
def add(self, tracks, at_position=None):
def add(self, tracks=None, at_position=None, uri=None):
"""
Add the track or list of tracks to the tracklist.
If ``uri`` is given instead of ``tracks``, the URI is looked up in the
library and the resulting tracks are added to the tracklist.
If ``at_position`` is given, the tracks placed at the given position in
the tracklist. If ``at_position`` is not given, the tracks are appended
to the end of the tracklist.
@ -76,9 +79,18 @@ class TracklistController(object):
:type tracks: list of :class:`mopidy.models.Track`
:param at_position: position in tracklist to add track
:type at_position: int or :class:`None`
:param uri: URI for tracks to add
:type uri: string
:rtype: list of :class:`mopidy.models.TlTrack`
"""
assert tracks is not None or uri is not None, \
'tracks or uri must be provided'
if tracks is None and uri is not None:
tracks = self._core.library.lookup(uri)
tl_tracks = []
for track in tracks:
tl_track = TlTrack(self._next_tlid, track)
self._next_tlid += 1

View File

@ -22,11 +22,9 @@ def add(context, uri):
"""
if not uri:
return
tracks = context.core.library.lookup(uri).get()
if tracks:
context.core.tracklist.add(tracks)
return
raise MpdNoExistError('directory or file not found', command='add')
tl_tracks = context.core.tracklist.add(uri=uri).get()
if not tl_tracks:
raise MpdNoExistError('directory or file not found', command='add')
@handle_request(r'^addid "(?P<uri>[^"]*)"( "(?P<songpos>\d+)")*$')
@ -52,12 +50,11 @@ def addid(context, uri, songpos=None):
raise MpdNoExistError('No such song', command='addid')
if songpos is not None:
songpos = int(songpos)
tracks = context.core.library.lookup(uri).get()
if not tracks:
raise MpdNoExistError('No such song', command='addid')
if songpos and songpos > context.core.tracklist.length.get():
raise MpdArgError('Bad song index', command='addid')
tl_tracks = context.core.tracklist.add(tracks, at_position=songpos).get()
tl_tracks = context.core.tracklist.add(uri=uri, at_position=songpos).get()
if not tl_tracks:
raise MpdNoExistError('No such song', command='addid')
return ('Id', tl_tracks[0].tlid)

View File

@ -279,9 +279,8 @@ class MprisObject(dbus.service.Object):
return
# NOTE Check if URI has MIME type known to the backend, if MIME support
# is added to the backend.
tracks = self.core.library.lookup(uri).get()
if tracks:
tl_tracks = self.core.tracklist.add(tracks).get()
tl_tracks = self.core.tracklist.add(uri=uri).get()
if tl_tracks:
self.core.playback.play(tl_tracks[0])
else:
logger.debug('Track with URI "%s" not found in library.', uri)

View File

@ -1,5 +1,8 @@
from __future__ import unicode_literals
import mock
from mopidy.backends import base
from mopidy.core import Core
from mopidy.models import Track
@ -9,13 +12,31 @@ from tests import unittest
class TracklistTest(unittest.TestCase):
def setUp(self):
self.tracks = [
Track(uri='a', name='foo'),
Track(uri='b', name='foo'),
Track(uri='c', name='bar')
Track(uri='dummy1:a', name='foo'),
Track(uri='dummy1:b', name='foo'),
Track(uri='dummy1:c', name='bar'),
]
self.core = Core(audio=None, backends=[])
self.backend = mock.Mock()
self.backend.uri_schemes.get.return_value = ['dummy1']
self.library = mock.Mock(spec=base.BaseLibraryProvider)
self.backend.library = self.library
self.core = Core(audio=None, backends=[self.backend])
self.tl_tracks = self.core.tracklist.add(self.tracks)
def test_add_by_uri_looks_up_uri_in_library(self):
track = Track(uri='dummy1:x', name='x')
self.library.lookup().get.return_value = [track]
self.library.lookup.reset_mock()
tl_tracks = self.core.tracklist.add(uri='dummy1:x')
self.library.lookup.assert_called_once_with('dummy1:x')
self.assertEqual(1, len(tl_tracks))
self.assertEqual(track, tl_tracks[0].track)
self.assertEqual(tl_tracks, self.core.tracklist.tl_tracks[-1:])
def test_remove_removes_tl_tracks_matching_query(self):
tl_tracks = self.core.tracklist.remove(name='foo')