From 9182f18e6f98ff0bfd5e15d4ba92d4b68be36beb Mon Sep 17 00:00:00 2001 From: Carl Suster Date: Sat, 13 Apr 2019 16:25:09 +1000 Subject: [PATCH] bpd: support short form of list command for albums Some clients list the albums belonging to an artist by issuing the command `list album `. This change inserts the tag `artist` before the artist name so that this succeeds. Fixes #3007 --- beetsplug/bpd/__init__.py | 15 +++++++++++++++ test/test_player.py | 14 ++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/beetsplug/bpd/__init__.py b/beetsplug/bpd/__init__.py index 11fec0890..a70c6ecd6 100644 --- a/beetsplug/bpd/__init__.py +++ b/beetsplug/bpd/__init__.py @@ -1404,16 +1404,31 @@ class Server(BaseServer): filtered by matching match_tag to match_term. """ show_tag_canon, show_key = self._tagtype_lookup(show_tag) + if len(kv) == 1: + if show_tag_canon == 'Album': + # If no tag was given, assume artist. This is because MPD + # supports a short version of this command for fetching the + # albums belonging to a particular artist, and some clients + # rely on this behaviour (e.g. MPDroid, M.A.L.P.). + kv = ('Artist', kv[0]) + else: + raise BPDError(ERROR_ARG, u'should be "Album" for 3 arguments') + elif len(kv) % 2 != 0: + raise BPDError(ERROR_ARG, u'Incorrect number of filter arguments') query = self._metadata_query(dbcore.query.MatchQuery, None, kv) clause, subvals = query.clause() statement = 'SELECT DISTINCT ' + show_key + \ ' FROM items WHERE ' + clause + \ ' ORDER BY ' + show_key + self._log.debug(statement) with self.lib.transaction() as tx: rows = tx.query(statement, subvals) for row in rows: + if not row[0]: + # Skip any empty values of the field. + continue yield show_tag_canon + u': ' + six.text_type(row[0]) def cmd_count(self, conn, tag, value): diff --git a/test/test_player.py b/test/test_player.py index 6cc0869a7..d7c9dba17 100644 --- a/test/test_player.py +++ b/test/test_player.py @@ -774,11 +774,21 @@ class BPDDatabaseTest(BPDTestHelper): with self.run_bpd() as client: responses = client.send_commands( ('list', 'album'), - ('list', 'track')) - self._assert_ok(*responses) + ('list', 'track'), + ('list', 'album', 'artist', 'Artist Name', 'track')) + self._assert_failed(responses, bpd.ERROR_ARG, pos=2) self.assertEqual('Album Title', responses[0].data['Album']) self.assertEqual(['1', '2'], responses[1].data['Track']) + def test_cmd_list_three_arg_form(self): + with self.run_bpd() as client: + responses = client.send_commands( + ('list', 'album', 'artist', 'Artist Name'), + ('list', 'album', 'Artist Name'), + ('list', 'track', 'Artist Name')) + self._assert_failed(responses, bpd.ERROR_ARG, pos=2) + self.assertEqual(responses[0].data, responses[1].data) + def test_cmd_lsinfo(self): with self.run_bpd() as client: response1 = client.send_command('lsinfo')