delarte/src/delarte/api.py
Barbagus 4667dbfca1 Refactor models and API
Change/add/rename model's data structures in order to provide a more
useful API #20, introducing new structures:
- `Sources`: summarizing program, renditions and variants found
  at a given ArteTV page URL
- `Target`: summarizing all required data for a download

And new functions:
- `fetch_sources()` to build the `Sources` from a URL
- `iter_[renditions|variants]()` describe the available options for the
  `Sources`
- `select_[renditions|variants]()` to narrow down the desired options
  for the `Sources`
- `compile_sources` to compute such a `Target` from `Sources`
- `download_target` to download such a `Target`

Finally, this should make the playlist handling #7 easier (I know, I've
said that before)
2023-01-09 19:30:46 +01:00

65 lines
1.8 KiB
Python

# License: 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."""
from .error import UnexpectedAPIResponse, UnsupportedHLSProtocol
from .model import ProgramMeta
MIME_TYPE = "application/vnd.api+json; charset=utf-8"
def _fetch_api_data(http_session, path, object_type):
# Fetch an API object.
url = "https://api.arte.tv/api/player/v2/" + path
r = http_session.get(url)
r.raise_for_status()
if (_ := r.headers["content-type"]) != MIME_TYPE:
raise UnexpectedAPIResponse("MIME_TYPE", path, MIME_TYPE, _)
obj = r.json()["data"]
if (_ := obj["type"]) != object_type:
raise UnexpectedAPIResponse("OBJECT_TYPE", path, object_type, _)
return obj["attributes"]
def fetch_program_info(http_session, site, program_id):
"""Fetch the given program metadata and indexes."""
obj = _fetch_api_data(http_session, f"config/{site}/{program_id}", "ConfigPlayer")
if (_ := obj["metadata"]["providerId"]) != program_id:
raise UnexpectedAPIResponse(
"PROGRAM_ID_MISMATCH",
site,
program_id,
_,
)
program_meta = ProgramMeta(
obj["metadata"]["title"],
obj["metadata"]["subtitle"],
obj["metadata"]["description"],
)
program_index_urls = set()
for s in obj["streams"]:
if (_ := s["protocol"]) != "HLS_NG":
raise UnsupportedHLSProtocol(site, program_id, _)
if (program_index_url := s["url"]) in program_index_urls:
raise UnexpectedAPIResponse(
"DUPLICATE_PROGRAM_INDEX_URL",
site,
program_id,
program_index_url,
)
program_index_urls.add(program_index_url)
return program_meta, program_index_urls