forked from fcode/delarte
59 lines
1.7 KiB
Python
59 lines
1.7 KiB
Python
# Licence: GNU AGPL v3: http://www.gnu.org/licenses/
|
|
# This file is part of [`delarte`](https://git.afpy.org/fcode/delarte.git)
|
|
|
|
"""Provide ArteTV JSON API utilities."""
|
|
|
|
import json
|
|
from http import HTTPStatus
|
|
from urllib.request import urlopen
|
|
|
|
|
|
def load_api_data(url):
|
|
"""Retrieve the root node (infamous "data") of an API call response."""
|
|
http_response = urlopen(url)
|
|
|
|
if http_response.status != HTTPStatus.OK:
|
|
raise RuntimeError("API request failed")
|
|
|
|
if (
|
|
http_response.getheader("Content-Type")
|
|
!= "application/vnd.api+json; charset=utf-8"
|
|
):
|
|
raise ValueError("API response not supported")
|
|
|
|
return json.load(http_response)["data"]
|
|
|
|
|
|
def load_config(lang, program_id):
|
|
"""Retrieve a program config from API."""
|
|
url = f"https://api.arte.tv/api/player/v2/config/{lang}/{program_id}"
|
|
config = load_api_data(url)
|
|
|
|
if config["type"] != "ConfigPlayer":
|
|
raise ValueError("Invalid API response")
|
|
|
|
if config["attributes"]["metadata"]["providerId"] != program_id:
|
|
raise ValueError("Invalid API response")
|
|
|
|
return config
|
|
|
|
|
|
def iter_renditions(config):
|
|
"""Return a rendition (code, label) iterator."""
|
|
for stream in config["attributes"]["streams"]:
|
|
yield (
|
|
# rendition code
|
|
stream["versions"][0]["eStat"]["ml5"],
|
|
# rendition full name
|
|
stream["versions"][0]["label"],
|
|
)
|
|
|
|
|
|
def select_rendition(config, rendition_code):
|
|
"""Return the master playlist index url for the given rendition code."""
|
|
for stream in config["attributes"]["streams"]:
|
|
if stream["versions"][0]["eStat"]["ml5"] == rendition_code:
|
|
return stream["url"]
|
|
|
|
return None
|