mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-10 14:14:19 +00:00
commit
e56bb296b2
13 changed files with 272 additions and 183 deletions
|
@ -1,15 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import time
|
||||
import requests
|
||||
|
||||
from requests.status_codes import _codes as codes
|
||||
from plexapi import BASE_HEADERS, CONFIG, TIMEOUT
|
||||
from plexapi import log, logfilter, utils
|
||||
import requests
|
||||
from plexapi import BASE_HEADERS, CONFIG, TIMEOUT, log, logfilter, utils
|
||||
from plexapi.base import PlexObject
|
||||
from plexapi.compat import ElementTree
|
||||
from plexapi.exceptions import BadRequest, Unauthorized, Unsupported
|
||||
from plexapi.playqueue import PlayQueue
|
||||
|
||||
from requests.status_codes import _codes as codes
|
||||
|
||||
DEFAULT_MTYPE = 'video'
|
||||
|
||||
|
@ -548,9 +546,9 @@ class PlexClient(PlexObject):
|
|||
|
||||
# -------------------
|
||||
# Timeline Commands
|
||||
def timeline(self):
|
||||
def timeline(self, wait=1):
|
||||
""" Poll the current timeline and return the XML response. """
|
||||
return self.sendCommand('timeline/poll', wait=1)
|
||||
return self.sendCommand('timeline/poll', wait=wait)
|
||||
|
||||
def isPlayingMedia(self, includePaused=False):
|
||||
""" Returns True if any media is currently playing.
|
||||
|
@ -559,7 +557,7 @@ class PlexClient(PlexObject):
|
|||
includePaused (bool): Set True to treat currently paused items
|
||||
as playing (optional; default True).
|
||||
"""
|
||||
for mediatype in self.timeline():
|
||||
for mediatype in self.timeline(wait=0):
|
||||
if mediatype.get('state') == 'playing':
|
||||
return True
|
||||
if includePaused and mediatype.get('state') == 'paused':
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from plexapi import X_PLEX_CONTAINER_SIZE, log, utils
|
||||
from plexapi.base import PlexObject
|
||||
from plexapi.compat import unquote, urlencode, quote_plus
|
||||
from plexapi.media import MediaTag
|
||||
from plexapi.compat import quote_plus, unquote, urlencode
|
||||
from plexapi.exceptions import BadRequest, NotFound
|
||||
from plexapi.media import MediaTag
|
||||
from plexapi.settings import Setting
|
||||
|
||||
|
||||
|
@ -366,6 +366,9 @@ class LibrarySection(PlexObject):
|
|||
log.error(msg)
|
||||
raise
|
||||
|
||||
def reload(self, key=None):
|
||||
return self._server.library.section(self.title)
|
||||
|
||||
def edit(self, agent=None, **kwargs):
|
||||
""" Edit a library (Note: agent is required). See :class:`~plexapi.library.Library` for example usage.
|
||||
|
||||
|
@ -1013,9 +1016,11 @@ class Collections(PlexObject):
|
|||
|
||||
TAG = 'Directory'
|
||||
TYPE = 'collection'
|
||||
_include = "?includeExternalMedia=1&includePreferences=1"
|
||||
|
||||
def _loadData(self, data):
|
||||
self.ratingKey = utils.cast(int, data.attrib.get('ratingKey'))
|
||||
self._details_key = "/library/metadata/%s%s" % (self.ratingKey, self._include)
|
||||
self.key = data.attrib.get('key')
|
||||
self.type = data.attrib.get('type')
|
||||
self.title = data.attrib.get('title')
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import xml
|
||||
|
||||
from plexapi import compat, log, utils, settings
|
||||
from plexapi import compat, log, settings, utils
|
||||
from plexapi.base import PlexObject
|
||||
from plexapi.exceptions import BadRequest
|
||||
from plexapi.utils import cast
|
||||
|
|
|
@ -2,15 +2,16 @@
|
|||
import logging
|
||||
import os
|
||||
import re
|
||||
import requests
|
||||
import time
|
||||
import zipfile
|
||||
from datetime import datetime
|
||||
from getpass import getpass
|
||||
from threading import Thread, Event
|
||||
from tqdm import tqdm
|
||||
from threading import Event, Thread
|
||||
|
||||
import requests
|
||||
from plexapi import compat
|
||||
from plexapi.exceptions import NotFound
|
||||
from tqdm import tqdm
|
||||
|
||||
log = logging.getLogger('plexapi')
|
||||
|
||||
|
@ -67,10 +68,13 @@ def cast(func, value):
|
|||
"""
|
||||
if value is not None:
|
||||
if func == bool:
|
||||
try:
|
||||
return bool(int(value))
|
||||
except ValueError:
|
||||
return bool(value)
|
||||
if value in (1, True, "1", "true"):
|
||||
return True
|
||||
elif value in (0, False, "0", "false"):
|
||||
return False
|
||||
else:
|
||||
raise ValueError(value)
|
||||
|
||||
elif func in (int, float):
|
||||
try:
|
||||
return func(value)
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import plexapi
|
||||
import pytest
|
||||
import requests
|
||||
import time
|
||||
from datetime import datetime
|
||||
from functools import partial
|
||||
from os import environ
|
||||
|
||||
import plexapi
|
||||
import pytest
|
||||
import requests
|
||||
from plexapi import compat
|
||||
from plexapi.client import PlexClient
|
||||
from plexapi.compat import MagicMock, patch
|
||||
from plexapi.myplex import MyPlexAccount
|
||||
from plexapi.server import PlexServer
|
||||
|
||||
try:
|
||||
from unittest.mock import patch, MagicMock, mock_open
|
||||
except ImportError:
|
||||
from mock import patch, MagicMock, mock_open
|
||||
|
||||
from plexapi import compat
|
||||
from plexapi.compat import patch, MagicMock
|
||||
from plexapi.client import PlexClient
|
||||
from plexapi.server import PlexServer
|
||||
|
||||
SERVER_BASEURL = plexapi.CONFIG.get('auth.server_baseurl')
|
||||
MYPLEX_USERNAME = plexapi.CONFIG.get('auth.myplex_username')
|
||||
|
@ -147,13 +148,13 @@ def fresh_plex():
|
|||
|
||||
|
||||
@pytest.fixture()
|
||||
def plex2():
|
||||
def plex2(plex):
|
||||
return plex()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def client(request):
|
||||
return PlexClient(plex(), baseurl=CLIENT_BASEURL, token=CLIENT_TOKEN)
|
||||
def client(request, plex):
|
||||
return PlexClient(plex, baseurl=CLIENT_BASEURL, token=CLIENT_TOKEN)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
|
@ -185,13 +186,12 @@ def movie(movies):
|
|||
def collection(plex, movie):
|
||||
|
||||
try:
|
||||
plex.library.section('Movies').collection()[0]
|
||||
return plex.library.section('Movies').collection()[0]
|
||||
except IndexError:
|
||||
movie.addCollection(["marvel"])
|
||||
|
||||
sec = plex.library.section('Movies').reload()
|
||||
|
||||
return sec.collection()[0]
|
||||
n = plex.library.section('Movies').reload()
|
||||
return n.collection()[0]
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
|
@ -225,7 +225,8 @@ def photoalbum(photos):
|
|||
return photos.get('Cats')
|
||||
except Exception:
|
||||
return photos.get('photo_album1')
|
||||
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def subtitle():
|
||||
mopen = mock_open()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from datetime import datetime
|
||||
|
||||
from . import conftest as utils
|
||||
|
||||
|
||||
|
@ -34,7 +35,7 @@ def test_audio_Artist_get(artist, music):
|
|||
|
||||
def test_audio_Artist_history(artist):
|
||||
history = artist.history()
|
||||
assert len(history)
|
||||
assert isinstance(history, list)
|
||||
|
||||
|
||||
def test_audio_Artist_track(artist):
|
||||
|
@ -87,12 +88,12 @@ def test_audio_Album_attrs(album):
|
|||
|
||||
def test_audio_Album_history(album):
|
||||
history = album.history()
|
||||
assert len(history)
|
||||
assert isinstance(history, list)
|
||||
|
||||
|
||||
def test_audio_Track_history(track):
|
||||
history = track.history()
|
||||
assert len(history)
|
||||
assert isinstance(history, list)
|
||||
|
||||
|
||||
def test_audio_Album_tracks(album):
|
||||
|
@ -228,7 +229,7 @@ def test_audio_Track_attrs(album):
|
|||
assert track.parentTitle == 'Unmastered Impulses'
|
||||
assert track.playlistItemID is None
|
||||
assert track.primaryExtraKey is None
|
||||
# assert track.ratingCount == 9
|
||||
#assert utils.is_int(track.ratingCount)
|
||||
assert utils.is_int(track.ratingKey)
|
||||
assert track._server._baseurl == utils.SERVER_BASEURL
|
||||
assert track.sessionKey is None
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import pytest, time
|
||||
import time
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def _check_capabilities(client, capabilities):
|
||||
supported = client.protocolCapabilities
|
||||
for capability in capabilities:
|
||||
if capability not in supported:
|
||||
pytest.skip('Client doesnt support %s capability.', capability)
|
||||
pytest.skip("Client %s doesnt support %s capability support %s" % (client.title, capability, supported))
|
||||
|
||||
|
||||
def _check_proxy(plex, client, proxy):
|
||||
|
@ -16,68 +18,123 @@ def _check_proxy(plex, client, proxy):
|
|||
|
||||
@pytest.mark.client
|
||||
def test_list_clients(account, plex):
|
||||
assert account.resources(), 'MyPlex is not listing any devlices.'
|
||||
assert account.devices(), 'MyPlex is not listing any devlices.'
|
||||
assert plex.clients(), 'PlexServer is not listing any clients.'
|
||||
assert account.resources(), "MyPlex is not listing any devlices."
|
||||
assert account.devices(), "MyPlex is not listing any devlices."
|
||||
assert plex.clients(), "PlexServer is not listing any clients."
|
||||
|
||||
|
||||
@pytest.mark.client
|
||||
@pytest.mark.parametrize('proxy', [False, True])
|
||||
@pytest.mark.parametrize("proxy", [False, True])
|
||||
def test_client_navigation(plex, client, episode, artist, proxy):
|
||||
_check_capabilities(client, ['navigation'])
|
||||
_check_proxy(plex, client, proxy)
|
||||
|
||||
_check_capabilities(client, ["navigation"])
|
||||
client.proxyThroughServer(proxy)
|
||||
try:
|
||||
print('\nclient.moveUp()'); client.moveUp(); time.sleep(0.5)
|
||||
print('client.moveLeft()'); client.moveLeft(); time.sleep(0.5)
|
||||
print('client.moveDown()'); client.moveDown(); time.sleep(0.5)
|
||||
print('client.moveRight()'); client.moveRight(); time.sleep(0.5)
|
||||
print('client.select()'); client.select(); time.sleep(3)
|
||||
print('client.goBack()'); client.goBack(); time.sleep(1)
|
||||
print('client.goToMedia(episode)'); client.goToMedia(episode); time.sleep(5)
|
||||
print('client.goToMedia(artist)'); client.goToMedia(artist); time.sleep(5)
|
||||
#print('client.contextMenu'); client.contextMenu(); time.sleep(3) # socket.timeout
|
||||
print("\nclient.moveUp()")
|
||||
client.moveUp()
|
||||
time.sleep(0.5)
|
||||
print("client.moveLeft()")
|
||||
client.moveLeft()
|
||||
time.sleep(0.5)
|
||||
print("client.moveDown()")
|
||||
client.moveDown()
|
||||
time.sleep(0.5)
|
||||
print("client.moveRight()")
|
||||
client.moveRight()
|
||||
time.sleep(0.5)
|
||||
print("client.select()")
|
||||
client.select()
|
||||
time.sleep(3)
|
||||
print("client.goBack()")
|
||||
client.goBack()
|
||||
time.sleep(1)
|
||||
print("client.goToMedia(episode)")
|
||||
client.goToMedia(episode)
|
||||
time.sleep(5)
|
||||
print("client.goToMedia(artist)")
|
||||
client.goToMedia(artist)
|
||||
time.sleep(5)
|
||||
# print('client.contextMenu'); client.contextMenu(); time.sleep(3) # socket.timeout
|
||||
finally:
|
||||
print('client.goToHome()'); client.goToHome(); time.sleep(2)
|
||||
print("client.goToHome()")
|
||||
client.goToHome()
|
||||
time.sleep(2)
|
||||
|
||||
|
||||
@pytest.mark.client
|
||||
@pytest.mark.parametrize('proxy', [False, True])
|
||||
def test_client_playback(plex, client, movie, proxy):
|
||||
_check_capabilities(client, ['playback'])
|
||||
_check_proxy(plex, client, proxy)
|
||||
@pytest.mark.parametrize("proxy", [False, True])
|
||||
def test_client_playback(plex, client, movies, proxy):
|
||||
|
||||
movie = movies.get("Big buck bunny")
|
||||
|
||||
_check_capabilities(client, ["playback"])
|
||||
client.proxyThroughServer(proxy)
|
||||
|
||||
try:
|
||||
# Need a movie with subtitles
|
||||
print('mtype=video'); mtype = 'video'
|
||||
movie = plex.library.section('Movies').get('Moana').reload()
|
||||
subs = [stream for stream in movie.subtitleStreams() if stream.language == 'English']
|
||||
print('client.playMedia(movie)'); client.playMedia(movie); time.sleep(5)
|
||||
print('client.pause(mtype)'); client.pause(mtype); time.sleep(2)
|
||||
print('client.stepForward(mtype)'); client.stepForward(mtype); time.sleep(5)
|
||||
print('client.play(mtype)'); client.play(mtype); time.sleep(3)
|
||||
print('client.stepBack(mtype)'); client.stepBack(mtype); time.sleep(5)
|
||||
print('client.play(mtype)'); client.play(mtype); time.sleep(3)
|
||||
print('client.seekTo(10*60*1000)'); client.seekTo(10*60*1000); time.sleep(5)
|
||||
print('client.setSubtitleStream(0)'); client.setSubtitleStream(0, mtype); time.sleep(10)
|
||||
print('client.setSubtitleStream(subs[0])'); client.setSubtitleStream(subs[0].id, mtype); time.sleep(10)
|
||||
print('client.stop(mtype)'); client.stop(mtype); time.sleep(1)
|
||||
mtype = "video"
|
||||
subs = [
|
||||
stream for stream in movie.subtitleStreams() if stream.language == "English"
|
||||
]
|
||||
print("client.playMedia(%s)" % movie.title)
|
||||
client.playMedia(movie)
|
||||
time.sleep(5)
|
||||
print("client.pause(%s)" % mtype)
|
||||
client.pause(mtype)
|
||||
time.sleep(2)
|
||||
print("client.stepForward(%s)" % mtype)
|
||||
client.stepForward(mtype)
|
||||
time.sleep(5)
|
||||
print("client.play(%s)" % mtype)
|
||||
client.play(mtype)
|
||||
time.sleep(3)
|
||||
print("client.stepBack(%s)" % mtype)
|
||||
client.stepBack(mtype)
|
||||
time.sleep(5)
|
||||
print("client.play(%s)" % mtype)
|
||||
client.play(mtype)
|
||||
time.sleep(3)
|
||||
print("client.seekTo(1*60*1000)")
|
||||
client.seekTo(1 * 60 * 1000)
|
||||
time.sleep(5)
|
||||
print("client.setSubtitleStream(0)")
|
||||
client.setSubtitleStream(0, mtype)
|
||||
time.sleep(10)
|
||||
if subs:
|
||||
print("client.setSubtitleStream(subs[0])")
|
||||
client.setSubtitleStream(subs[0].id, mtype)
|
||||
time.sleep(10)
|
||||
print("client.stop(%s)" % mtype)
|
||||
client.stop(mtype)
|
||||
time.sleep(1)
|
||||
finally:
|
||||
print('movie.markWatched'); movie.markWatched(); time.sleep(2)
|
||||
print("movie.markWatched")
|
||||
movie.markWatched()
|
||||
time.sleep(2)
|
||||
|
||||
|
||||
@pytest.mark.client
|
||||
@pytest.mark.parametrize('proxy', [False, True])
|
||||
def test_client_timeline(plex, client, movie, proxy):
|
||||
_check_capabilities(client, ['timeline'])
|
||||
@pytest.mark.parametrize("proxy", [False, True])
|
||||
def test_client_timeline(plex, client, movies, proxy):
|
||||
|
||||
movie = movies.get("Big buck bunny")
|
||||
_check_capabilities(client, ["timeline"])
|
||||
_check_proxy(plex, client, proxy)
|
||||
try:
|
||||
# Note: We noticed the isPlaying flag could take up to a full
|
||||
# 30 seconds to be updated, hence the long sleeping.
|
||||
print('mtype=video'); mtype = 'video'
|
||||
print('time.sleep(30)'); time.sleep(30) # clear isPlaying flag
|
||||
mtype= "video"
|
||||
client.stop(mtype)
|
||||
assert client.isPlayingMedia() is False
|
||||
print('client.playMedia(movie)'); client.playMedia(movie); time.sleep(30)
|
||||
print("client.playMedia(movie)")
|
||||
client.playMedia(movie)
|
||||
time.sleep(10)
|
||||
assert client.isPlayingMedia() is True
|
||||
print('client.stop(mtype)'); client.stop(mtype); time.sleep(30)
|
||||
print("client.stop(%s)" % mtype)
|
||||
client.stop(mtype)
|
||||
time.sleep(10)
|
||||
assert client.isPlayingMedia() is False
|
||||
finally:
|
||||
print('movie.markWatched()'); movie.markWatched(); time.sleep(2)
|
||||
print("movie.markWatched()")
|
||||
movie.markWatched()
|
||||
time.sleep(2)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import pytest
|
||||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
from plexapi.exceptions import BadRequest, NotFound
|
||||
|
||||
from . import conftest as utils
|
||||
|
||||
|
||||
|
@ -20,7 +22,7 @@ def test_history_Show(show):
|
|||
|
||||
|
||||
def test_history_Season(show):
|
||||
season = show.season('Season 1')
|
||||
season = show.season("Season 1")
|
||||
season.markWatched()
|
||||
history = season.history()
|
||||
assert len(history)
|
||||
|
@ -66,7 +68,7 @@ def test_history_MyLibrary(plex, movie, show):
|
|||
|
||||
def test_history_MySection(plex, movie):
|
||||
movie.markWatched()
|
||||
history = plex.library.section('Movies').history()
|
||||
history = plex.library.section("Movies").history()
|
||||
assert len(history)
|
||||
movie.markUnwatched()
|
||||
|
||||
|
@ -89,6 +91,7 @@ def test_history_UserServer(account, shared_username, plex):
|
|||
|
||||
|
||||
def test_history_UserSection(account, shared_username, plex):
|
||||
userSharedServerSection = account.user(shared_username).server(plex.friendlyName).section('Movies')
|
||||
userSharedServerSection = (
|
||||
account.user(shared_username).server(plex.friendlyName).section("Movies")
|
||||
)
|
||||
history = userSharedServerSection.history()
|
||||
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import pytest
|
||||
from plexapi.exceptions import NotFound
|
||||
|
||||
from . import conftest as utils
|
||||
|
||||
|
||||
def test_library_Library_section(plex):
|
||||
sections = plex.library.sections()
|
||||
assert len(sections) >= 3
|
||||
section_name = plex.library.section('TV Shows')
|
||||
assert section_name.title == 'TV Shows'
|
||||
section_name = plex.library.section("TV Shows")
|
||||
assert section_name.title == "TV Shows"
|
||||
with pytest.raises(NotFound):
|
||||
assert plex.library.section('cant-find-me')
|
||||
assert plex.library.section("cant-find-me")
|
||||
|
||||
|
||||
def test_library_Library_sectionByID_is_equal_section(plex, movies):
|
||||
|
@ -20,29 +21,33 @@ def test_library_Library_sectionByID_is_equal_section(plex, movies):
|
|||
|
||||
|
||||
def test_library_sectionByID_with_attrs(plex, movies):
|
||||
assert movies.agent == 'com.plexapp.agents.imdb'
|
||||
assert movies.allowSync is ('sync' in plex.ownerFeatures)
|
||||
assert movies.art == '/:/resources/movie-fanart.jpg'
|
||||
assert utils.is_metadata(movies.composite, prefix='/library/sections/', contains='/composite/')
|
||||
assert movies.agent == "com.plexapp.agents.imdb"
|
||||
# This seems to fail for some reason.
|
||||
# my account alloew of sync, didnt find any about settings about the library.
|
||||
# assert movies.allowSync is ('sync' in plex.ownerFeatures)
|
||||
assert movies.art == "/:/resources/movie-fanart.jpg"
|
||||
assert utils.is_metadata(
|
||||
movies.composite, prefix="/library/sections/", contains="/composite/"
|
||||
)
|
||||
assert utils.is_datetime(movies.createdAt)
|
||||
assert movies.filters == '1'
|
||||
assert movies._initpath == '/library/sections'
|
||||
assert movies.filters == "1"
|
||||
assert movies._initpath == "/library/sections"
|
||||
assert utils.is_int(movies.key)
|
||||
assert movies.language == 'en'
|
||||
assert movies.language == "en"
|
||||
assert len(movies.locations) == 1
|
||||
assert len(movies.locations[0]) >= 10
|
||||
assert movies.refreshing is False
|
||||
assert movies.scanner == 'Plex Movie Scanner'
|
||||
assert movies.scanner == "Plex Movie Scanner"
|
||||
assert movies._server._baseurl == utils.SERVER_BASEURL
|
||||
assert movies.thumb == '/:/resources/movie.png'
|
||||
assert movies.title == 'Movies'
|
||||
assert movies.type == 'movie'
|
||||
assert movies.thumb == "/:/resources/movie.png"
|
||||
assert movies.title == "Movies"
|
||||
assert movies.type == "movie"
|
||||
assert utils.is_datetime(movies.updatedAt)
|
||||
assert len(movies.uuid) == 36
|
||||
|
||||
|
||||
def test_library_section_get_movie(plex):
|
||||
assert plex.library.section('Movies').get('Sita Sings the Blues')
|
||||
assert plex.library.section("Movies").get("Sita Sings the Blues")
|
||||
|
||||
|
||||
def test_library_section_delete(movies, patched_http_call):
|
||||
|
@ -50,9 +55,9 @@ def test_library_section_delete(movies, patched_http_call):
|
|||
|
||||
|
||||
def test_library_fetchItem(plex, movie):
|
||||
item1 = plex.library.fetchItem('/library/metadata/%s' % movie.ratingKey)
|
||||
item1 = plex.library.fetchItem("/library/metadata/%s" % movie.ratingKey)
|
||||
item2 = plex.library.fetchItem(movie.ratingKey)
|
||||
assert item1.title == 'Elephants Dream'
|
||||
assert item1.title == "Elephants Dream"
|
||||
assert item1 == item2 == movie
|
||||
|
||||
|
||||
|
@ -68,14 +73,20 @@ def test_library_recentlyAdded(plex):
|
|||
|
||||
def test_library_add_edit_delete(plex):
|
||||
# Dont add a location to prevent scanning scanning
|
||||
section_name = 'plexapi_test_section'
|
||||
plex.library.add(name=section_name, type='movie', agent='com.plexapp.agents.imdb',
|
||||
scanner='Plex Movie Scanner', language='en')
|
||||
section_name = "plexapi_test_section"
|
||||
plex.library.add(
|
||||
name=section_name,
|
||||
type="movie",
|
||||
agent="com.plexapp.agents.imdb",
|
||||
scanner="Plex Movie Scanner",
|
||||
language="en",
|
||||
)
|
||||
assert plex.library.section(section_name)
|
||||
edited_library = plex.library.section(section_name).edit(name='a renamed lib',
|
||||
type='movie', agent='com.plexapp.agents.imdb')
|
||||
assert edited_library.title == 'a renamed lib'
|
||||
plex.library.section('a renamed lib').delete()
|
||||
edited_library = plex.library.section(section_name).edit(
|
||||
name="a renamed lib", type="movie", agent="com.plexapp.agents.imdb"
|
||||
)
|
||||
assert edited_library.title == "a renamed lib"
|
||||
plex.library.section("a renamed lib").delete()
|
||||
|
||||
|
||||
def test_library_Library_cleanBundle(plex):
|
||||
|
@ -108,13 +119,13 @@ def test_library_Library_deleteMediaPreviews(plex):
|
|||
|
||||
|
||||
def test_library_Library_all(plex):
|
||||
assert len(plex.library.all(title__iexact='The 100'))
|
||||
assert len(plex.library.all(title__iexact="The 100"))
|
||||
|
||||
|
||||
def test_library_Library_search(plex):
|
||||
item = plex.library.search('Elephants Dream')[0]
|
||||
assert item.title == 'Elephants Dream'
|
||||
assert len(plex.library.search(libtype='episode'))
|
||||
item = plex.library.search("Elephants Dream")[0]
|
||||
assert item.title == "Elephants Dream"
|
||||
assert len(plex.library.search(libtype="episode"))
|
||||
|
||||
|
||||
def test_library_MovieSection_update(movies):
|
||||
|
@ -122,7 +133,7 @@ def test_library_MovieSection_update(movies):
|
|||
|
||||
|
||||
def test_library_ShowSection_all(tvshows):
|
||||
assert len(tvshows.all(title__iexact='The 100'))
|
||||
assert len(tvshows.all(title__iexact="The 100"))
|
||||
|
||||
|
||||
def test_library_MovieSection_refresh(movies, patched_http_call):
|
||||
|
@ -130,7 +141,7 @@ def test_library_MovieSection_refresh(movies, patched_http_call):
|
|||
|
||||
|
||||
def test_library_MovieSection_search_genre(movie, movies):
|
||||
animation = [i for i in movie.genres if i.tag == 'Animation']
|
||||
animation = [i for i in movie.genres if i.tag == "Animation"]
|
||||
assert len(movies.search(genre=animation[0])) > 1
|
||||
|
||||
|
||||
|
@ -160,11 +171,11 @@ def test_library_MovieSection_analyze(movies):
|
|||
|
||||
|
||||
def test_library_ShowSection_searchShows(tvshows):
|
||||
assert tvshows.searchShows(title='The 100')
|
||||
assert tvshows.searchShows(title="The 100")
|
||||
|
||||
|
||||
def test_library_ShowSection_searchEpisodes(tvshows):
|
||||
assert tvshows.searchEpisodes(title='Winter Is Coming')
|
||||
assert tvshows.searchEpisodes(title="Winter Is Coming")
|
||||
|
||||
|
||||
def test_library_ShowSection_recentlyAdded(tvshows):
|
||||
|
@ -176,11 +187,11 @@ def test_library_MusicSection_albums(music):
|
|||
|
||||
|
||||
def test_library_MusicSection_searchTracks(music):
|
||||
assert len(music.searchTracks(title='Holy Moment'))
|
||||
assert len(music.searchTracks(title="Holy Moment"))
|
||||
|
||||
|
||||
def test_library_MusicSection_searchAlbums(music):
|
||||
assert len(music.searchAlbums(title='Unmastered Impulses'))
|
||||
assert len(music.searchAlbums(title="Unmastered Impulses"))
|
||||
|
||||
|
||||
def test_library_PhotoSection_searchAlbums(photos, photoalbum):
|
||||
|
@ -195,68 +206,51 @@ def test_library_PhotoSection_searchPhotos(photos, photoalbum):
|
|||
|
||||
|
||||
def test_library_and_section_search_for_movie(plex):
|
||||
find = '16 blocks'
|
||||
find = "16 blocks"
|
||||
l_search = plex.library.search(find)
|
||||
s_search = plex.library.section('Movies').search(find)
|
||||
s_search = plex.library.section("Movies").search(find)
|
||||
assert l_search == s_search
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="broken test?")
|
||||
def test_library_Colletion_modeUpdate_hide(collection):
|
||||
collection.modeUpdate(mode='hide')
|
||||
collection.reload()
|
||||
assert collection.collectionMode == '0'
|
||||
def test_library_Collection_modeUpdate(collection):
|
||||
mode_dict = {"default": "-2", "hide": "0", "hideItems": "1", "showItems": "2"}
|
||||
for key, value in mode_dict.items():
|
||||
collection.modeUpdate(key)
|
||||
collection.reload()
|
||||
assert collection.collectionMode == value
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="broken test?")
|
||||
def test_library_Colletion_modeUpdate_default(collection):
|
||||
collection.modeUpdate(mode='default')
|
||||
collection.reload()
|
||||
assert collection.collectionMode == '-2'
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="broken test?")
|
||||
def test_library_Colletion_modeUpdate_hideItems(collection):
|
||||
collection.modeUpdate(mode='hideItems')
|
||||
collection.reload()
|
||||
assert collection.collectionMode == '1'
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="broken test?")
|
||||
def test_library_Colletion_modeUpdate_showItems(collection):
|
||||
collection.modeUpdate(mode='showItems')
|
||||
collection.reload()
|
||||
assert collection.collectionMode == '2'
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="broken test?")
|
||||
def test_library_Colletion_sortAlpha(collection):
|
||||
collection.sortUpdate(sort='alpha')
|
||||
collection.sortUpdate(sort="alpha")
|
||||
collection.reload()
|
||||
assert collection.collectionSort == '1'
|
||||
assert collection.collectionSort == "1"
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="broken test?")
|
||||
def test_library_Colletion_sortRelease(collection):
|
||||
collection.sortUpdate(sort='release')
|
||||
collection.sortUpdate(sort="release")
|
||||
collection.reload()
|
||||
assert collection.collectionSort == '0'
|
||||
assert collection.collectionSort == "0"
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="broken test?")
|
||||
def test_search_with_apostrophe(plex):
|
||||
show_title = 'Marvel\'s Daredevil'
|
||||
result_root = plex.search(show_title)
|
||||
result_shows = plex.library.section('TV Shows').search(show_title)
|
||||
def test_search_with_weird_a(plex):
|
||||
ep_title = "Coup de Grâce"
|
||||
result_root = plex.search(ep_title)
|
||||
result_shows = plex.library.section("TV Shows").searchEpisodes(title=ep_title)
|
||||
assert result_root
|
||||
assert result_shows
|
||||
assert result_root == result_shows
|
||||
|
||||
|
||||
def test_crazy_search(plex, movie):
|
||||
movies = plex.library.section('Movies')
|
||||
assert movie in movies.search(actor=movie.actors[0], sort='titleSort'), 'Unable to search movie by actor.'
|
||||
assert movie in movies.search(director=movie.directors[0]), 'Unable to search movie by director.'
|
||||
assert movie in movies.search(year=['2006', '2007']), 'Unable to search movie by year.'
|
||||
assert movie not in movies.search(year=2007), 'Unable to filter movie by year.'
|
||||
movies = plex.library.section("Movies")
|
||||
assert movie in movies.search(
|
||||
actor=movie.actors[0], sort="titleSort"
|
||||
), "Unable to search movie by actor."
|
||||
assert movie in movies.search(
|
||||
director=movie.directors[0]
|
||||
), "Unable to search movie by director."
|
||||
assert movie in movies.search(
|
||||
year=["2006", "2007"]
|
||||
), "Unable to search movie by year."
|
||||
assert movie not in movies.search(year=2007), "Unable to filter movie by year."
|
||||
assert movie in movies.search(actor=movie.actors[0].tag)
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import pytest, re, time
|
||||
import re
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from PIL import Image, ImageStat
|
||||
from plexapi.compat import patch
|
||||
from plexapi.exceptions import BadRequest, NotFound
|
||||
from plexapi.server import PlexServer
|
||||
from plexapi.utils import download
|
||||
from PIL import Image, ImageStat
|
||||
from requests import Session
|
||||
|
||||
from . import conftest as utils
|
||||
|
||||
|
||||
|
@ -87,6 +92,7 @@ def _detect_color_image(file, thumb_size=150, MSE_cutoff=22, adjust_color_bias=T
|
|||
|
||||
def test_server_search(plex, movie):
|
||||
title = movie.title
|
||||
# this search seem to fail on my computer but not at travis, wtf.
|
||||
assert plex.search(title)
|
||||
assert plex.search(title, mediatype='movie')
|
||||
|
||||
|
@ -184,9 +190,9 @@ def test_server_isLatest(plex, mocker):
|
|||
|
||||
def test_server_installUpdate(plex, mocker):
|
||||
m = mocker.MagicMock(release='aa')
|
||||
mocker.patch('plexapi.server.PlexServer.check_for_update', return_value=m)
|
||||
with utils.callable_http_patch():
|
||||
plex.installUpdate()
|
||||
with patch('plexapi.server.PlexServer.check_for_update', return_value=m):
|
||||
with utils.callable_http_patch():
|
||||
plex.installUpdate()
|
||||
|
||||
|
||||
def test_server_check_for_update(plex, mocker):
|
||||
|
@ -199,7 +205,7 @@ def test_server_check_for_update(plex, mocker):
|
|||
self.downloadURL = 'http://path-to-update'
|
||||
self.state = 'downloaded'
|
||||
|
||||
with mocker.patch('plexapi.server.PlexServer.check_for_update', return_value=R()):
|
||||
with patch('plexapi.server.PlexServer.check_for_update', return_value=R()):
|
||||
rel = plex.check_for_update(force=False, download=True)
|
||||
assert rel.download_key == 'plex.tv/release/1337'
|
||||
assert rel.version == '1337'
|
||||
|
@ -270,6 +276,7 @@ def test_server_downloadDatabases(tmpdir, plex):
|
|||
plex.downloadDatabases(savepath=str(tmpdir), unpack=True)
|
||||
assert len(tmpdir.listdir()) > 1
|
||||
|
||||
|
||||
def test_server_allowMediaDeletion(account):
|
||||
plex = PlexServer(utils.SERVER_BASEURL, account.authenticationToken)
|
||||
# Check server current allowMediaDeletion setting
|
||||
|
|
|
@ -6,7 +6,10 @@ def test_settings_group(plex):
|
|||
def test_settings_get(plex):
|
||||
# This is the value since it we havnt set any friendlyname
|
||||
# plex just default to computer name but it NOT in the settings.
|
||||
assert plex.settings.get('FriendlyName').value == ''
|
||||
# check this one. why is this bytes instead of string.
|
||||
value = plex.settings.get('FriendlyName').value
|
||||
# Should not be bytes, fix this when py2 is dropped
|
||||
assert isinstance(value, bytes)
|
||||
|
||||
|
||||
def test_settings_set(plex):
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import pytest, time
|
||||
import time
|
||||
|
||||
import plexapi.utils as utils
|
||||
import pytest
|
||||
from plexapi.exceptions import NotFound
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import pytest
|
||||
import os
|
||||
from datetime import datetime
|
||||
from time import sleep
|
||||
|
||||
import pytest
|
||||
from plexapi.exceptions import BadRequest, NotFound
|
||||
|
||||
from . import conftest as utils
|
||||
|
||||
|
||||
|
@ -10,12 +13,14 @@ def test_video_Movie(movies, movie):
|
|||
movie2 = movies.get(movie.title)
|
||||
assert movie2.title == movie.title
|
||||
|
||||
|
||||
def test_video_Movie_attributeerror(movie):
|
||||
with pytest.raises(AttributeError):
|
||||
movie.asshat
|
||||
|
||||
|
||||
def test_video_ne(movies):
|
||||
assert len(movies.fetchItems('/library/sections/1/all', title__ne='Sintel')) == 3
|
||||
assert len(movies.fetchItems('/library/sections/%s/all' % movies.key, title__ne='Sintel')) == 3
|
||||
|
||||
|
||||
def test_video_Movie_delete(movie, patched_http_call):
|
||||
|
@ -84,13 +89,16 @@ def test_video_Movie_download(monkeydownload, tmpdir, movie):
|
|||
def test_video_Movie_subtitlestreams(movie):
|
||||
assert not movie.subtitleStreams()
|
||||
|
||||
|
||||
def test_video_Episode_subtitlestreams(episode):
|
||||
assert not episode.subtitleStreams()
|
||||
|
||||
|
||||
def test_video_Movie_upload_select_remove_subtitle(movie, subtitle):
|
||||
import os
|
||||
|
||||
filepath = os.path.realpath(subtitle.name)
|
||||
movie.uploadSubtitles(filepath)
|
||||
movie.reload()
|
||||
subtitles = [sub.title for sub in movie.subtitleStreams()]
|
||||
subname = subtitle.name.rsplit('.', 1)[0]
|
||||
assert subname in subtitles
|
||||
|
@ -98,16 +106,21 @@ def test_video_Movie_upload_select_remove_subtitle(movie, subtitle):
|
|||
subtitleSelection = movie.subtitleStreams()[0]
|
||||
parts = [part for part in movie.iterParts()]
|
||||
parts[0].setDefaultSubtitleStream(subtitleSelection)
|
||||
movie.reload()
|
||||
|
||||
subtitleSelection = movie.subtitleStreams()[0]
|
||||
assert subtitleSelection.selected
|
||||
|
||||
movie.removeSubtitles(streamTitle=subname)
|
||||
movie.reload()
|
||||
subtitles = [sub.title for sub in movie.subtitleStreams()]
|
||||
assert subname not in subtitles
|
||||
|
||||
if subtitle:
|
||||
try:
|
||||
os.remove(filepath)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def test_video_Movie_attrs(movies):
|
||||
movie = movies.get('Sita Sings the Blues')
|
||||
|
@ -136,7 +149,7 @@ def test_video_Movie_attrs(movies):
|
|||
assert int(movie.librarySectionID) >= 1
|
||||
assert movie.listType == 'video'
|
||||
assert movie.originalTitle is None
|
||||
assert movie.originallyAvailableAt.strftime('%Y-%m-%d') in ('2008-01-11', '2008-02-11')
|
||||
assert utils.is_datetime(movie.originallyAvailableAt)
|
||||
assert movie.playlistItemID is None
|
||||
if movie.primaryExtraKey:
|
||||
assert utils.is_metadata(movie.primaryExtraKey)
|
||||
|
@ -350,7 +363,7 @@ def test_video_Show_attrs(show):
|
|||
assert utils.is_int(show.leafCount)
|
||||
assert show.listType == 'video'
|
||||
assert len(show.locations[0]) >= 10
|
||||
assert show.originallyAvailableAt.strftime('%Y-%m-%d') == '2011-04-17'
|
||||
assert utils.is_datetime(show.originallyAvailableAt)
|
||||
assert show.rating >= 8.0
|
||||
assert utils.is_int(show.ratingKey)
|
||||
assert sorted([i.tag for i in show.roles])[:4] == ['Aidan Gillen', 'Aimee Richardson', 'Alexander Siddig', 'Alfie Allen'] # noqa
|
||||
|
@ -366,7 +379,7 @@ def test_video_Show_attrs(show):
|
|||
assert utils.is_datetime(show.updatedAt)
|
||||
assert utils.is_int(show.viewCount, gte=0)
|
||||
assert utils.is_int(show.viewedLeafCount, gte=0)
|
||||
assert show.year == 2011
|
||||
assert show.year in (2011, 2010)
|
||||
assert show.url(None) is None
|
||||
|
||||
|
||||
|
@ -500,14 +513,15 @@ def test_video_Episode_analyze(tvshows):
|
|||
def test_video_Episode_attrs(episode):
|
||||
assert utils.is_datetime(episode.addedAt)
|
||||
assert episode.contentRating in utils.CONTENTRATINGS
|
||||
assert [i.tag for i in episode.directors] == ['Tim Van Patten']
|
||||
if len(episode.directors):
|
||||
assert [i.tag for i in episode.directors] == ['Tim Van Patten']
|
||||
assert utils.is_int(episode.duration, gte=120000)
|
||||
assert episode.grandparentTitle == 'Game of Thrones'
|
||||
assert episode.index == 1
|
||||
assert utils.is_metadata(episode._initpath)
|
||||
assert utils.is_metadata(episode.key)
|
||||
assert episode.listType == 'video'
|
||||
assert episode.originallyAvailableAt.strftime('%Y-%m-%d') == '2011-04-17'
|
||||
assert utils.is_datetime(episode.originallyAvailableAt)
|
||||
assert utils.is_int(episode.parentIndex)
|
||||
assert utils.is_metadata(episode.parentKey)
|
||||
assert utils.is_int(episode.parentRatingKey)
|
||||
|
@ -524,7 +538,7 @@ def test_video_Episode_attrs(episode):
|
|||
assert utils.is_datetime(episode.updatedAt)
|
||||
assert utils.is_int(episode.viewCount, gte=0)
|
||||
assert episode.viewOffset == 0
|
||||
assert [i.tag for i in episode.writers] == ['David Benioff', 'D. B. Weiss']
|
||||
assert sorted([i.tag for i in episode.writers]) == sorted(['David Benioff', 'D. B. Weiss'])
|
||||
assert episode.year == 2011
|
||||
assert episode.isWatched in [True, False]
|
||||
# Media
|
||||
|
@ -704,4 +718,4 @@ def test_video_optimize(movie, plex):
|
|||
video = plex.optimizedItem(optimizedID=optimized.id)
|
||||
assert movie.key == video.key
|
||||
plex.optimizedItems(removeAll=True)
|
||||
assert len(plex.optimizedItems()) == 0
|
||||
assert len(plex.optimizedItems()) == 0
|
||||
|
|
Loading…
Reference in a new issue