2022-12-20 08:48:57 +00:00
|
|
|
# License: GNU AGPL v3: http://www.gnu.org/licenses/
|
|
|
|
# This file is part of `delarte` (https://git.afpy.org/fcode/delarte.git)
|
2022-12-13 06:29:59 +00:00
|
|
|
|
|
|
|
"""Provide ArteTV JSON API utilities."""
|
|
|
|
|
2023-02-13 08:35:33 +00:00
|
|
|
import json
|
|
|
|
|
|
|
|
from .error import UnexpectedAPIResponse, HTTPError
|
2023-01-24 07:27:37 +00:00
|
|
|
from .model import Rendition
|
2022-12-13 06:29:59 +00:00
|
|
|
|
2022-12-20 22:46:44 +00:00
|
|
|
MIME_TYPE = "application/vnd.api+json; charset=utf-8"
|
2022-12-13 06:29:59 +00:00
|
|
|
|
|
|
|
|
2023-02-13 08:35:33 +00:00
|
|
|
def _fetch_api_object(http, url, object_type):
|
2022-12-20 22:46:44 +00:00
|
|
|
# Fetch an API object.
|
2022-12-13 06:29:59 +00:00
|
|
|
|
2023-02-13 08:35:33 +00:00
|
|
|
r = http.request("GET", url)
|
2023-02-13 17:44:32 +00:00
|
|
|
HTTPError.raise_for_status(r)
|
2022-12-13 06:29:59 +00:00
|
|
|
|
2023-02-13 08:35:33 +00:00
|
|
|
mime_type = r.getheader("content-type")
|
2023-01-24 07:27:37 +00:00
|
|
|
if mime_type != MIME_TYPE:
|
|
|
|
raise UnexpectedAPIResponse("MIME_TYPE", url, MIME_TYPE, mime_type)
|
2022-12-13 06:29:59 +00:00
|
|
|
|
2023-02-13 08:35:33 +00:00
|
|
|
obj = json.loads(r.data.decode("utf-8"))
|
2022-12-13 06:29:59 +00:00
|
|
|
|
2023-01-24 07:27:37 +00:00
|
|
|
try:
|
2023-01-16 20:12:55 +00:00
|
|
|
data_type = obj["data"]["type"]
|
2023-01-24 07:27:37 +00:00
|
|
|
if data_type != object_type:
|
|
|
|
raise UnexpectedAPIResponse("OBJECT_TYPE", url, object_type, data_type)
|
2023-01-16 20:12:55 +00:00
|
|
|
|
2023-01-24 07:27:37 +00:00
|
|
|
return obj["data"]["attributes"]
|
2022-12-13 06:29:59 +00:00
|
|
|
|
2023-01-24 07:27:37 +00:00
|
|
|
except (KeyError, IndexError, ValueError) as e:
|
|
|
|
raise UnexpectedAPIResponse("SCHEMA", url) from e
|
2022-12-20 22:46:44 +00:00
|
|
|
|
|
|
|
|
2023-02-13 08:35:33 +00:00
|
|
|
def iter_renditions(program_id, player_config_url, http):
|
2023-01-24 07:27:37 +00:00
|
|
|
"""Iterate over renditions for the given program."""
|
2023-02-13 08:35:33 +00:00
|
|
|
obj = _fetch_api_object(http, player_config_url, "ConfigPlayer")
|
2022-12-20 22:46:44 +00:00
|
|
|
|
2023-01-24 07:27:37 +00:00
|
|
|
codes = set()
|
|
|
|
try:
|
2023-01-16 20:12:55 +00:00
|
|
|
provider_id = obj["metadata"]["providerId"]
|
2023-01-24 07:27:37 +00:00
|
|
|
if provider_id != program_id:
|
2023-01-08 19:04:18 +00:00
|
|
|
raise UnexpectedAPIResponse(
|
2023-01-24 07:27:37 +00:00
|
|
|
"PROVIDER_ID_MISMATCH", player_config_url, provider_id
|
2022-12-27 07:21:30 +00:00
|
|
|
)
|
2022-12-13 06:29:59 +00:00
|
|
|
|
2023-01-24 07:27:37 +00:00
|
|
|
for s in obj["streams"]:
|
|
|
|
code = s["versions"][0]["eStat"]["ml5"]
|
|
|
|
|
|
|
|
if code in codes:
|
|
|
|
raise UnexpectedAPIResponse(
|
|
|
|
"DUPLICATE_RENDITION_CODE", player_config_url, code
|
|
|
|
)
|
|
|
|
codes.add(code)
|
|
|
|
|
|
|
|
yield (
|
|
|
|
Rendition(
|
|
|
|
s["versions"][0]["eStat"]["ml5"],
|
|
|
|
s["versions"][0]["label"],
|
|
|
|
),
|
|
|
|
s["protocol"],
|
|
|
|
s["url"],
|
|
|
|
)
|
|
|
|
|
|
|
|
except (KeyError, IndexError, ValueError) as e:
|
|
|
|
raise UnexpectedAPIResponse("SCHEMA", player_config_url) from e
|
2022-12-13 06:29:59 +00:00
|
|
|
|
2023-01-24 07:27:37 +00:00
|
|
|
if not codes:
|
|
|
|
raise UnexpectedAPIResponse("NO_RENDITIONS", player_config_url)
|