Add Library timeline support (#573)

* Add Library timeline support

* Retry intentional failure with different canary test

* Temporarily disable activities tests

* Set tests for normal runs

* Add tests to validate library timeline attributes
This commit is contained in:
jjlawren 2020-09-21 16:06:14 -05:00 committed by GitHub
parent 8410d81520
commit 860ad7bc3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 95 additions and 2 deletions

View file

@ -466,6 +466,12 @@ class LibrarySection(PlexObject):
data = self._server.query(key)
return self.findItems(data, cls=Setting)
def timeline(self):
""" Returns a timeline query for this library section. """
key = '/library/sections/%s/timeline' % self.key
data = self._server.query(key)
return LibraryTimeline(self, data)
def onDeck(self):
""" Returns a list of media items on deck from this library section. """
key = '/library/sections/%s/onDeck' % self.key
@ -1060,6 +1066,46 @@ class FilterChoice(PlexObject):
self.type = data.attrib.get('type')
@utils.registerPlexObject
class LibraryTimeline(PlexObject):
"""Represents a LibrarySection timeline.
Attributes:
TAG (str): 'LibraryTimeline'
size (int): Unknown
allowSync (bool): Unknown
art (str): Relative path to art image.
content (str): "secondary"
identifier (str): "com.plexapp.plugins.library"
latestEntryTime (int): Epoch timestamp
mediaTagPrefix (str): "/system/bundle/media/flags/"
mediaTagVersion (int): Unknown
thumb (str): Relative path to library thumb image.
title1 (str): Name of library section.
updateQueueSize (int): Number of items queued to update.
viewGroup (str): "secondary"
viewMode (int): Unknown
"""
TAG = 'LibraryTimeline'
def _loadData(self, data):
""" Load attribute values from Plex XML response. """
self._data = data
self.size = utils.cast(int, data.attrib.get('size'))
self.allowSync = utils.cast(bool, data.attrib.get('allowSync'))
self.art = data.attrib.get('art')
self.content = data.attrib.get('content')
self.identifier = data.attrib.get('identifier')
self.latestEntryTime = utils.cast(int, data.attrib.get('latestEntryTime'))
self.mediaTagPrefix = data.attrib.get('mediaTagPrefix')
self.mediaTagVersion = utils.cast(int, data.attrib.get('mediaTagVersion'))
self.thumb = data.attrib.get('thumb')
self.title1 = data.attrib.get('title1')
self.updateQueueSize = utils.cast(int, data.attrib.get('updateQueueSize'))
self.viewGroup = data.attrib.get('viewGroup')
self.viewMode = utils.cast(int, data.attrib.get('viewMode'))
@utils.registerPlexObject
class Location(PlexObject):
""" Represents a single library Location.

View file

@ -16,10 +16,37 @@ def wait_for_idle_server(server):
assert attempts < MAX_ATTEMPTS, f"Server still busy after {MAX_ATTEMPTS}s"
def test_ensure_metadata_scans_completed(plex):
def wait_for_metadata_processing(server):
"""Wait for async metadata processing to complete."""
attempts = 0
while True:
busy = False
for section in server.library.sections():
tl = section.timeline()
if tl.updateQueueSize > 0:
busy = True
print(f"{section.title}: {tl.updateQueueSize} items left")
if not busy or attempts > MAX_ATTEMPTS:
break
time.sleep(1)
attempts += 1
assert attempts < MAX_ATTEMPTS, f"Metadata still processing after {MAX_ATTEMPTS}s"
def test_ensure_activities_completed(plex):
wait_for_idle_server(plex)
@pytest.mark.authenticated
def test_ensure_metadata_scans_completed_authenticated(plex):
def test_ensure_activities_completed_authenticated(plex):
wait_for_idle_server(plex)
def test_ensure_metadata_scans_completed(plex):
wait_for_metadata_processing(plex)
@pytest.mark.authenticated
def test_ensure_metadata_scans_completed_authenticated(plex):
wait_for_metadata_processing(plex)

View file

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from datetime import datetime
import pytest
from plexapi.exceptions import NotFound
@ -277,3 +278,22 @@ def test_crazy_search(plex, movie):
assert len(movies.search(container_size=1)) == 4
assert len(movies.search(container_start=9999, container_size=1)) == 0
assert len(movies.search(container_start=2, container_size=1)) == 2
def test_library_section_timeline(plex):
movies = plex.library.section("Movies")
tl = movies.timeline()
assert tl.TAG == "LibraryTimeline"
assert tl.size > 0
assert tl.allowSync is False
assert tl.art == "/:/resources/movie-fanart.jpg"
assert tl.content == "secondary"
assert tl.identifier == "com.plexapp.plugins.library"
assert datetime.fromtimestamp(tl.latestEntryTime).date() == datetime.today().date()
assert tl.mediaTagPrefix == "/system/bundle/media/flags/"
assert tl.mediaTagVersion > 1
assert tl.thumb == "/:/resources/movie.png"
assert tl.title1 == "Movies"
assert tl.updateQueueSize == 0
assert tl.viewGroup == "secondary"
assert tl.viewMode == 65592