home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
69.75k stars 28.91k forks source link

Plex: Cannot browse media, 'Tag' object has no attribute 'playlistType' #119719

Open amccook opened 2 weeks ago

amccook commented 2 weeks ago

The problem

TL;DR

HA getting stuck on Playlists in Plex that do not have "playlistType" defined. An example of such a playlist is a "directory" that has been imported into Plex via iTunes Plugin. Need to add some logic to skip over playlists that have "type": "directory".

Details:

Trying to browse/play Plex Media via HA and unable to do so.

When browsing media from Plex an "Unknown Error" occurs. image

Logs show: 'Tag' object has no attribute 'playlistType'.

2024-06-13 20:14:38.141 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [546745671328] Error handling message: Unknown error (unknown_error) MYUSERNAME from 47.XXX.XXX.XXX (Mozilla/5.0 (iPhone; CPU iPhone OS 17_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Home Assistant/2024.5.1 (io.robbie.HomeAssistant; build:2024.688; iOS 17.5.1) Mobile/HomeAssistant, like Safari)
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/decorators.py", line 27, in _handle_async_response
    await func(hass, connection, msg)
  File "/usr/src/homeassistant/homeassistant/components/media_player/__init__.py", line 1308, in websocket_browse_media
    payload = await player.async_browse_media(media_content_type, media_content_id)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/cast/media_player.py", line 654, in async_browse_media
    browse_media = await platform.async_browse_media(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/plex/cast.py", line 45, in async_browse_media
    return await async_browse_plex_media(hass, None, None, platform=CAST_DOMAIN)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/plex/__init__.py", line 75, in async_browse_media
    return await hass.async_add_executor_job(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/plex/media_browser.py", line 55, in browse_media
    return root_payload(hass, is_internal, platform=platform)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/plex/media_browser.py", line 297, in root_payload
    browse_media(
  File "/usr/src/homeassistant/homeassistant/components/plex/media_browser.py", line 253, in browse_media
    return server_payload()
           ^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/plex/media_browser.py", line 109, in server_payload
    server_info.children.append(playlists_payload())
                                ^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/plex/media_browser.py", line 135, in playlists_payload
    if playlist.playlistType != "audio" and platform == "sonos":
       ^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Tag' object has no attribute 'playlistType'

Manually ran API calls to Plex to verify which playlists are missing the attribute playlistType. curl -L -X GET 'http://<My-Plex-IP>:32400/playlists' -H 'Accept: application/json' -H 'X-Plex-Token: <myToken>'

Here's a small excerpt of that response, you can see multiple entries in the array do not have the playlistType attribute. Those all coincide with them having a "type": "directory" which is how Plex imports playlist folders from iTunes.

{
    "MediaContainer": {
        "size": 45,
        "Metadata": [{
                "ratingKey": "1207933",
                "key": "/playlists/1207933/items",
                "guid": "com.plexapp.agents.none://cbdf571e-a02c-44eb-885a-cb5513649a9a",
                "type": "playlist",
                "title": "❤️ Tracks",
                "titleSort": "️ Tracks",
                "summary": "All your highly rated tracks, in one convenient place.",
                "smart": true,
                "playlistType": "audio",
                "composite": "/playlists/1207933/composite/1707187779",
                "icon": "playlist://image.smart",
                "viewCount": 1,
                "lastViewedAt": 1706449250,
                "duration": 166763000,
                "leafCount": 606,
                "addedAt": 1706449250,
                "updatedAt": 1707187779
            }, {
                "ratingKey": "1230056",
                "key": "/playlists?parent=1230056",
                "guid": "com.plexapp.plugins.itunes://C03D18262845EE9C",
                "type": "directory",
                "title": "Time Period",
                "summary": "",
                "addedAt": 1706915130
            }, {
                "ratingKey": "1229947",
                "key": "/playlists?parent=1229947",
                "guid": "com.plexapp.plugins.itunes://2459FB97A6958E75",
                "type": "directory",
                "title": "2018",
                "summary": "",
                "addedAt": 1706915110
            }, {
                "ratingKey": "1230860",
                "key": "/playlists/1230860/items",
                "guid": "com.plexapp.plugins.itunes://38127DFC61B3DCAB",
                "type": "playlist",
                "title": "A Random Assortment",
                "titleSort": "Random Assortment",
                "summary": "",
                "smart": false,
                "playlistType": "audio",
                "composite": "/playlists/1230860/composite/1706916713",
                "viewCount": 1,
                "lastViewedAt": 1706916712,
                "duration": 120035000,
                "leafCount": 439,
                "addedAt": 1706916712,
                "updatedAt": 1706916713
            }
        ]
    }
}

image

The "type": "directory" entries do not render in the Plex UI and are not usable as a playlist in Plex, wasn't obvious until viewing the API response.

Suggested Fix

Introduce some logic to ignore the "type": "directory" entries. Perhaps first evaluate the type. For example, if type == playlist, then continue to evaluate the playlistType.

Let me know if any additional information is needed.

What version of Home Assistant Core has the issue?

core-2024.6.2

What was the last working version of Home Assistant Core?

No response

What type of installation are you running?

Home Assistant OS

Integration causing the issue

Plex

Link to integration documentation on our website

https://www.home-assistant.io/integrations/plex/

Diagnostics information

homeassistantlogs20240614.txt

Example YAML snippet

No response

Anything in the logs that might be useful for us?

2024-06-13 20:14:38.141 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [546745671328] Error handling message: Unknown error (unknown_error) MYUSERNAME from 47.XXX.XXX.XXX (Mozilla/5.0 (iPhone; CPU iPhone OS 17_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Home Assistant/2024.5.1 (io.robbie.HomeAssistant; build:2024.688; iOS 17.5.1) Mobile/HomeAssistant, like Safari)
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/decorators.py", line 27, in _handle_async_response
    await func(hass, connection, msg)
  File "/usr/src/homeassistant/homeassistant/components/media_player/__init__.py", line 1308, in websocket_browse_media
    payload = await player.async_browse_media(media_content_type, media_content_id)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/cast/media_player.py", line 654, in async_browse_media
    browse_media = await platform.async_browse_media(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/plex/cast.py", line 45, in async_browse_media
    return await async_browse_plex_media(hass, None, None, platform=CAST_DOMAIN)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/plex/__init__.py", line 75, in async_browse_media
    return await hass.async_add_executor_job(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/plex/media_browser.py", line 55, in browse_media
    return root_payload(hass, is_internal, platform=platform)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/plex/media_browser.py", line 297, in root_payload
    browse_media(
  File "/usr/src/homeassistant/homeassistant/components/plex/media_browser.py", line 253, in browse_media
    return server_payload()
           ^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/plex/media_browser.py", line 109, in server_payload
    server_info.children.append(playlists_payload())
                                ^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/plex/media_browser.py", line 135, in playlists_payload
    if playlist.playlistType != "audio" and platform == "sonos":
       ^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Tag' object has no attribute 'playlistType'

Additional information

No response

home-assistant[bot] commented 2 weeks ago

Hey there @jjlawren, mind taking a look at this issue as it has been labeled with an integration (plex) you are listed as a code owner for? Thanks!

Code owner commands Code owners of `plex` can trigger bot actions by commenting: - `@home-assistant close` Closes the issue. - `@home-assistant rename Awesome new title` Renames the issue. - `@home-assistant reopen` Reopen the issue. - `@home-assistant unassign plex` Removes the current integration label and assignees on the issue, add the integration domain after the command. - `@home-assistant add-label needs-more-information` Add a label (needs-more-information, problem in dependency, problem in custom component) to the issue. - `@home-assistant remove-label needs-more-information` Remove a label (needs-more-information, problem in dependency, problem in custom component) on the issue.

(message by CodeOwnersMention)


plex documentation plex source (message by IssueLinks)

amccook commented 1 week ago

Giving this a little nudge :) Any additional information I can provide to help resolve?