From b95c8032de14cdb7a92620eb45bf7a7259532497 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 15 Dec 2012 01:18:13 +0100 Subject: [PATCH] mpd: Add 'searchaddpl' command --- docs/changes.rst | 2 + mopidy/frontends/mpd/protocol/music_db.py | 35 +++++++++++++++++ tests/frontends/mpd/protocol/music_db_test.py | 38 +++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/docs/changes.rst b/docs/changes.rst index 83252a9c..8add66e1 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -21,6 +21,8 @@ v0.11.0 (in development) - Add support for ``searchadd`` command added in MPD 0.17. +- Add support for ``searchaddpl`` command added in MPD 0.17. + v0.10.0 (2012-12-12) ==================== diff --git a/mopidy/frontends/mpd/protocol/music_db.py b/mopidy/frontends/mpd/protocol/music_db.py index 2c0a2c32..66735538 100644 --- a/mopidy/frontends/mpd/protocol/music_db.py +++ b/mopidy/frontends/mpd/protocol/music_db.py @@ -402,6 +402,41 @@ def searchadd(context, mpd_query): context.core.tracklist.add(result) +@handle_request( + r'^searchaddpl ' + r'"(?P[^"]+)" ' + r'(?P("?([Aa]lbum|[Aa]rtist|[Dd]ate|[Ff]ile[name]*|' + r'[Tt]itle|[Aa]ny)"? "[^"]*"\s?)+)$') +def searchaddpl(context, playlist_name, mpd_query): + """ + *musicpd.org, music database section:* + + ``searchaddpl {NAME} {TYPE} {WHAT} [...]`` + + Searches for any song that contains ``WHAT`` in tag ``TYPE`` and adds + them to the playlist named ``NAME``. + + If a playlist by that name doesn't exist it is created. + + Parameters have the same meaning as for ``find``, except that search is + not case sensitive. + """ + try: + query = _build_query(mpd_query) + except ValueError: + return + result = context.core.library.search(**query).get() + + playlists = context.core.playlists.filter(name=playlist_name).get() + if playlists: + playlist = playlists[0] + else: + playlist = context.core.playlists.create(playlist_name).get() + tracks = list(playlist.tracks) + result + playlist = playlist.copy(tracks=tracks) + context.core.playlists.save(playlist) + + @handle_request(r'^update( "(?P[^"]+)")*$') def update(context, uri=None, rescan_unmodified_files=False): """ diff --git a/tests/frontends/mpd/protocol/music_db_test.py b/tests/frontends/mpd/protocol/music_db_test.py index 13f0759b..5c887958 100644 --- a/tests/frontends/mpd/protocol/music_db_test.py +++ b/tests/frontends/mpd/protocol/music_db_test.py @@ -36,6 +36,44 @@ class MusicDatabaseHandlerTest(protocol.BaseTestCase): self.assertEqual(self.core.tracklist.tracks.get()[0].uri, 'dummy:a') self.assertInResponse('OK') + def test_searchaddpl_appends_to_existing_playlist(self): + playlist = self.core.playlists.create('my favs').get() + playlist = playlist.copy(tracks=[ + Track(uri='dummy:x', name='X'), + Track(uri='dummy:y', name='y'), + ]) + self.core.playlists.save(playlist) + self.backend.library.dummy_search_result = [ + Track(uri='dummy:a', name='A'), + ] + playlists = self.core.playlists.filter(name='my favs').get() + self.assertEqual(len(playlists), 1) + self.assertEqual(len(playlists[0].tracks), 2) + + self.sendRequest('searchaddpl "my favs" "title" "a"') + + playlists = self.core.playlists.filter(name='my favs').get() + self.assertEqual(len(playlists), 1) + self.assertEqual(len(playlists[0].tracks), 3) + self.assertEqual(playlists[0].tracks[0].uri, 'dummy:x') + self.assertEqual(playlists[0].tracks[1].uri, 'dummy:y') + self.assertEqual(playlists[0].tracks[2].uri, 'dummy:a') + self.assertInResponse('OK') + + def test_searchaddpl_creates_missing_playlist(self): + self.backend.library.dummy_search_result = [ + Track(uri='dummy:a', name='A'), + ] + self.assertEqual( + len(self.core.playlists.filter(name='my favs').get()), 0) + + self.sendRequest('searchaddpl "my favs" "title" "a"') + + playlists = self.core.playlists.filter(name='my favs').get() + self.assertEqual(len(playlists), 1) + self.assertEqual(playlists[0].tracks[0].uri, 'dummy:a') + self.assertInResponse('OK') + def test_listall(self): self.sendRequest('listall "file:///dev/urandom"') self.assertEqualResponse('ACK [0@0] {} Not implemented')