pkkid / python-plexapi

Python bindings for the Plex API.
BSD 3-Clause "New" or "Revised" License
1.11k stars 198 forks source link

Synchronous version of library.section.update #1036

Open doug-w opened 1 year ago

doug-w commented 1 year ago

What is your feature request?

Calling update() on a library section kicks off the webrequest and returns None. I'd like to wait for an update to finish on the section and then query the items in the section.

I don't see any way to poll to see if an update() I requested is still running. Under the hood, doing the update spawns a 'Plex Media Scanner' with a GUID for tracking: /usr/lib/plexmediaserver/Plex Media Scanner --scan --refresh --section 36 --activity 2f87a17d-cb45-426a-a66e-ac4565fc0

So if there was a way to return that, and a way to query for it, I could spin lock until it was done.

Are there any workarounds?

No response

Code Snippets

No response

Additional Context

No response

Hellowlol commented 1 year ago

No. The response isnt any usefull. You can Connect to the websocket and check if its hasnt scanned/update any media for x sec. Then do a update request

Hellowlol commented 1 year ago

I see the command returns self. Maybe its possible to just reload.

Hellowlol commented 1 year ago

Psudo code as im on mobil and cba with formatting:

S = plex.library.sections()

for x in s: T = datetime.now() While true: F= datetime.now() If F > x.updatedAt: Break Else: x.reload() time.sleep(10)

doug-w commented 1 year ago

Regarding returning self:

s = plex.library.section('Movies') s

print(s.__dict__) {'_server': , '_data': , '_initpath': '/library/sections', '_parent': None, '_details_key': 1, '_overwriteNone': True, '_autoReload': True, '_edits': None, 'agent': 'tv.plex.agents.movie', 'allowSync': True, 'art': '/:/resources/movie-fanart.jpg', 'composite': '/library/sections/1/composite/1664561242', 'createdAt': datetime.datetime(2018, 1, 25, 0, 34, 13), 'filters': True, 'key': 1, 'language': 'en-US', 'locations': ['/media/public/Movies'], 'refreshing': False, 'scanner': 'Plex Movie', 'thumb': '/:/resources/movie.png', 'title': 'Movies', 'type': 'movie', 'updatedAt': datetime.datetime(2022, 9, 30, 18, 8, 9), 'uuid': 'c1355d9b-a667-463d-8553-d2e50f1c0041', '_filterTypes': None, '_fieldTypes': None, '_totalViewSize': None, '_totalSize': None, '_totalDuration': None, '_totalStorage': None} l = s.update() print(l.__dict__) Traceback (most recent call last): File "", line 1, in AttributeError: 'NoneType' object has no attribute '__dict__'. Did you mean: '__dir__'?

Regarding updatedAt, I'll check if that writes at the end of the update rather than when it's queued.

JonnyWong16 commented 1 year ago

You're using an outdated version of PlexAPI. return self was added in version 4.13.0.

https://github.com/pkkid/python-plexapi/releases/tag/4.13.0

cpt-kuesel commented 1 year ago

i hope its okay to ask, but did you manage to find a way to tell if the library.section.update has finished @doug-w ? in my limited testing the updatedAt did not change with the update(), so this does not seem to be a way to achieve what i want. my case might be possible to do with a 10 second sleep, but i rather just know for sure the update() went through before continuing.

jjlawren commented 1 year ago

As @Hellowlol suggested earlier in the issue, the websocket subscription will deliver when the library has been updated. It's a more complex setup as you'll need to set up a separate websocket connection (i.e., AlertListener), but it's more accurate and faster than repeatedly polling.

In the delivered payload, library updates can be found when payload["StatusNotification"][0]["title"] == "Library scan complete".

cpt-kuesel commented 1 year ago

thank you for your answer and explaining the websocket subscription more. it seems a bit daunting for a python beginner like me, but with the sleep() fallback option i shall try it out!