diff --git a/mopidy/mpd/dispatcher.py b/mopidy/mpd/dispatcher.py index 4ddb4025..a601f13e 100644 --- a/mopidy/mpd/dispatcher.py +++ b/mopidy/mpd/dispatcher.py @@ -165,7 +165,12 @@ class MpdDispatcher(object): def _call_handler(self, request): (handler, kwargs) = self._find_handler(request) - return handler(self.context, **kwargs) + try: + return handler(self.context, **kwargs) + except exceptions.MpdAckError as exc: + if exc.command is None: + exc.command = handler.__name__.split('__', 1)[0] + raise def _find_handler(self, request): for pattern in protocol.request_handlers: diff --git a/mopidy/mpd/exceptions.py b/mopidy/mpd/exceptions.py index 07e3a421..ec874553 100644 --- a/mopidy/mpd/exceptions.py +++ b/mopidy/mpd/exceptions.py @@ -21,7 +21,7 @@ class MpdAckError(MopidyException): error_code = 0 - def __init__(self, message='', index=0, command=''): + def __init__(self, message='', index=0, command=None): super(MpdAckError, self).__init__(message, index, command) self.message = message self.index = index @@ -50,6 +50,7 @@ class MpdPermissionError(MpdAckError): def __init__(self, *args, **kwargs): super(MpdPermissionError, self).__init__(*args, **kwargs) + assert self.command is not None, 'command must be given explicitly' self.message = 'you don\'t have permission for "%s"' % self.command @@ -58,12 +59,14 @@ class MpdUnknownCommand(MpdAckError): def __init__(self, *args, **kwargs): super(MpdUnknownCommand, self).__init__(*args, **kwargs) + assert self.command is not None, 'command must be given explicitly' self.message = 'unknown command "%s"' % self.command self.command = '' class MpdNoCommand(MpdUnknownCommand): def __init__(self, *args, **kwargs): + kwargs['command'] = '' super(MpdNoCommand, self).__init__(*args, **kwargs) self.message = 'No command given' diff --git a/mopidy/mpd/protocol/audio_output.py b/mopidy/mpd/protocol/audio_output.py index 606eb1d3..802be6c0 100644 --- a/mopidy/mpd/protocol/audio_output.py +++ b/mopidy/mpd/protocol/audio_output.py @@ -16,7 +16,7 @@ def disableoutput(context, outputid): if int(outputid) == 0: context.core.playback.set_mute(False) else: - raise MpdNoExistError('No such audio output', command='disableoutput') + raise MpdNoExistError('No such audio output') @handle_request(r'enableoutput\ "(?P\d+)"$') @@ -31,7 +31,7 @@ def enableoutput(context, outputid): if int(outputid) == 0: context.core.playback.set_mute(True) else: - raise MpdNoExistError('No such audio output', command='enableoutput') + raise MpdNoExistError('No such audio output') @handle_request(r'outputs$') diff --git a/mopidy/mpd/protocol/connection.py b/mopidy/mpd/protocol/connection.py index 2c615e65..a6f9ffcb 100644 --- a/mopidy/mpd/protocol/connection.py +++ b/mopidy/mpd/protocol/connection.py @@ -30,7 +30,7 @@ def kill(context): @handle_request(r'password\ "(?P[^"]+)"$', auth_required=False) -def password_(context, password): +def password(context, password): """ *musicpd.org, connection section:* @@ -42,7 +42,7 @@ def password_(context, password): if password == context.config['mpd']['password']: context.dispatcher.authenticated = True else: - raise MpdPasswordError('incorrect password', command='password') + raise MpdPasswordError('incorrect password') @handle_request(r'ping$', auth_required=False) diff --git a/mopidy/mpd/protocol/current_playlist.py b/mopidy/mpd/protocol/current_playlist.py index ab799fb4..6263e2e8 100644 --- a/mopidy/mpd/protocol/current_playlist.py +++ b/mopidy/mpd/protocol/current_playlist.py @@ -44,7 +44,7 @@ def add(context, uri): tracks.extend(future.get()) if not tracks: - raise MpdNoExistError('directory or file not found', command='add') + raise MpdNoExistError('directory or file not found') context.core.tracklist.add(tracks=tracks) @@ -69,14 +69,14 @@ def addid(context, uri, songpos=None): - ``addid ""`` should return an error. """ if not uri: - raise MpdNoExistError('No such song', command='addid') + raise MpdNoExistError('No such song') if songpos is not None: songpos = int(songpos) if songpos and songpos > context.core.tracklist.length.get(): - raise MpdArgError('Bad song index', command='addid') + raise MpdArgError('Bad song index') tl_tracks = context.core.tracklist.add(uri=uri, at_position=songpos).get() if not tl_tracks: - raise MpdNoExistError('No such song', command='addid') + raise MpdNoExistError('No such song') return ('Id', tl_tracks[0].tlid) @@ -125,7 +125,7 @@ def deleteid(context, tlid): tlid = int(tlid) tl_tracks = context.core.tracklist.remove(tlid=[tlid]).get() if not tl_tracks: - raise MpdNoExistError('No such song', command='deleteid') + raise MpdNoExistError('No such song') @handle_request(r'clear$') @@ -181,7 +181,7 @@ def moveid(context, tlid, to): to = int(to) tl_tracks = context.core.tracklist.filter(tlid=[tlid]).get() if not tl_tracks: - raise MpdNoExistError('No such song', command='moveid') + raise MpdNoExistError('No such song') position = context.core.tracklist.index(tl_tracks[0]).get() context.core.tracklist.move(position, position + 1, to) @@ -239,7 +239,7 @@ def playlistid(context, tlid=None): tlid = int(tlid) tl_tracks = context.core.tracklist.filter(tlid=[tlid]).get() if not tl_tracks: - raise MpdNoExistError('No such song', command='playlistid') + raise MpdNoExistError('No such song') position = context.core.tracklist.index(tl_tracks[0]).get() return translator.track_to_mpd_format(tl_tracks[0], position=position) else: @@ -276,7 +276,7 @@ def playlistinfo(context, songpos=None, start=None, end=None): start = 0 start = int(start) if not (0 <= start <= context.core.tracklist.length.get()): - raise MpdArgError('Bad song index', command='playlistinfo') + raise MpdArgError('Bad song index') if end is not None: end = int(end) if end > context.core.tracklist.length.get(): @@ -403,7 +403,7 @@ def swapid(context, tlid1, tlid2): tl_tracks1 = context.core.tracklist.filter(tlid=[tlid1]).get() tl_tracks2 = context.core.tracklist.filter(tlid=[tlid2]).get() if not tl_tracks1 or not tl_tracks2: - raise MpdNoExistError('No such song', command='swapid') + raise MpdNoExistError('No such song') position1 = context.core.tracklist.index(tl_tracks1[0]).get() position2 = context.core.tracklist.index(tl_tracks2[0]).get() swap(context, position1, position2) diff --git a/mopidy/mpd/protocol/empty.py b/mopidy/mpd/protocol/empty.py index 9cb0aa6b..64cfc1fb 100644 --- a/mopidy/mpd/protocol/empty.py +++ b/mopidy/mpd/protocol/empty.py @@ -7,4 +7,4 @@ from mopidy.mpd.exceptions import MpdNoCommand @handle_request(r'[\ ]*$') def empty(context): """The original MPD server returns an error on an empty request.""" - raise MpdNoCommand + raise MpdNoCommand() diff --git a/mopidy/mpd/protocol/music_db.py b/mopidy/mpd/protocol/music_db.py index 7ef11111..774ec383 100644 --- a/mopidy/mpd/protocol/music_db.py +++ b/mopidy/mpd/protocol/music_db.py @@ -163,7 +163,7 @@ def count(context, mpd_query): try: query = _query_from_mpd_search_format(mpd_query) except ValueError: - raise MpdArgError('incorrect arguments', command='count') + raise MpdArgError('incorrect arguments') results = context.core.library.find_exact(**query).get() result_tracks = _get_tracks(results) return [ @@ -433,7 +433,7 @@ def listall(context, uri=None): result.append(('file', ref.uri)) if not result: - raise MpdNoExistError('Not found', command='listall') + raise MpdNoExistError('Not found') return [('directory', uri)] + result @@ -474,7 +474,7 @@ def listallinfo(context, uri=None): result.append(obj) if not result: - raise MpdNoExistError('Not found', command='listallinfo') + raise MpdNoExistError('Not found') return [('directory', uri)] + result diff --git a/mopidy/mpd/protocol/playback.py b/mopidy/mpd/protocol/playback.py index c09afde8..4f8ae73a 100644 --- a/mopidy/mpd/protocol/playback.py +++ b/mopidy/mpd/protocol/playback.py @@ -151,12 +151,12 @@ def playid(context, tlid): return _play_minus_one(context) tl_tracks = context.core.tracklist.filter(tlid=[tlid]).get() if not tl_tracks: - raise MpdNoExistError('No such song', command='playid') + raise MpdNoExistError('No such song') return context.core.playback.play(tl_tracks[0]).get() @handle_request(r'play\ ("?)(?P-?\d+)\1$') -def playpos(context, songpos): +def play__pos(context, songpos): """ *musicpd.org, playback section:* @@ -184,7 +184,7 @@ def playpos(context, songpos): tl_track = context.core.tracklist.slice(songpos, songpos + 1).get()[0] return context.core.playback.play(tl_track).get() except IndexError: - raise MpdArgError('Bad song index', command='play') + raise MpdArgError('Bad song index') def _play_minus_one(context): @@ -325,7 +325,7 @@ def seek(context, songpos, seconds): """ tl_track = context.core.playback.current_tl_track.get() if context.core.tracklist.index(tl_track).get() != int(songpos): - playpos(context, songpos) + play__pos(context, songpos) context.core.playback.seek(int(seconds) * 1000).get() diff --git a/mopidy/mpd/protocol/stickers.py b/mopidy/mpd/protocol/stickers.py index 1243d7a6..17798523 100644 --- a/mopidy/mpd/protocol/stickers.py +++ b/mopidy/mpd/protocol/stickers.py @@ -7,7 +7,7 @@ from mopidy.mpd.exceptions import MpdNotImplemented @handle_request( r'sticker\ delete\ "(?P[^"]+)"\ ' r'"(?P[^"]+)"(\ "(?P[^"]+)")*$') -def sticker_delete(context, field, uri, name=None): +def sticker__delete(context, field, uri, name=None): """ *musicpd.org, sticker section:* @@ -22,7 +22,7 @@ def sticker_delete(context, field, uri, name=None): @handle_request( r'sticker\ find\ "(?P[^"]+)"\ "(?P[^"]+)"\ ' r'"(?P[^"]+)"$') -def sticker_find(context, field, uri, name): +def sticker__find(context, field, uri, name): """ *musicpd.org, sticker section:* @@ -38,7 +38,7 @@ def sticker_find(context, field, uri, name): @handle_request( r'sticker\ get\ "(?P[^"]+)"\ "(?P[^"]+)"\ ' r'"(?P[^"]+)"$') -def sticker_get(context, field, uri, name): +def sticker__get(context, field, uri, name): """ *musicpd.org, sticker section:* @@ -50,7 +50,7 @@ def sticker_get(context, field, uri, name): @handle_request(r'sticker\ list\ "(?P[^"]+)"\ "(?P[^"]+)"$') -def sticker_list(context, field, uri): +def sticker__list(context, field, uri): """ *musicpd.org, sticker section:* @@ -64,7 +64,7 @@ def sticker_list(context, field, uri): @handle_request( r'sticker\ set\ "(?P[^"]+)"\ "(?P[^"]+)"\ ' r'"(?P[^"]+)"\ "(?P[^"]+)"$') -def sticker_set(context, field, uri, name, value): +def sticker__set(context, field, uri, name, value): """ *musicpd.org, sticker section:* diff --git a/mopidy/mpd/protocol/stored_playlists.py b/mopidy/mpd/protocol/stored_playlists.py index 6564236e..a852d795 100644 --- a/mopidy/mpd/protocol/stored_playlists.py +++ b/mopidy/mpd/protocol/stored_playlists.py @@ -24,7 +24,7 @@ def listplaylist(context, name): """ playlist = context.lookup_playlist_from_name(name) if not playlist: - raise MpdNoExistError('No such playlist', command='listplaylist') + raise MpdNoExistError('No such playlist') return ['file: %s' % t.uri for t in playlist.tracks] @@ -44,7 +44,7 @@ def listplaylistinfo(context, name): """ playlist = context.lookup_playlist_from_name(name) if not playlist: - raise MpdNoExistError('No such playlist', command='listplaylistinfo') + raise MpdNoExistError('No such playlist') return playlist_to_mpd_format(playlist) @@ -115,7 +115,7 @@ def load(context, name, start=None, end=None): """ playlist = context.lookup_playlist_from_name(name) if not playlist: - raise MpdNoExistError('No such playlist', command='load') + raise MpdNoExistError('No such playlist') if start is not None: start = int(start) if end is not None: diff --git a/tests/mpd/protocol/test_channels.py b/tests/mpd/protocol/test_channels.py index 5d4ee670..be3b96a8 100644 --- a/tests/mpd/protocol/test_channels.py +++ b/tests/mpd/protocol/test_channels.py @@ -6,20 +6,20 @@ from tests.mpd import protocol class ChannelsHandlerTest(protocol.BaseTestCase): def test_subscribe(self): self.sendRequest('subscribe "topic"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {subscribe} Not implemented') def test_unsubscribe(self): self.sendRequest('unsubscribe "topic"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {unsubscribe} Not implemented') def test_channels(self): self.sendRequest('channels') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {channels} Not implemented') def test_readmessages(self): self.sendRequest('readmessages') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {readmessages} Not implemented') def test_sendmessage(self): self.sendRequest('sendmessage "topic" "a message"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {sendmessage} Not implemented') diff --git a/tests/mpd/protocol/test_current_playlist.py b/tests/mpd/protocol/test_current_playlist.py index 34221fcd..dbb77d08 100644 --- a/tests/mpd/protocol/test_current_playlist.py +++ b/tests/mpd/protocol/test_current_playlist.py @@ -253,7 +253,7 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase): def test_playlistfind(self): self.sendRequest('playlistfind "tag" "needle"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {playlistfind} Not implemented') def test_playlistfind_by_filename_not_in_tracklist(self): self.sendRequest('playlistfind "filename" "file:///dev/null"') @@ -391,11 +391,11 @@ class CurrentPlaylistHandlerTest(protocol.BaseTestCase): def test_playlistsearch(self): self.sendRequest('playlistsearch "any" "needle"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {playlistsearch} Not implemented') def test_playlistsearch_without_quotes(self): self.sendRequest('playlistsearch any "needle"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {playlistsearch} Not implemented') def test_plchanges_with_lower_version_returns_changes(self): self.core.tracklist.add( diff --git a/tests/mpd/protocol/test_playback.py b/tests/mpd/protocol/test_playback.py index a572aabe..67b4e787 100644 --- a/tests/mpd/protocol/test_playback.py +++ b/tests/mpd/protocol/test_playback.py @@ -36,7 +36,7 @@ class PlaybackOptionsHandlerTest(protocol.BaseTestCase): def test_crossfade(self): self.sendRequest('crossfade "10"') - self.assertInResponse('ACK [0@0] {} Not implemented') + self.assertInResponse('ACK [0@0] {crossfade} Not implemented') def test_random_off(self): self.sendRequest('random "0"') @@ -135,15 +135,15 @@ class PlaybackOptionsHandlerTest(protocol.BaseTestCase): def test_replay_gain_mode_off(self): self.sendRequest('replay_gain_mode "off"') - self.assertInResponse('ACK [0@0] {} Not implemented') + self.assertInResponse('ACK [0@0] {replay_gain_mode} Not implemented') def test_replay_gain_mode_track(self): self.sendRequest('replay_gain_mode "track"') - self.assertInResponse('ACK [0@0] {} Not implemented') + self.assertInResponse('ACK [0@0] {replay_gain_mode} Not implemented') def test_replay_gain_mode_album(self): self.sendRequest('replay_gain_mode "album"') - self.assertInResponse('ACK [0@0] {} Not implemented') + self.assertInResponse('ACK [0@0] {replay_gain_mode} Not implemented') def test_replay_gain_status_default(self): self.sendRequest('replay_gain_status') diff --git a/tests/mpd/protocol/test_status.py b/tests/mpd/protocol/test_status.py index 8ded6938..7d30ea89 100644 --- a/tests/mpd/protocol/test_status.py +++ b/tests/mpd/protocol/test_status.py @@ -8,7 +8,7 @@ from tests.mpd import protocol class StatusHandlerTest(protocol.BaseTestCase): def test_clearerror(self): self.sendRequest('clearerror') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {clearerror} Not implemented') def test_currentsong(self): track = Track() diff --git a/tests/mpd/protocol/test_stickers.py b/tests/mpd/protocol/test_stickers.py index 31fd5da0..c3ce264a 100644 --- a/tests/mpd/protocol/test_stickers.py +++ b/tests/mpd/protocol/test_stickers.py @@ -7,29 +7,29 @@ class StickersHandlerTest(protocol.BaseTestCase): def test_sticker_get(self): self.sendRequest( 'sticker get "song" "file:///dev/urandom" "a_name"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {sticker} Not implemented') def test_sticker_set(self): self.sendRequest( 'sticker set "song" "file:///dev/urandom" "a_name" "a_value"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {sticker} Not implemented') def test_sticker_delete_with_name(self): self.sendRequest( 'sticker delete "song" "file:///dev/urandom" "a_name"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {sticker} Not implemented') def test_sticker_delete_without_name(self): self.sendRequest( 'sticker delete "song" "file:///dev/urandom"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {sticker} Not implemented') def test_sticker_list(self): self.sendRequest( 'sticker list "song" "file:///dev/urandom"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {sticker} Not implemented') def test_sticker_find(self): self.sendRequest( 'sticker find "song" "file:///dev/urandom" "a_name"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {sticker} Not implemented') diff --git a/tests/mpd/protocol/test_stored_playlists.py b/tests/mpd/protocol/test_stored_playlists.py index a65b3ed7..636c5c2c 100644 --- a/tests/mpd/protocol/test_stored_playlists.py +++ b/tests/mpd/protocol/test_stored_playlists.py @@ -189,28 +189,28 @@ class PlaylistsHandlerTest(protocol.BaseTestCase): def test_playlistadd(self): self.sendRequest('playlistadd "name" "dummy:a"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {playlistadd} Not implemented') def test_playlistclear(self): self.sendRequest('playlistclear "name"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {playlistclear} Not implemented') def test_playlistdelete(self): self.sendRequest('playlistdelete "name" "5"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {playlistdelete} Not implemented') def test_playlistmove(self): self.sendRequest('playlistmove "name" "5" "10"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {playlistmove} Not implemented') def test_rename(self): self.sendRequest('rename "old_name" "new_name"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {rename} Not implemented') def test_rm(self): self.sendRequest('rm "name"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {rm} Not implemented') def test_save(self): self.sendRequest('save "name"') - self.assertEqualResponse('ACK [0@0] {} Not implemented') + self.assertEqualResponse('ACK [0@0] {save} Not implemented') diff --git a/tests/mpd/test_exceptions.py b/tests/mpd/test_exceptions.py index b470ed44..ef84a5f9 100644 --- a/tests/mpd/test_exceptions.py +++ b/tests/mpd/test_exceptions.py @@ -25,7 +25,7 @@ class MpdExceptionsTest(unittest.TestCase): def test_get_mpd_ack_with_default_values(self): e = MpdAckError('A description') - self.assertEqual(e.get_mpd_ack(), 'ACK [0@0] {} A description') + self.assertEqual(e.get_mpd_ack(), 'ACK [0@0] {None} A description') def test_get_mpd_ack_with_values(self): try: @@ -38,24 +38,21 @@ class MpdExceptionsTest(unittest.TestCase): raise MpdUnknownCommand(command='play') except MpdAckError as e: self.assertEqual( - e.get_mpd_ack(), - 'ACK [5@0] {} unknown command "play"') + e.get_mpd_ack(), 'ACK [5@0] {} unknown command "play"') def test_mpd_no_command(self): try: raise MpdNoCommand except MpdAckError as e: self.assertEqual( - e.get_mpd_ack(), - 'ACK [5@0] {} No command given') + e.get_mpd_ack(), 'ACK [5@0] {} No command given') def test_mpd_system_error(self): try: raise MpdSystemError('foo') except MpdSystemError as e: self.assertEqual( - e.get_mpd_ack(), - 'ACK [52@0] {} foo') + e.get_mpd_ack(), 'ACK [52@0] {None} foo') def test_mpd_permission_error(self): try: