bpd: support the single command

This command instructs bpd to stop playing when the current song
finishes. In the MPD 0.20 protocol this flag gains a value 'oneshot' but
for now we just support its older version with a boolean value.
This commit is contained in:
Carl Suster 2019-04-01 16:26:00 +11:00
parent 71e7621642
commit bae9c40600
2 changed files with 27 additions and 2 deletions

View file

@ -174,6 +174,7 @@ class BaseServer(object):
self.random = False
self.repeat = False
self.consume = False
self.single = False
self.volume = VOLUME_MAX
self.crossfade = 0
self.mixrampdb = 0.0
@ -311,6 +312,7 @@ class BaseServer(object):
u'repeat: ' + six.text_type(int(self.repeat)),
u'random: ' + six.text_type(int(self.random)),
u'consume: ' + six.text_type(int(self.consume)),
u'single: ' + six.text_type(int(self.single)),
u'playlist: ' + six.text_type(self.playlist_version),
u'playlistlength: ' + six.text_type(len(self.playlist)),
u'mixrampdb: ' + six.text_type(self.mixrampdb),
@ -356,6 +358,11 @@ class BaseServer(object):
"""Set or unset consume mode."""
self.consume = cast_arg('intbool', state)
def cmd_single(self, conn, state):
"""Set or unset single mode."""
# TODO support oneshot in addition to 0 and 1 [MPD 0.20]
self.single = cast_arg('intbool', state)
def cmd_setvol(self, conn, vol):
"""Set the player's volume level (0-100)."""
vol = cast_arg(int, vol)
@ -534,6 +541,8 @@ class BaseServer(object):
if self.current_index >= len(self.playlist):
# Fallen off the end. Just move to stopped state.
return self.cmd_stop(conn)
elif self.single:
return self.cmd_stop(conn)
else:
return self.cmd_play(conn)

View file

@ -367,8 +367,8 @@ class BPDQueryTest(BPDTestHelper):
class BPDPlaybackTest(BPDTestHelper):
test_implements_playback = implements({
'random',
'repeat', 'single',
}, expectedFailure=True)
'repeat',
})
def test_cmd_consume(self):
with self.run_bpd() as client:
@ -391,6 +391,22 @@ class BPDPlaybackTest(BPDTestHelper):
self.assertEqual('1', responses[9].data['consume'])
self.assertEqual('play', responses[9].data['state'])
def test_cmd_single(self):
with self.run_bpd() as client:
self._bpd_add(client, self.item1, self.item2)
responses = client.send_commands(
('status',),
('single', '1'),
('play',),
('status',),
('next',),
('status',))
self._assert_ok(*responses)
self.assertEqual('0', responses[0].data['single'])
self.assertEqual('1', responses[3].data['single'])
self.assertEqual('play', responses[3].data['state'])
self.assertEqual('stop', responses[5].data['state'])
def test_cmd_crossfade(self):
with self.run_bpd() as client:
responses = client.send_commands(