mpd: Implement "listallinfo" command (fixes #145)

This commit is contained in:
Stein Magnus Jodal 2014-01-15 01:08:17 +01:00
parent afbff12ccc
commit d698653d83
2 changed files with 65 additions and 6 deletions

View File

@ -6,8 +6,7 @@ import re
from mopidy.models import Ref, Track
from mopidy.mpd import translator
from mopidy.mpd.exceptions import (
MpdArgError, MpdNoExistError, MpdNotImplemented)
from mopidy.mpd.exceptions import MpdArgError, MpdNoExistError
from mopidy.mpd.protocol import handle_request, stored_playlists
@ -450,7 +449,34 @@ def listallinfo(context, uri=None):
Same as ``listall``, except it also returns metadata info in the
same format as ``lsinfo``.
"""
raise MpdNotImplemented # TODO
if uri is None:
uri = '/'
if not uri.startswith('/'):
uri = '/%s' % uri
dirs_and_futures = []
browse_futures = [context.core.library.browse(uri)]
while browse_futures:
for ref in browse_futures.pop().get():
if ref.type == Ref.DIRECTORY:
dirs_and_futures.append(('directory', ref.uri))
browse_futures.append(context.core.library.browse(ref.uri))
elif ref.type == Ref.TRACK:
# TODO Lookup tracks in batch for better performance
dirs_and_futures.append(context.core.library.lookup(ref.uri))
result = []
for obj in dirs_and_futures:
if hasattr(obj, 'get'):
for track in obj.get():
result.extend(translator.track_to_mpd_format(track))
else:
result.append(obj)
if not result:
raise MpdNoExistError('Not found', command='listallinfo')
return [('directory', uri)] + result
@handle_request(r'lsinfo$')

View File

@ -160,12 +160,45 @@ class MusicDatabaseHandlerTest(protocol.BaseTestCase):
self.assertEqualResponse('ACK [50@0] {listall} Not found')
def test_listallinfo_without_uri(self):
tracks = [Track(uri='dummy:/a', name='a'),
Track(uri='dummy:/b', name='b')]
self.backend.library.dummy_library = tracks
self.backend.library.dummy_browse_result = {
'/': [Ref.track(uri='dummy:/a', name='a'),
Ref.directory(uri='/foo')],
'/foo': [Ref.track(uri='dummy:/b', name='b')]}
self.sendRequest('listallinfo')
self.assertEqualResponse('ACK [0@0] {} Not implemented')
self.assertInResponse('file: dummy:/a')
self.assertInResponse('Title: a')
self.assertInResponse('directory: /dummy/foo')
self.assertInResponse('file: dummy:/b')
self.assertInResponse('Title: b')
self.assertInResponse('OK')
def test_listallinfo_with_uri(self):
self.sendRequest('listallinfo "file:///dev/urandom"')
self.assertEqualResponse('ACK [0@0] {} Not implemented')
tracks = [Track(uri='dummy:/a', name='a'),
Track(uri='dummy:/b', name='b')]
self.backend.library.dummy_library = tracks
self.backend.library.dummy_browse_result = {
'/': [Ref.track(uri='dummy:/a', name='a'),
Ref.directory(uri='/foo')],
'/foo': [Ref.track(uri='dummy:/b', name='b')]}
self.sendRequest('listallinfo "/dummy/foo"')
self.assertNotInResponse('file: dummy:/a')
self.assertNotInResponse('Title: a')
self.assertInResponse('directory: /dummy/foo')
self.assertInResponse('file: dummy:/b')
self.assertInResponse('Title: b')
self.assertInResponse('OK')
def test_listallinfo_with_unknown_uri(self):
self.sendRequest('listallinfo "/unknown"')
self.assertEqualResponse('ACK [50@0] {listallinfo} Not found')
def test_lsinfo_without_path_returns_same_as_for_root(self):
last_modified = datetime.datetime(2001, 3, 17, 13, 41, 17, 12345)