From 2b59b917c4a7393f907a71ac7bb39bcb912d0fdc Mon Sep 17 00:00:00 2001 From: Matt Colyer Date: Mon, 31 Jul 2017 23:16:05 -0700 Subject: [PATCH] Allow sonos to select playlists as a source (#8258) * Allow sonos to select playlists as a source Most of this was taken from https://github.com/home-assistant/home-assistant/issues/5598#issuecomment-278229895 however I made a few small improvements so that it works for other services than Spotify and it should properly switch to playing the queue if you had another song playing previously. /cc @PatBoud * Attempt to fix style issues * More indent changes * Fix misplaced period * Move playlist replacement to function * Privatize replace_queue_with_playlist and explain * Remove unneeded decorator * Fix doc formatting --- .../components/media_player/sonos.py | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/media_player/sonos.py b/homeassistant/components/media_player/sonos.py index 33decf35f89..e51f3d70f2c 100644 --- a/homeassistant/components/media_player/sonos.py +++ b/homeassistant/components/media_player/sonos.py @@ -893,7 +893,44 @@ class SonosDevice(MediaPlayerDevice): if len(fav) == 1: src = fav.pop() self._source_name = src['title'] - self._player.play_uri(src['uri'], src['meta'], src['title']) + + if 'object.container.playlistContainer' in src['meta']: + self._replace_queue_with_playlist(src) + self._player.play_from_queue(0) + else: + self._player.play_uri(src['uri'], src['meta'], + src['title']) + + def _replace_queue_with_playlist(self, src): + """Replace queue with playlist represented by src. + + Playlists can't be played directly with the self._player.play_uri + API as they are actually composed of mulitple URLs. Until soco has + suppport for playing a playlist, we'll need to parse the playlist item + and replace the current queue in order to play it. + """ + import soco + import xml.etree.ElementTree as ET + + root = ET.fromstring(src['meta']) + namespaces = {'item': + 'urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/', + 'desc': 'urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/'} + desc = root.find('item:item', namespaces).find('desc:desc', + namespaces).text + + res = [soco.data_structures.DidlResource(uri=src['uri'], + protocol_info="DUMMY")] + didl = soco.data_structures.DidlItem(title="DUMMY", + parent_id="DUMMY", + item_id=src['uri'], + desc=desc, + resources=res) + + self._player.stop() + self._player.clear_queue() + self._player.play_mode = 'NORMAL' + self._player.add_to_queue(didl) @property def source_list(self):