import json
from http import HTTPStatus
import requests
from requests.exceptions import ConnectionError, Timeout
from lib.api.plex.models.plex_models import (
PlexEpisodeMeta,
PlexLibrarySection,
PlexMediaMeta,
PlexMediaType,
PlexServer,
)
from lib.api.plex.settings import settings
from lib.api.plex.utils import PlexUnauthorizedError
from lib.utils.kodi.utils import kodilog
def check_server_connection(url, access_token):
try:
response = requests.get(
url,
params={
"X-Plex-Token": access_token,
},
timeout=settings.plex_requests_timeout,
)
return response.status_code == HTTPStatus.OK
except (Timeout, ConnectionError):
return False
def get_servers(url, token):
json = get_json(
url=f"{url}/resources",
params={
"includeHttps": 1,
"includeRelay": 1,
"X-Plex-Token": token,
"X-Plex-Client-Identifier": settings.identifier,
},
)
return [
PlexServer(**server)
for server in json
if "server" in server["provides"] and "accessToken" in server
]
def get_sections(url, token):
json = get_json(
url=f"{url}/library/sections",
params={
"X-Plex-Token": token,
},
)
return [
PlexLibrarySection(**section)
for section in json["MediaContainer"]["Directory"]
if section["type"] in {PlexMediaType.movie, PlexMediaType.show}
]
def get_section_media(
url,
token: str,
section_id: str,
skip: int,
search: str,
):
params = {
"includeGuids": 1,
"X-Plex-Container-Start": skip,
"X-Plex-Container-Size": 100,
"X-Plex-Token": token,
}
if search:
params["title"] = search
json = get_json(
url=f"{url}/library/sections/{section_id}/all",
params=params,
)
metadata = json["MediaContainer"].get("Metadata", [])
return [PlexMediaMeta(**meta) for meta in metadata]
def get_media(url, token, guid, get_only_first=False):
json = get_json(
url=f"{url}/library/all",
params={
"guid": guid,
"X-Plex-Token": token,
},
)
kodilog(f"get_media/library/all: {json}")
media_sections = json["MediaContainer"].get("Metadata", [])
media_metas = []
for section in media_sections:
json = get_json(
url=f"{url}/library/metadata/{section['ratingKey']}",
params={
"X-Plex-Token": token,
"includeElements": "Stream",
},
)
metadata = json["MediaContainer"]["Metadata"][0]
kodilog(f"get_media/library/metadata/: {json}")
media_metas.append(PlexMediaMeta(**metadata))
if get_only_first:
break
return media_metas
def get_all_episodes(url, token, key):
json = get_json(
url=str(f"{url}/{key[1:]}").replace("/children", "/allLeaves"),
params={
"X-Plex-Token": token,
},
)
metadata = json["MediaContainer"].get("Metadata", [])
return [PlexEpisodeMeta(**meta) for meta in metadata]
def imdb_to_plex_id(imdb_id, token, mode, media_type):
json = get_json(
url="https://metadata.provider.plex.tv/library/metadata/matches",
params={
"X-Plex-Token": token,
"type": 1 if (media_type == "movies" or mode == "movies") else 2,
"title": f"imdb-{imdb_id}",
"guid": f"com.plexapp.agents.imdb://{imdb_id}?lang=en",
},
)
media_container = json["MediaContainer"]
if media_container["totalSize"]:
return media_container["Metadata"][0]["guid"]
def get_episode_guid(url, token, show_guid, season, episode):
all_episodes = get_all_episodes(
url=url,
token=token,
key=show_guid,
)
for metadata in all_episodes:
if str(metadata.parent_index) == season and str(metadata.index) == episode:
return metadata.guid
def convert_to_plex_id(url, access_token, auth_token, id, mode, media_type, season, episode):
plex_id = imdb_to_plex_id(id, auth_token, mode, media_type)
if not plex_id:
return None
if mode == "tv" or media_type == "tv":
media = get_media(
url=url,
token=access_token,
guid=plex_id,
)
for meta in media:
plex_id = get_episode_guid(
url=url,
token=access_token,
show_guid=meta.key,
season=season,
episode=episode,
)
if plex_id:
break
else:
return None
return plex_id
def get_json(url, params=None):
if params is None:
params = {}
try:
response = requests.get(
url,
params=params,
headers={"accept": "application/json"},
timeout=settings.plex_requests_timeout,
)
if response.status_code in (401, 403):
raise PlexUnauthorizedError()
if response.status_code >= 400:
kodilog("Received error from plex server")
return json.loads(response.content)
except TimeoutError:
kodilog("Plex server timeout error")