Remove websocket_api send_big_result (#75452)

This commit is contained in:
uvjustin 2022-07-20 12:08:11 +08:00 committed by GitHub
parent 51ed9ee59d
commit d989e4373d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 27 additions and 201 deletions

View file

@ -2,7 +2,6 @@
from __future__ import annotations from __future__ import annotations
import asyncio import asyncio
import base64
import collections import collections
from collections.abc import Awaitable, Callable, Iterable from collections.abc import Awaitable, Callable, Iterable
from contextlib import suppress from contextlib import suppress
@ -362,12 +361,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
hass.http.register_view(CameraImageView(component)) hass.http.register_view(CameraImageView(component))
hass.http.register_view(CameraMjpegStream(component)) hass.http.register_view(CameraMjpegStream(component))
websocket_api.async_register_command(
hass,
WS_TYPE_CAMERA_THUMBNAIL,
websocket_camera_thumbnail,
SCHEMA_WS_CAMERA_THUMBNAIL,
)
websocket_api.async_register_command(hass, ws_camera_stream) websocket_api.async_register_command(hass, ws_camera_stream)
websocket_api.async_register_command(hass, ws_camera_web_rtc_offer) websocket_api.async_register_command(hass, ws_camera_web_rtc_offer)
websocket_api.async_register_command(hass, websocket_get_prefs) websocket_api.async_register_command(hass, websocket_get_prefs)
@ -793,32 +787,6 @@ class CameraMjpegStream(CameraView):
raise web.HTTPBadRequest() from err raise web.HTTPBadRequest() from err
@websocket_api.async_response
async def websocket_camera_thumbnail(
hass: HomeAssistant, connection: ActiveConnection, msg: dict
) -> None:
"""Handle get camera thumbnail websocket command.
Async friendly.
"""
_LOGGER.warning("The websocket command 'camera_thumbnail' has been deprecated")
try:
image = await async_get_image(hass, msg["entity_id"])
connection.send_big_result(
msg["id"],
{
"content_type": image.content_type,
"content": base64.b64encode(image.content).decode("utf-8"),
},
)
except HomeAssistantError:
connection.send_message(
websocket_api.error_message(
msg["id"], "image_fetch_failed", "Unable to fetch image"
)
)
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required("type"): "camera/stream", vol.Required("type"): "camera/stream",

View file

@ -37,9 +37,6 @@ def _handle_errors(func):
connection.send_error(msg["id"], *error) connection.send_error(msg["id"], *error)
return return
if msg is not None:
connection.send_big_result(msg["id"], result)
else:
connection.send_result(msg["id"], result) connection.send_result(msg["id"], result)
return send_with_error_handling return send_with_error_handling

View file

@ -2,7 +2,6 @@
from __future__ import annotations from __future__ import annotations
import asyncio import asyncio
import base64
import collections import collections
from collections.abc import Callable from collections.abc import Callable
from contextlib import suppress from contextlib import suppress
@ -27,7 +26,6 @@ from homeassistant.backports.enum import StrEnum
from homeassistant.components import websocket_api from homeassistant.components import websocket_api
from homeassistant.components.http import KEY_AUTHENTICATED, HomeAssistantView from homeassistant.components.http import KEY_AUTHENTICATED, HomeAssistantView
from homeassistant.components.websocket_api.const import ( from homeassistant.components.websocket_api.const import (
ERR_NOT_FOUND,
ERR_NOT_SUPPORTED, ERR_NOT_SUPPORTED,
ERR_UNKNOWN_ERROR, ERR_UNKNOWN_ERROR,
) )
@ -254,7 +252,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL
) )
websocket_api.async_register_command(hass, websocket_handle_thumbnail)
websocket_api.async_register_command(hass, websocket_browse_media) websocket_api.async_register_command(hass, websocket_browse_media)
hass.http.register_view(MediaPlayerImageView(component)) hass.http.register_view(MediaPlayerImageView(component))
@ -1130,49 +1127,6 @@ class MediaPlayerImageView(HomeAssistantView):
return web.Response(body=data, content_type=content_type, headers=headers) return web.Response(body=data, content_type=content_type, headers=headers)
@websocket_api.websocket_command(
{
vol.Required("type"): "media_player_thumbnail",
vol.Required("entity_id"): cv.entity_id,
}
)
@websocket_api.async_response
async def websocket_handle_thumbnail(hass, connection, msg):
"""Handle get media player cover command.
Async friendly.
"""
component = hass.data[DOMAIN]
if (player := component.get_entity(msg["entity_id"])) is None:
connection.send_message(
websocket_api.error_message(msg["id"], ERR_NOT_FOUND, "Entity not found")
)
return
_LOGGER.warning(
"The websocket command media_player_thumbnail is deprecated. Use /api/media_player_proxy instead"
)
data, content_type = await player.async_get_media_image()
if data is None:
connection.send_message(
websocket_api.error_message(
msg["id"], "thumbnail_fetch_failed", "Failed to fetch thumbnail"
)
)
return
connection.send_big_result(
msg["id"],
{
"content_type": content_type,
"content": base64.b64encode(data).decode("utf-8"),
},
)
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required("type"): "media_player/browse_media", vol.Required("type"): "media_player/browse_media",

View file

@ -11,7 +11,6 @@ import voluptuous as vol
from homeassistant.auth.models import RefreshToken, User from homeassistant.auth.models import RefreshToken, User
from homeassistant.core import Context, HomeAssistant, callback from homeassistant.core import Context, HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError, Unauthorized from homeassistant.exceptions import HomeAssistantError, Unauthorized
from homeassistant.helpers.json import JSON_DUMP
from . import const, messages from . import const, messages
@ -54,10 +53,6 @@ class ActiveConnection:
"""Send a result message.""" """Send a result message."""
self.send_message(messages.result_message(msg_id, result)) self.send_message(messages.result_message(msg_id, result))
def send_big_result(self, msg_id: int, result: Any) -> None:
"""Send a result message that would be expensive to JSON serialize."""
self.send_message(JSON_DUMP(messages.result_message(msg_id, result)))
@callback @callback
def send_error(self, msg_id: int, code: str, message: str) -> None: def send_error(self, msg_id: int, code: str, message: str) -> None:
"""Send a error message.""" """Send a error message."""

View file

@ -1,5 +1,4 @@
"""The tests for the androidtv platform.""" """The tests for the androidtv platform."""
import base64
import logging import logging
from unittest.mock import Mock, patch from unittest.mock import Mock, patch
@ -52,7 +51,6 @@ from homeassistant.components.media_player import (
SERVICE_VOLUME_SET, SERVICE_VOLUME_SET,
SERVICE_VOLUME_UP, SERVICE_VOLUME_UP,
) )
from homeassistant.components.websocket_api.const import TYPE_RESULT
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import ( from homeassistant.const import (
ATTR_COMMAND, ATTR_COMMAND,
@ -851,10 +849,10 @@ async def test_androidtv_volume_set(hass):
patch_set_volume_level.assert_called_with(0.5) patch_set_volume_level.assert_called_with(0.5)
async def test_get_image(hass, hass_ws_client): async def test_get_image_http(hass, hass_client_no_auth):
"""Test taking a screen capture. """Test taking a screen capture.
This is based on `test_get_image` in tests/components/media_player/test_init.py. This is based on `test_get_image_http` in tests/components/media_player/test_init.py.
""" """
patch_key, entity_id, config_entry = _setup(CONFIG_ANDROIDTV_DEFAULT) patch_key, entity_id, config_entry = _setup(CONFIG_ANDROIDTV_DEFAULT)
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
@ -868,44 +866,36 @@ async def test_get_image(hass, hass_ws_client):
with patchers.patch_shell("11")[patch_key]: with patchers.patch_shell("11")[patch_key]:
await async_update_entity(hass, entity_id) await async_update_entity(hass, entity_id)
client = await hass_ws_client(hass) media_player_name = "media_player." + slugify(
CONFIG_ANDROIDTV_DEFAULT[TEST_ENTITY_NAME]
)
state = hass.states.get(media_player_name)
assert "entity_picture_local" not in state.attributes
client = await hass_client_no_auth()
with patch( with patch(
"androidtv.basetv.basetv_async.BaseTVAsync.adb_screencap", return_value=b"image" "androidtv.basetv.basetv_async.BaseTVAsync.adb_screencap", return_value=b"image"
): ):
await client.send_json( resp = await client.get(state.attributes["entity_picture"])
{"id": 5, "type": "media_player_thumbnail", "entity_id": entity_id} content = await resp.read()
)
msg = await client.receive_json() assert content == b"image"
assert msg["id"] == 5
assert msg["type"] == TYPE_RESULT
assert msg["success"]
assert msg["result"]["content_type"] == "image/png"
assert msg["result"]["content"] == base64.b64encode(b"image").decode("utf-8")
with patch( with patch(
"androidtv.basetv.basetv_async.BaseTVAsync.adb_screencap", "androidtv.basetv.basetv_async.BaseTVAsync.adb_screencap",
side_effect=ConnectionResetError, side_effect=ConnectionResetError,
): ):
await client.send_json( resp = await client.get(state.attributes["entity_picture"])
{"id": 6, "type": "media_player_thumbnail", "entity_id": entity_id}
)
msg = await client.receive_json()
# The device is unavailable, but getting the media image did not cause an exception # The device is unavailable, but getting the media image did not cause an exception
state = hass.states.get(entity_id) state = hass.states.get(media_player_name)
assert state is not None assert state is not None
assert state.state == STATE_UNAVAILABLE assert state.state == STATE_UNAVAILABLE
async def test_get_image_disabled(hass, hass_ws_client): async def test_get_image_disabled(hass):
"""Test taking a screen capture with screencap option disabled. """Test that the screencap option can disable entity_picture."""
This is based on `test_get_image` in tests/components/media_player/test_init.py.
"""
patch_key, entity_id, config_entry = _setup(CONFIG_ANDROIDTV_DEFAULT) patch_key, entity_id, config_entry = _setup(CONFIG_ANDROIDTV_DEFAULT)
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
hass.config_entries.async_update_entry( hass.config_entries.async_update_entry(
@ -921,17 +911,12 @@ async def test_get_image_disabled(hass, hass_ws_client):
with patchers.patch_shell("11")[patch_key]: with patchers.patch_shell("11")[patch_key]:
await async_update_entity(hass, entity_id) await async_update_entity(hass, entity_id)
client = await hass_ws_client(hass) media_player_name = "media_player." + slugify(
CONFIG_ANDROIDTV_DEFAULT[TEST_ENTITY_NAME]
with patch(
"androidtv.basetv.basetv_async.BaseTVAsync.adb_screencap", return_value=b"image"
) as screen_cap:
await client.send_json(
{"id": 5, "type": "media_player_thumbnail", "entity_id": entity_id}
) )
state = hass.states.get(media_player_name)
await client.receive_json() assert "entity_picture_local" not in state.attributes
assert not screen_cap.called assert "entity_picture" not in state.attributes
async def _test_service( async def _test_service(

View file

@ -1,6 +1,5 @@
"""The tests for the camera component.""" """The tests for the camera component."""
import asyncio import asyncio
import base64
from http import HTTPStatus from http import HTTPStatus
import io import io
from unittest.mock import AsyncMock, Mock, PropertyMock, mock_open, patch from unittest.mock import AsyncMock, Mock, PropertyMock, mock_open, patch
@ -235,24 +234,6 @@ async def test_snapshot_service(hass, mock_camera):
assert mock_write.mock_calls[0][1][0] == b"Test" assert mock_write.mock_calls[0][1][0] == b"Test"
async def test_websocket_camera_thumbnail(hass, hass_ws_client, mock_camera):
"""Test camera_thumbnail websocket command."""
await async_setup_component(hass, "camera", {})
client = await hass_ws_client(hass)
await client.send_json(
{"id": 5, "type": "camera_thumbnail", "entity_id": "camera.demo_camera"}
)
msg = await client.receive_json()
assert msg["id"] == 5
assert msg["type"] == TYPE_RESULT
assert msg["success"]
assert msg["result"]["content_type"] == "image/jpg"
assert msg["result"]["content"] == base64.b64encode(b"Test").decode("utf-8")
async def test_websocket_stream_no_source( async def test_websocket_stream_no_source(
hass, hass_ws_client, mock_camera, mock_stream hass, hass_ws_client, mock_camera, mock_stream
): ):

View file

@ -1,6 +1,5 @@
"""Test the base functions of the media player.""" """Test the base functions of the media player."""
import asyncio import asyncio
import base64
from http import HTTPStatus from http import HTTPStatus
from unittest.mock import patch from unittest.mock import patch
@ -14,39 +13,6 @@ from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
async def test_get_image(hass, hass_ws_client, caplog):
"""Test get image via WS command."""
await async_setup_component(
hass, "media_player", {"media_player": {"platform": "demo"}}
)
await hass.async_block_till_done()
client = await hass_ws_client(hass)
with patch(
"homeassistant.components.media_player.MediaPlayerEntity."
"async_get_media_image",
return_value=(b"image", "image/jpeg"),
):
await client.send_json(
{
"id": 5,
"type": "media_player_thumbnail",
"entity_id": "media_player.bedroom",
}
)
msg = await client.receive_json()
assert msg["id"] == 5
assert msg["type"] == TYPE_RESULT
assert msg["success"]
assert msg["result"]["content_type"] == "image/jpeg"
assert msg["result"]["content"] == base64.b64encode(b"image").decode("utf-8")
assert "media_player_thumbnail is deprecated" in caplog.text
async def test_get_image_http(hass, hass_client_no_auth): async def test_get_image_http(hass, hass_client_no_auth):
"""Test get image via http command.""" """Test get image via http command."""
await async_setup_component( await async_setup_component(

View file

@ -7,30 +7,10 @@ import voluptuous as vol
from homeassistant import exceptions from homeassistant import exceptions
from homeassistant.components import websocket_api from homeassistant.components import websocket_api
from homeassistant.components.websocket_api import const
from tests.common import MockUser from tests.common import MockUser
async def test_send_big_result(hass, websocket_client):
"""Test sending big results over the WS."""
@websocket_api.websocket_command({"type": "big_result"})
@websocket_api.async_response
def send_big_result(hass, connection, msg):
connection.send_big_result(msg["id"], {"big": "result"})
websocket_api.async_register_command(hass, send_big_result)
await websocket_client.send_json({"id": 5, "type": "big_result"})
msg = await websocket_client.receive_json()
assert msg["id"] == 5
assert msg["type"] == const.TYPE_RESULT
assert msg["success"]
assert msg["result"] == {"big": "result"}
async def test_exception_handling(): async def test_exception_handling():
"""Test handling of exceptions.""" """Test handling of exceptions."""
send_messages = [] send_messages = []