Skip to content

Commit 05d6ec2

Browse files
committed
Change
- fanart and poster has been grabbed wrong - made that the integration would make sensor for each selecter type (movies, shows, ect.) and one for all of the data merged
1 parent 5c89023 commit 05d6ec2

File tree

3 files changed

+55
-22
lines changed

3 files changed

+55
-22
lines changed

custom_components/plex_recently_added/parser.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,48 @@ def parse_library(root):
99
for medium in root.findall("Video"):
1010
output.append(medium.attrib)
1111

12+
if len(output) == 0:
13+
for medium in root.findall("Directory"):
14+
output.append(medium.attrib)
15+
16+
if len(output) == 0:
17+
for medium in root.findall("Photo"):
18+
output.append(medium.attrib)
19+
1220
return output
1321

14-
def parse_data(data, max, base_url, token, identifier):
22+
def parse_data(data, max, base_url, token, identifier, section_key):
1523
data = sorted(data, key=lambda i: i['addedAt'], reverse=True)[:max]
1624

1725
output = []
1826
for item in data:
1927
date = datetime.strptime(item.get("originallyAvailableAt", "1900-01-01"), "%Y-%m-%d").strftime('%Y-%m-%dT%H:%M:%SZ')
28+
thumb = item.get("thumb", item.get("parentThumb", item.get("grandparentThumb", None)))
29+
art = item.get("art", item.get("grandparentArt", None))
30+
deep_link_position = -1
31+
if section_key == "artist":
32+
deep_link_position = -2
33+
deep_link = f'{base_url}/web/index.html#!/server/{identifier}/details?key=%2Flibrary%2Fmetadata%2F{item.get("key", "").split("/")[deep_link_position]}'
34+
2035
output.append(
2136
{
2237
"airdate": date,
2338
"title": item.get("grandparentTitle", item.get("parentTitle", item.get("title", ""))),
2439
"release": datetime.utcfromtimestamp(int(item.get("addedAt", 0))).strftime('%Y-%m-%dT%H:%M:%SZ'),
2540
"episode": item.get("title", ""),
26-
"number": f'S{"{:0>2}".format(item.get("parentIndex", "1"))}E{"{:0>2}".format(item.get("index", "1"))}',
41+
"number": f'S{"{:0>2}".format(item.get("parentIndex", "1"))}E{"{:0>2}".format(item.get("index", "1"))}' if item.get("parentIndex", None) and item.get("index", None) else "",
2742
"season_num": item.get("parentIndex", ""),
2843
"season_num": item.get("parentIndex", "1"),
2944
"episode_num": item.get("index", "1"),
3045
"genres": ", ".join([genre['tag'] for genre in item.get('Genre', [])][:3]),
31-
"rating": ('\N{BLACK STAR} ' + str(item.get("rating"))) if int(item.get("rating", 0)) > 0 else '',
46+
"rating": ('\N{BLACK STAR} ' + str(item.get("rating"))) if int(float(item.get("rating", 0))) > 0 else '',
3247
"studio": item.get("grandparentTitle", ""),
3348
"aired": date,
3449
"runtime": math.floor(int(item.get("duration", 0)) / 60000),
35-
"poster": base_url + item.get("thumb", "") + f'?X-Plex-Token={token}',
36-
"fanart": base_url + item.get("parentThumb", item.get("grandparentThumb", "")) + f'?X-Plex-Token={token}',
50+
"poster": (base_url + thumb + f'?X-Plex-Token={token}') if thumb else "",
51+
"fanart": (base_url + art + f'?X-Plex-Token={token}') if art else "",
3752
"flag": "viewCount" not in item,
38-
"deep_link": f'{base_url}/web/index.html#!/server/{identifier}/details?key=%2Flibrary%2Fmetadata%2F{item.get("key", "").split("/")[-1]}' if identifier else None
53+
"deep_link": deep_link if identifier else None
3954
}
4055
)
4156

custom_components/plex_recently_added/plex_api.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88
from .parser import parse_data, parse_library
99

1010

11-
import logging
12-
_LOGGER = logging.getLogger(__name__)
13-
1411
def check_headers(response):
1512
if 'text/xml' not in response.headers.get('Content-Type', '') and 'application/xml' not in response.headers.get('Content-Type', ''):
1613
raise ValueError(f"Expected XML but received different content type: {response.headers.get('Content-Type')}")
@@ -97,17 +94,22 @@ async def update(self):
9794
for lib in root.findall("Directory"):
9895
libs.append(lib.get("title"))
9996
if lib.get("type") in self._section_types and (len(self._section_libraries) == 0 or lib.get("title") in self._section_libraries):
100-
sections.append(lib.get("key"))
97+
sections.append({'type': lib.get("type"),'key': lib.get("key")})
10198
except OSError as e:
10299
raise FailedToLogin
103100

104101
""" Looping through all libraries (sections) """
105-
data = []
102+
data = {
103+
'all': []
104+
}
105+
for s in self._section_types:
106+
data[s] = []
107+
106108
for library in sections:
107109
recent_or_deck = on_deck if self._on_deck else recently_added
108110
sub_sec = await self._hass.async_add_executor_job(
109111
requests.get,
110-
f'{recent_or_deck.format(library, self._max * 2)}&X-Plex-Token={self._token}',
112+
f'{recent_or_deck.format(library["key"], self._max * 2)}&X-Plex-Token={self._token}',
111113
{
112114
"headers":{
113115
"User-agent": USER_AGENT,
@@ -119,10 +121,16 @@ async def update(self):
119121
)
120122
check_headers(sub_sec)
121123
root = ElementTree.fromstring(sub_sec.text)
122-
data += parse_library(root)
124+
parsed_libs = parse_library(root)
125+
data['all'] += parsed_libs
126+
data[library["type"]] += parsed_libs
127+
128+
data_out = {}
129+
for k in data.keys():
130+
data_out[k] = {'data': [DEFAULT_PARSE_DICT] + parse_data(data[k], self._max, info_url, self._token, identifier, k)}
123131

124132
return {
125-
"data": {"data": [DEFAULT_PARSE_DICT] + parse_data(data, self._max, info_url, self._token, identifier)},
133+
"data": {**data_out},
126134
"online": True,
127135
"libraries": libs
128136
}

custom_components/plex_recently_added/sensor.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@
88

99
from homeassistant.const import (
1010
CONF_API_KEY,
11-
CONF_NAME,
11+
CONF_NAME,
1212
)
1313

14-
from .const import DOMAIN
14+
from .const import (
15+
DOMAIN,
16+
CONF_SECTION_TYPES,
17+
DEFAULT_PARSE_DICT
18+
)
1519
from .coordinator import PlexDataCoordinator
1620

1721

@@ -21,17 +25,18 @@ async def async_setup_entry(
2125
async_add_entities: Callable,
2226
) -> None:
2327
coordinator: PlexDataCoordinator = hass.data[DOMAIN][config_entry.entry_id]
28+
section_types = config_entry.data[CONF_SECTION_TYPES]
2429

25-
async_add_entities([PlexRecentlyAddedSensor(coordinator, config_entry)], update_before_add=True)
26-
30+
async_add_entities([PlexRecentlyAddedSensor(coordinator, config_entry, type) for type in section_types] + [PlexRecentlyAddedSensor(coordinator, config_entry)], update_before_add=True)
2731

2832

2933
class PlexRecentlyAddedSensor(CoordinatorEntity[PlexDataCoordinator], SensorEntity):
30-
def __init__(self, coordinator: PlexDataCoordinator, config_entry: ConfigEntry):
34+
def __init__(self, coordinator: PlexDataCoordinator, config_entry: ConfigEntry, type: str = ""):
3135
super().__init__(coordinator)
3236
self._coordinator = coordinator
33-
self._name = f'{config_entry.data[CONF_NAME].capitalize() + " " if len(config_entry.data[CONF_NAME]) > 0 else ""}Plex Recently Added'
37+
self._name = f'{config_entry.data[CONF_NAME].capitalize() + " " if len(config_entry.data[CONF_NAME]) > 0 else ""}Plex Recently Added{ " " + type.capitalize() if len(type) > 0 else ""}'
3438
self._api_key = config_entry.data[CONF_API_KEY]
39+
self._section_type = type
3540

3641
@property
3742
def name(self) -> str:
@@ -41,7 +46,7 @@ def name(self) -> str:
4146
@property
4247
def unique_id(self) -> str:
4348
"""Return the unique ID of the sensor."""
44-
return f'{self._api_key}_Plex_Recently_Added'
49+
return f'{self._api_key}_Plex_Recently_Added{"_" + self._section_type.capitalize() if len(self._section_type) > 0 else ""}'
4550

4651
@property
4752
def state(self) -> Optional[str]:
@@ -50,4 +55,9 @@ def state(self) -> Optional[str]:
5055

5156
@property
5257
def extra_state_attributes(self) -> Dict[str, Any]:
53-
return self._coordinator.data['data']
58+
if 'data' in self._coordinator.data:
59+
if len(self._section_type) == 0 and 'all' in self._coordinator.data['data']:
60+
return self._coordinator.data['data']['all']
61+
elif self._section_type in self._coordinator.data['data']:
62+
return self._coordinator.data['data'][self._section_type]
63+
return {'data': DEFAULT_PARSE_DICT}

0 commit comments

Comments
 (0)