Skip to content

Commit

Permalink
Merge pull request #71 from elad-bar/adjust-api-parsing
Browse files Browse the repository at this point in the history
Add support for new monitor details format
  • Loading branch information
elad-bar authored Aug 7, 2024
2 parents a6e3a0d + 71449ac commit 953772a
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 42 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v3.0.11

- Add support for new monitor details format (as JSON, instead of string of JSON)

## v3.0.10

- Fix blocking call on startup
Expand Down
8 changes: 7 additions & 1 deletion custom_components/shinobi/common/enums.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from enum import StrEnum
from enum import Enum, StrEnum


class MonitorMode(StrEnum):
Expand All @@ -19,3 +19,9 @@ def get_icon(mode: str):
}

return icons.get(mode)


class RequestType(Enum):
JSON = 0
RESOURCE_CHECK = 1
BYTES = 2
110 changes: 70 additions & 40 deletions custom_components/shinobi/managers/rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import sys
from typing import Any

from aiohttp import ClientResponseError, ClientSession
from aiohttp import ClientResponse, ClientSession

from homeassistant.const import ATTR_DATE
from homeassistant.core import HomeAssistant
Expand Down Expand Up @@ -49,6 +49,7 @@
VIDEO_DETAILS_EXTENSION,
VIDEO_DETAILS_TIME,
)
from ..common.enums import RequestType
from ..models.config_data import ConfigData
from ..models.exceptions import APIValidationException
from ..models.monitor_data import MonitorData
Expand Down Expand Up @@ -169,7 +170,7 @@ def build_proxy_url(self, endpoint, monitor_id: str = None):

return url

def build_url(self, endpoint, monitor_id: str = None):
def build_url(self, endpoint: str, monitor_id: str = None):
url = self._build_url(self.config_data.api_url, endpoint, monitor_id)

return url
Expand Down Expand Up @@ -233,16 +234,7 @@ async def _async_post(
async with self._session.post(
url, data=data, json=json_data, ssl=False
) as response:
_LOGGER.debug(f"Status of {url}: {response.status}")

response.raise_for_status()

result = await response.json()

except ClientResponseError as crex:
_LOGGER.error(
f"Failed to post JSON to {endpoint}, HTTP Status: {crex.message} ({crex.status})"
)
result = await self._handle_response(response)

except Exception as ex:
exc_type, exc_obj, tb = sys.exc_info()
Expand All @@ -256,46 +248,75 @@ async def _async_post(

return result

async def get_snapshot(self, url) -> bytes:
async with self._session.get(url, ssl=False) as response:
result = await response.read()
@staticmethod
async def _handle_response(
response: ClientResponse, request_type: RequestType = RequestType.JSON
) -> bytes | dict | bool | None:
result: bytes | dict | bool | None = None
ok_response = response.ok

return result
_LOGGER.debug(
f"Status of request type {request_type} to {response.url}: "
f"{response.status} [ok: {ok_response}]"
)

async def _async_get(
self, endpoint, monitor_id: str = None, resource_available_check: bool = False
):
result = None
if request_type == RequestType.RESOURCE_CHECK:
result = ok_response

try:
self._validate_request(endpoint)
else:
if ok_response:
if request_type == RequestType.BYTES:
result = await response.read()

url = self.build_url(endpoint, monitor_id)
else:
response_data = await response.json()
valid_response = response_data.get("ok", False)

_LOGGER.debug(f"GET {url}")
if valid_response:
result = response_data

async with self._session.get(url, ssl=False) as response:
_LOGGER.debug(f"Status of {url}: {response.status}")
else:
_LOGGER.error(
f"Request to {response.url} failed, "
f"HTTP Status: {response.reason} ({response.status})"
)

if resource_available_check:
result = response.ok
return result

else:
response.raise_for_status()
async def get_snapshot(self, url) -> bytes:
result = await self._async_get_url(url, RequestType.BYTES)

result = await response.json()
return result

except ClientResponseError as crex:
_LOGGER.error(
f"Failed to get data from {endpoint}, HTTP Status: {crex.message} ({crex.status})"
)
async def _async_get(
self,
endpoint: str,
monitor_id: str = None,
request_type: RequestType = RequestType.JSON,
):
self._validate_request(endpoint)

url = self.build_url(endpoint, monitor_id)

result = await self._async_get_url(url, request_type)

return result

async def _async_get_url(
self, url: str, request_type: RequestType = RequestType.JSON
):
result = None

try:
async with self._session.get(url, ssl=False) as response:
result = await self._handle_response(response, request_type)

except Exception as ex:
exc_type, exc_obj, tb = sys.exc_info()
line_number = tb.tb_lineno

_LOGGER.error(
f"Failed to get data from {endpoint}, Error: {ex}, Line: {line_number}"
f"Failed to get data from {url}, Error: {ex}, Line: {line_number}"
)

await sleep(0.001)
Expand Down Expand Up @@ -420,7 +441,7 @@ async def _set_socket_io_version(self):
version = 3

response: bool = await self._async_get(
URL_SOCKET_IO_V4, resource_available_check=True
URL_SOCKET_IO_V4, request_type=RequestType.RESOURCE_CHECK
)

if response:
Expand Down Expand Up @@ -460,10 +481,19 @@ async def _load_monitors(self):
_LOGGER.warning("Invalid monitor details found")

else:
monitor_details_str = monitor.get(ATTR_MONITOR_DETAILS)
details = json.loads(monitor_details_str)
monitor_details = monitor.get(ATTR_MONITOR_DETAILS)

if monitor_details is None:
_LOGGER.warning(f"Invalid monitor data, Data: {monitor}")
continue

if isinstance(monitor_details, dict):
monitor[ATTR_MONITOR_DETAILS] = monitor_details

else:
details = json.loads(monitor_details)

monitor[ATTR_MONITOR_DETAILS] = details
monitor[ATTR_MONITOR_DETAILS] = details

monitor_data = MonitorData(monitor)

Expand Down
2 changes: 1 addition & 1 deletion custom_components/shinobi/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"iot_class": "local_polling",
"issue_tracker": "https://github.com/elad-bar/ha-shinobi/issues",
"requirements": [],
"version": "3.0.10"
"version": "3.0.11"
}

0 comments on commit 953772a

Please sign in to comment.