diff --git a/custom_components/plex_recently_added/manifest.json b/custom_components/plex_recently_added/manifest.json index 1812c1e..e3354b5 100644 --- a/custom_components/plex_recently_added/manifest.json +++ b/custom_components/plex_recently_added/manifest.json @@ -9,5 +9,5 @@ "iot_class": "local_polling", "issue_tracker": "https://github.com/custom-components/sensor.plex_recently_added/issues", "requirements": [], - "version": "0.4.6" + "version": "0.4.7" } diff --git a/custom_components/plex_recently_added/parser.py b/custom_components/plex_recently_added/parser.py index c0177de..b42e4fa 100644 --- a/custom_components/plex_recently_added/parser.py +++ b/custom_components/plex_recently_added/parser.py @@ -67,6 +67,7 @@ def parse_data(data, max, base_url, token, identifier, section_key, images_base_ data_output["genres"] = ", ".join([genre['tag'] for genre in item.get('Genre', [])][:3]) data_output["rating"] = ('\N{BLACK STAR} ' + str(item.get("rating"))) if int(float(item.get("rating", 0))) > 0 else '' data_output['summary'] = item.get('summary', '') + data_output['trailer'] = item.get('trailer') data_output["poster"] = (f'{images_base_url}?path={thumb}') if thumb else "" data_output["fanart"] = (f'{images_base_url}?path={art}') if art else "" data_output["deep_link"] = deep_link if identifier else None @@ -75,4 +76,3 @@ def parse_data(data, max, base_url, token, identifier, section_key, images_base_ return output - diff --git a/custom_components/plex_recently_added/plex_api.py b/custom_components/plex_recently_added/plex_api.py index 78f4ba7..08c8292 100644 --- a/custom_components/plex_recently_added/plex_api.py +++ b/custom_components/plex_recently_added/plex_api.py @@ -39,6 +39,33 @@ def __init__( self._exclude_keywords = exclude_keywords self._images_base_url = f'/{name.lower() + "_" if len(name) > 0 else ""}plex_recently_added' + async def get_trailer_url(self, item_key): + extras_url = f'http{self._ssl}://{self._host}:{self._port}/library/metadata/{item_key}/extras?X-Plex-Token={self._token}' + try: + extras_res = await self._hass.async_add_executor_job( + requests.get, + extras_url, + { + "headers": { + "User-agent": USER_AGENT, + "Accept": ACCEPTS, + }, + "timeout": 10 + } + ) + check_headers(extras_res) + root = ElementTree.fromstring(extras_res.text) + + for video in root.findall(".//Video"): + if video.get("type") == "clip" and video.get("subtype") == "trailer": + part = video.find(".//Part") + if part is not None and part.get("key"): + return f'http{self._ssl}://{self._host}:{self._port}{part.get("key")}&X-Plex-Token={self._token}' + + except Exception as e: + print(f"Error fetching trailer: {str(e)}") + return None + async def update(self): info_url = 'http{0}://{1}:{2}'.format( self._ssl, @@ -117,6 +144,11 @@ async def update(self): check_headers(sub_sec) root = ElementTree.fromstring(sub_sec.text) parsed_libs = parse_library(root) + + # Fetch trailer URLs for each item + for item in parsed_libs: + item['trailer'] = await self.get_trailer_url(item['ratingKey']) + if library["type"] not in data['all']: data['all'][library["type"]] = [] data['all'][library["type"]] += parsed_libs @@ -135,4 +167,4 @@ async def update(self): class FailedToLogin(Exception): "Raised when the Plex user fail to Log-in" - pass \ No newline at end of file + pass