From 987f155b1601bd80d91dc70c0703aa713dd8b6df Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 17:47:36 -0600 Subject: [PATCH 01/17] use media player proxy for roku media browser images --- homeassistant/components/roku/media_player.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/roku/media_player.py b/homeassistant/components/roku/media_player.py index 0e035106824d58..c9993047315971 100644 --- a/homeassistant/components/roku/media_player.py +++ b/homeassistant/components/roku/media_player.py @@ -238,6 +238,19 @@ async def search(self, keyword): """Emulate opening the search screen and entering the search keyword.""" await self.coordinator.roku.search(keyword) + async def async_get_browse_image( + self, media_content_type, media_content_id, media_image_id=None + ): + """Fetch media browser image to serve via proxy.""" + if media_content_type === MEDIA_TYPE_APP and media_content_id: + image_url = self.coordinator.roku.app_icon_url(media_content_id) + result = await self._async_fetch_image(image_url) + if result == (None, None): + _LOGGER.debug("Error retrieving proxied album art from %s", image_url) + return result + + return (None, None) + async def async_browse_media(self, media_content_type=None, media_content_id=None): """Implement the websocket media browsing helper.""" if media_content_type in [None, "library"]: @@ -247,7 +260,11 @@ async def async_browse_media(self, media_content_type=None, media_content_id=Non "search_type": media_content_type, "search_id": media_content_id, } - response = build_item_response(self.coordinator, payload) + + async def _async_get_thumbnail_url(*args, **kwargs): + return await self.get_browse_image_url(*args, **kwargs) + + response = build_item_response(self.coordinator, payload, _async_get_thumbnail_url) if response is None: raise BrowseError( From a3b8a1ecd2a466f4a8c744e1e4afe8bf729ecd97 Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 17:50:54 -0600 Subject: [PATCH 02/17] Update browse_media.py --- homeassistant/components/roku/browse_media.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/roku/browse_media.py b/homeassistant/components/roku/browse_media.py index b5be3e99d9a094..c1a5b799a4fcbd 100644 --- a/homeassistant/components/roku/browse_media.py +++ b/homeassistant/components/roku/browse_media.py @@ -81,7 +81,7 @@ def build_item_response(coordinator, payload): ) -def item_payload(item, coordinator): +def item_payload(item, coordinator, get_thumbnail_url): """ Create response payload for a single media item. @@ -92,7 +92,7 @@ def item_payload(item, coordinator): if "app_id" in item: media_content_type = MEDIA_TYPE_APP media_content_id = item["app_id"] - thumbnail = coordinator.roku.app_icon_url(item["app_id"]) + thumbnail = get_thumbnail_url(media_content_type, media_content_id) elif "channel_number" in item: media_content_type = MEDIA_TYPE_CHANNEL media_content_id = item["channel_number"] From e33ef6a5921f8172f209ab1130c838c25273f257 Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 17:52:14 -0600 Subject: [PATCH 03/17] Update media_player.py --- homeassistant/components/roku/media_player.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/roku/media_player.py b/homeassistant/components/roku/media_player.py index c9993047315971..dc1798f62d1aa1 100644 --- a/homeassistant/components/roku/media_player.py +++ b/homeassistant/components/roku/media_player.py @@ -261,10 +261,10 @@ async def async_browse_media(self, media_content_type=None, media_content_id=Non "search_id": media_content_id, } - async def _async_get_thumbnail_url(*args, **kwargs): - return await self.get_browse_image_url(*args, **kwargs) + def _get_thumbnail_url(*args, **kwargs): + return self.get_browse_image_url(*args, **kwargs) - response = build_item_response(self.coordinator, payload, _async_get_thumbnail_url) + response = build_item_response(self.coordinator, payload, _get_thumbnail_url) if response is None: raise BrowseError( From d24168b8749a6e30ec37513408200a929498f261 Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 17:55:28 -0600 Subject: [PATCH 04/17] Update browse_media.py --- homeassistant/components/roku/browse_media.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/roku/browse_media.py b/homeassistant/components/roku/browse_media.py index c1a5b799a4fcbd..cdbf96e3fc9549 100644 --- a/homeassistant/components/roku/browse_media.py +++ b/homeassistant/components/roku/browse_media.py @@ -81,7 +81,7 @@ def build_item_response(coordinator, payload): ) -def item_payload(item, coordinator, get_thumbnail_url): +def item_payload(item, coordinator, get_thumbnail_url=None): """ Create response payload for a single media item. @@ -92,7 +92,8 @@ def item_payload(item, coordinator, get_thumbnail_url): if "app_id" in item: media_content_type = MEDIA_TYPE_APP media_content_id = item["app_id"] - thumbnail = get_thumbnail_url(media_content_type, media_content_id) + if get_thumbnail_url; + thumbnail = get_thumbnail_url(media_content_type, media_content_id) elif "channel_number" in item: media_content_type = MEDIA_TYPE_CHANNEL media_content_id = item["channel_number"] From f0a5f12ce4590f58531c714850007609bced5aba Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 17:58:53 -0600 Subject: [PATCH 05/17] Update browse_media.py --- homeassistant/components/roku/browse_media.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/roku/browse_media.py b/homeassistant/components/roku/browse_media.py index cdbf96e3fc9549..e065bbb5959d9c 100644 --- a/homeassistant/components/roku/browse_media.py +++ b/homeassistant/components/roku/browse_media.py @@ -34,7 +34,7 @@ ] -def build_item_response(coordinator, payload): +def build_item_response(coordinator, payload, get_thumbnail_url=None): """Create response payload for the provided media query.""" search_id = payload["search_id"] search_type = payload["search_type"] @@ -75,7 +75,9 @@ def build_item_response(coordinator, payload): title=title, can_play=search_type in PLAYABLE_MEDIA_TYPES and search_id, can_expand=True, - children=[item_payload(item, coordinator) for item in media], + children=[ + item_payload(item, coordinator, get_thumbnail_url) for item in media + ], children_media_class=children_media_class, thumbnail=thumbnail, ) From 99dfb5bdb1b02557c360044ac1d68900717ada6a Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 18:02:08 -0600 Subject: [PATCH 06/17] Update media_player.py --- homeassistant/components/roku/media_player.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/roku/media_player.py b/homeassistant/components/roku/media_player.py index dc1798f62d1aa1..53b05d5a1a6a5f 100644 --- a/homeassistant/components/roku/media_player.py +++ b/homeassistant/components/roku/media_player.py @@ -242,11 +242,11 @@ async def async_get_browse_image( self, media_content_type, media_content_id, media_image_id=None ): """Fetch media browser image to serve via proxy.""" - if media_content_type === MEDIA_TYPE_APP and media_content_id: + if media_content_type == MEDIA_TYPE_APP and media_content_id: image_url = self.coordinator.roku.app_icon_url(media_content_id) result = await self._async_fetch_image(image_url) if result == (None, None): - _LOGGER.debug("Error retrieving proxied album art from %s", image_url) + _LOGGER.debug("Error retrieving proxied image from %s", image_url) return result return (None, None) From 71671db5ab8988df4f13abe3c25fa7c6fd8ebd0d Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 18:06:38 -0600 Subject: [PATCH 07/17] Update browse_media.py --- homeassistant/components/roku/browse_media.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/roku/browse_media.py b/homeassistant/components/roku/browse_media.py index e065bbb5959d9c..daf01779a0d499 100644 --- a/homeassistant/components/roku/browse_media.py +++ b/homeassistant/components/roku/browse_media.py @@ -94,7 +94,7 @@ def item_payload(item, coordinator, get_thumbnail_url=None): if "app_id" in item: media_content_type = MEDIA_TYPE_APP media_content_id = item["app_id"] - if get_thumbnail_url; + if get_thumbnail_url: thumbnail = get_thumbnail_url(media_content_type, media_content_id) elif "channel_number" in item: media_content_type = MEDIA_TYPE_CHANNEL From 71bcbbc63d0fa7658a400c798b23edb4ffa428f1 Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 18:22:21 -0600 Subject: [PATCH 08/17] Update browse_media.py --- homeassistant/components/roku/browse_media.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/homeassistant/components/roku/browse_media.py b/homeassistant/components/roku/browse_media.py index daf01779a0d499..0e080166af2f15 100644 --- a/homeassistant/components/roku/browse_media.py +++ b/homeassistant/components/roku/browse_media.py @@ -75,9 +75,7 @@ def build_item_response(coordinator, payload, get_thumbnail_url=None): title=title, can_play=search_type in PLAYABLE_MEDIA_TYPES and search_id, can_expand=True, - children=[ - item_payload(item, coordinator, get_thumbnail_url) for item in media - ], + children=[item_payload(item, coordinator, get_thumbnail_url) for item in media], children_media_class=children_media_class, thumbnail=thumbnail, ) From 8bf329653ef6f799f68e2c877db09f1c483b6bef Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 18:23:40 -0600 Subject: [PATCH 09/17] Update media_player.py --- homeassistant/components/roku/media_player.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/roku/media_player.py b/homeassistant/components/roku/media_player.py index 53b05d5a1a6a5f..280121f0e4ee63 100644 --- a/homeassistant/components/roku/media_player.py +++ b/homeassistant/components/roku/media_player.py @@ -253,17 +253,17 @@ async def async_get_browse_image( async def async_browse_media(self, media_content_type=None, media_content_id=None): """Implement the websocket media browsing helper.""" + + def _get_thumbnail_url(*args, **kwargs): + return self.get_browse_image_url(*args, **kwargs) + if media_content_type in [None, "library"]: - return library_payload(self.coordinator) + return library_payload(self.coordinator, _get_thumbnail_url) payload = { "search_type": media_content_type, "search_id": media_content_id, } - - def _get_thumbnail_url(*args, **kwargs): - return self.get_browse_image_url(*args, **kwargs) - response = build_item_response(self.coordinator, payload, _get_thumbnail_url) if response is None: From be8e76165439e14b13cbcd9b9257dc8d5cc52608 Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 18:24:44 -0600 Subject: [PATCH 10/17] Update browse_media.py --- homeassistant/components/roku/browse_media.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/roku/browse_media.py b/homeassistant/components/roku/browse_media.py index 0e080166af2f15..8110174450e9a6 100644 --- a/homeassistant/components/roku/browse_media.py +++ b/homeassistant/components/roku/browse_media.py @@ -116,7 +116,7 @@ def item_payload(item, coordinator, get_thumbnail_url=None): ) -def library_payload(coordinator): +def library_payload(coordinator, get_thumbnail_url=None): """ Create response payload to describe contents of a specific library. @@ -148,6 +148,7 @@ def library_payload(coordinator): item_payload( {"title": item["title"], "type": item["type"]}, coordinator, + get_thumbnail_url, ) ) From 2a841c51801451e95f0ba28b65d1c421b8168493 Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 18:44:22 -0600 Subject: [PATCH 11/17] Update __init__.py --- homeassistant/components/media_player/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index 4fb0cdae33eeeb..6a68d985e7f802 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -914,7 +914,7 @@ def get_browse_image_url( URL(url_path).with_query( { "token": self.access_token, - "media_image_id": media_image_id, + "media_image_id": media_image_id if media_image_id, } ) ) From 9d26ff64878891980d966b1f2f42729cfae012c7 Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 19:01:51 -0600 Subject: [PATCH 12/17] Update __init__.py --- homeassistant/components/media_player/__init__.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index 6a68d985e7f802..743f18bf663cc1 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -910,15 +910,12 @@ def get_browse_image_url( f"/api/media_player_proxy/{self.entity_id}/browse_media" f"/{media_content_type}/{media_content_id}" ) - url = str( - URL(url_path).with_query( - { - "token": self.access_token, - "media_image_id": media_image_id if media_image_id, - } - ) - ) - return url + + url_query = {"token": self.access_token} + if media_image_id: + url_query.update({"media_image_id": media_image_id}) + + return str(URL(url_path).with_query(url_query)) class MediaPlayerImageView(HomeAssistantView): From 87d2e17b08a871bc433f52dc80991f5c1a9326d9 Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 19:25:15 -0600 Subject: [PATCH 13/17] Update test_media_player.py --- tests/components/roku/test_media_player.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/components/roku/test_media_player.py b/tests/components/roku/test_media_player.py index b4ce1811c915bb..f7969ee186d3f3 100644 --- a/tests/components/roku/test_media_player.py +++ b/tests/components/roku/test_media_player.py @@ -539,8 +539,7 @@ async def test_media_browse(hass, aioclient_mock, hass_ws_client): assert msg["result"]["children"][0]["media_content_type"] == MEDIA_TYPE_APP assert msg["result"]["children"][0]["media_content_id"] == "tvinput.hdmi2" assert ( - msg["result"]["children"][0]["thumbnail"] - == "http://192.168.1.161:8060/query/icon/tvinput.hdmi2" + "/browse_media/app/tvinput.hdmi2" in msg["result"]["children"][0]["thumbnail"] ) assert msg["result"]["children"][0]["can_play"] @@ -548,8 +547,7 @@ async def test_media_browse(hass, aioclient_mock, hass_ws_client): assert msg["result"]["children"][3]["media_content_type"] == MEDIA_TYPE_APP assert msg["result"]["children"][3]["media_content_id"] == "11" assert ( - msg["result"]["children"][3]["thumbnail"] - == "http://192.168.1.161:8060/query/icon/11" + "/browse_media/app/11" in msg["result"]["children"][3]["thumbnail"] ) assert msg["result"]["children"][3]["can_play"] From fe5c8398403544e60cfe4c384854eff5b85c33cd Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Tue, 10 Nov 2020 19:43:13 -0600 Subject: [PATCH 14/17] Update test_media_player.py --- tests/components/roku/test_media_player.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/components/roku/test_media_player.py b/tests/components/roku/test_media_player.py index f7969ee186d3f3..23dd9dbc6c8dc1 100644 --- a/tests/components/roku/test_media_player.py +++ b/tests/components/roku/test_media_player.py @@ -546,9 +546,7 @@ async def test_media_browse(hass, aioclient_mock, hass_ws_client): assert msg["result"]["children"][3]["title"] == "Roku Channel Store" assert msg["result"]["children"][3]["media_content_type"] == MEDIA_TYPE_APP assert msg["result"]["children"][3]["media_content_id"] == "11" - assert ( - "/browse_media/app/11" in msg["result"]["children"][3]["thumbnail"] - ) + assert "/browse_media/app/11" in msg["result"]["children"][3]["thumbnail"] assert msg["result"]["children"][3]["can_play"] # test channels From 13d4ac2e91db6b19457cb3e1fa4f5218799e657d Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Wed, 11 Nov 2020 09:22:21 -0600 Subject: [PATCH 15/17] Update __init__.py --- homeassistant/components/media_player/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index 743f18bf663cc1..fb253f5930c733 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -913,7 +913,7 @@ def get_browse_image_url( url_query = {"token": self.access_token} if media_image_id: - url_query.update({"media_image_id": media_image_id}) + url_query["media_image_id"] = media_image_id return str(URL(url_path).with_query(url_query)) @@ -962,6 +962,7 @@ async def get( data, content_type = await player.async_get_media_image() if data is None: + _LOGGER.warning("Error retrieving proxied image from %s", image_url) return web.Response(status=HTTP_INTERNAL_SERVER_ERROR) headers: LooseHeaders = {CACHE_CONTROL: "max-age=3600"} From 6292fad80836813b8aa69733c340f4e7485f3f7f Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Wed, 11 Nov 2020 09:23:19 -0600 Subject: [PATCH 16/17] Update media_player.py --- homeassistant/components/roku/media_player.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/homeassistant/components/roku/media_player.py b/homeassistant/components/roku/media_player.py index 280121f0e4ee63..e1662972cf64b8 100644 --- a/homeassistant/components/roku/media_player.py +++ b/homeassistant/components/roku/media_player.py @@ -244,10 +244,7 @@ async def async_get_browse_image( """Fetch media browser image to serve via proxy.""" if media_content_type == MEDIA_TYPE_APP and media_content_id: image_url = self.coordinator.roku.app_icon_url(media_content_id) - result = await self._async_fetch_image(image_url) - if result == (None, None): - _LOGGER.debug("Error retrieving proxied image from %s", image_url) - return result + return await self._async_fetch_image(image_url) return (None, None) From 9ebd887cd79e32363d8073653b4cfdc375054666 Mon Sep 17 00:00:00 2001 From: Chris Talkington Date: Wed, 11 Nov 2020 09:57:40 -0600 Subject: [PATCH 17/17] Update __init__.py --- homeassistant/components/media_player/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index fb253f5930c733..71db60baa2e725 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -900,6 +900,9 @@ async def _async_fetch_image(self, url): except asyncio.TimeoutError: pass + if content is None: + _LOGGER.warning("Error retrieving proxied image from %s", url) + return content, content_type def get_browse_image_url( @@ -962,7 +965,6 @@ async def get( data, content_type = await player.async_get_media_image() if data is None: - _LOGGER.warning("Error retrieving proxied image from %s", image_url) return web.Response(status=HTTP_INTERNAL_SERVER_ERROR) headers: LooseHeaders = {CACHE_CONTROL: "max-age=3600"}