mirror of
https://github.com/pkkid/python-plexapi
synced 2025-02-16 21:08:27 +00:00
Move _find function from PlexPartialObject to generic utility functions
This commit is contained in:
parent
3889c49b30
commit
e81f2506e9
7 changed files with 87 additions and 92 deletions
22
CHANGELOG.md
22
CHANGELOG.md
|
@ -1,22 +0,0 @@
|
|||
# Python-PlexAPI Change Log #
|
||||
|
||||
### Version 2.0.0 ###
|
||||
* Added support for audio.
|
||||
* Ability to compare NA value with None.
|
||||
* Use a session for requests to get advantages of keepalive.
|
||||
* Add tagging to tests to more easily run tests for a specific category.
|
||||
* Bugfix: Level for a media object might not always be an integer.
|
||||
|
||||
### NAME CHANGES IN VERSION 2.0.0 (this will only ever happen on a major version increment) ###
|
||||
* myplex.MyPlexResource.fetch_resources() renamed to myplex.MyPlexResource.fetchResources()
|
||||
* myplex.MyPlexDevice.fetch_resources() renamed to myplex.MyPlexDevice.fetchResources()
|
||||
* myplex.MyPlexResource.fetch_resources() renamed to myplex.MyPlexResource.fetchResources()
|
||||
* media.VideoTag() renamed to media.MediaTag()
|
||||
* media.MediaPart.select_stream() renamed to media.MediaPart.selectedStream()
|
||||
* video.iter_parts() was renamed to video.iterParts()
|
||||
* config.PlexConfig._as_dict() renamed to config.PlexConfig._asDict()
|
||||
* build_item() renamed to buildItem() and moved to utils.py
|
||||
* list_items() renamed to listItems() and moved to utils.py
|
||||
* find_item() renamed to findItem() and moved to utils.py
|
||||
* find_key() renamed to findKey() and moved to utils.py
|
||||
* search_type() renamed to searchType() and moved to utils.py
|
|
@ -33,7 +33,7 @@ class Artist(Audio):
|
|||
self.art = data.attrib.get('art', NA)
|
||||
self.guid = data.attrib.get('guid', NA)
|
||||
self.key = self.key.replace('/children', '') # plex bug? http://bit.ly/1Sc2J3V
|
||||
self.location = self._findLocation(data)
|
||||
self.location = utils.findLocation(data)
|
||||
if self.isFullObject():
|
||||
self.countries = [media.Country(self.server, e) for e in data if e.tag == media.Country.TYPE]
|
||||
self.genres = [media.Genre(self.server, e) for e in data if e.tag == media.Genre.TYPE]
|
||||
|
@ -141,9 +141,9 @@ class Track(Audio):
|
|||
self.media = [media.Media(self.server, e, self.initpath, self) for e in data if e.tag == media.Media.TYPE]
|
||||
# data for active sessions
|
||||
self.sessionKey = utils.cast(int, data.attrib.get('sessionKey', NA))
|
||||
self.user = self._findUser(data)
|
||||
self.player = self._findPlayer(data)
|
||||
self.transcodeSession = self._findTranscodeSession(data)
|
||||
self.user = utils.findUser(data, self.initpath)
|
||||
self.player = utils.findPlayer(self.server, data)
|
||||
self.transcodeSession = utils.findTranscodeSession(self.server, data)
|
||||
|
||||
@property
|
||||
def thumbUrl(self):
|
||||
|
|
|
@ -45,7 +45,6 @@ class MyPlexUser(object):
|
|||
self.subscriptionFeatures = None # renamed on server
|
||||
self.roles = None
|
||||
self.entitlements = None
|
||||
|
||||
|
||||
def devices(self):
|
||||
return _listItems(MyPlexDevice.DEVICES, self.authenticationToken, MyPlexDevice)
|
||||
|
|
|
@ -39,13 +39,16 @@ NA = _NA()
|
|||
class PlexPartialObject(object):
|
||||
|
||||
def __init__(self, server, data, initpath):
|
||||
self.server = server
|
||||
self.server = server # TODO: This should not be needed here..
|
||||
self.initpath = initpath
|
||||
self._loadData(data)
|
||||
|
||||
# TODO: Make this work with objects that contain id instead of key (MyPlex objects)
|
||||
def __eq__(self, other):
|
||||
return other is not None and self.type == other.type and self.key == other.key
|
||||
|
||||
# TODO: This shouldn't be here, move downstream
|
||||
# or make it work with MyPlex objects..
|
||||
def __repr__(self):
|
||||
title = self.title.replace(' ','.')[0:20]
|
||||
return '<%s:%s:%s>' % (self.__class__.__name__, self.ratingKey, title.encode('utf8'))
|
||||
|
@ -59,10 +62,12 @@ class PlexPartialObject(object):
|
|||
if value != NA:
|
||||
super(PlexPartialObject, self).__setattr__(attr, value)
|
||||
|
||||
# TODO: This shouldn't be here, move downstream
|
||||
@property
|
||||
def thumbUrl(self):
|
||||
return self.server.url(self.thumb)
|
||||
|
||||
# TODO: Move to Playable()
|
||||
def _getStreamURL(self, **params):
|
||||
if self.TYPE not in ('movie', 'episode', 'track'):
|
||||
raise Unsupported('Fetching stream URL for %s is unsupported.' % self.TYPE)
|
||||
|
@ -82,42 +87,6 @@ class PlexPartialObject(object):
|
|||
streamtype = 'audio' if self.TYPE in ('track', 'album') else 'video'
|
||||
return self.server.url('/%s/:/transcode/universal/start.m3u8?%s' % (streamtype, urlencode(params)))
|
||||
|
||||
def _findLocation(self, data):
|
||||
elem = data.find('Location')
|
||||
if elem is not None:
|
||||
return elem.attrib.get('path')
|
||||
return None
|
||||
|
||||
def _findPlayer(self, data):
|
||||
elem = data.find('Player')
|
||||
if elem is not None:
|
||||
from plexapi.client import PlexClient
|
||||
return PlexClient(self.server, elem)
|
||||
return None
|
||||
|
||||
def _findStreams(self, streamtype):
|
||||
streams = []
|
||||
for media in self.media:
|
||||
for part in media.parts:
|
||||
for stream in part.streams:
|
||||
if stream.TYPE == streamtype:
|
||||
streams.append(stream)
|
||||
return streams
|
||||
|
||||
def _findTranscodeSession(self, data):
|
||||
elem = data.find('TranscodeSession')
|
||||
if elem is not None:
|
||||
from plexapi import media
|
||||
return media.TranscodeSession(self.server, elem)
|
||||
return None
|
||||
|
||||
def _findUser(self, data):
|
||||
elem = data.find('User')
|
||||
if elem is not None:
|
||||
from plexapi.myplex import MyPlexUser
|
||||
return MyPlexUser(elem, self.initpath)
|
||||
return None
|
||||
|
||||
def _loadData(self, data):
|
||||
raise Exception('Abstract method not implemented.')
|
||||
|
||||
|
@ -127,14 +96,17 @@ class PlexPartialObject(object):
|
|||
def isPartialObject(self):
|
||||
return not self.isFullObject()
|
||||
|
||||
# TODO: Move to Playable()
|
||||
def iterParts(self):
|
||||
for item in self.media:
|
||||
for part in item.parts:
|
||||
yield part
|
||||
|
||||
# TODO: Move to Playable()
|
||||
def play(self, client):
|
||||
client.playMedia(self)
|
||||
|
||||
# TODO: This shouldn't be here, move downstream
|
||||
def refresh(self):
|
||||
self.server.query('%s/refresh' % self.key, method=put)
|
||||
|
||||
|
@ -183,6 +155,47 @@ def findItem(server, path, title):
|
|||
raise NotFound('Unable to find item: %s' % title)
|
||||
|
||||
|
||||
def findLocation(data):
|
||||
elem = data.find('Location')
|
||||
if elem is not None:
|
||||
return elem.attrib.get('path')
|
||||
return None
|
||||
|
||||
|
||||
def findPlayer(server, data):
|
||||
elem = data.find('Player')
|
||||
if elem is not None:
|
||||
from plexapi.client import PlexClient
|
||||
return PlexClient(server, elem)
|
||||
return None
|
||||
|
||||
|
||||
def findStreams(media, streamtype):
|
||||
streams = []
|
||||
for mediaitem in media:
|
||||
for part in mediaitem.parts:
|
||||
for stream in part.streams:
|
||||
if stream.TYPE == streamtype:
|
||||
streams.append(stream)
|
||||
return streams
|
||||
|
||||
|
||||
def findTranscodeSession(server, data):
|
||||
elem = data.find('TranscodeSession')
|
||||
if elem is not None:
|
||||
from plexapi import media
|
||||
return media.TranscodeSession(server, elem)
|
||||
return None
|
||||
|
||||
|
||||
def findUser(data, initpath):
|
||||
elem = data.find('User')
|
||||
if elem is not None:
|
||||
from plexapi.myplex import MyPlexUser
|
||||
return MyPlexUser(elem, initpath)
|
||||
return None
|
||||
|
||||
|
||||
def isInt(string):
|
||||
try:
|
||||
int(string)
|
||||
|
|
|
@ -79,14 +79,14 @@ class Movie(Video):
|
|||
self.producers = [media.Producer(self.server, e) for e in data if e.tag == media.Producer.TYPE]
|
||||
self.roles = [media.Role(self.server, e) for e in data if e.tag == media.Role.TYPE]
|
||||
self.writers = [media.Writer(self.server, e) for e in data if e.tag == media.Writer.TYPE]
|
||||
self.videoStreams = self._findStreams('videostream')
|
||||
self.audioStreams = self._findStreams('audiostream')
|
||||
self.subtitleStreams = self._findStreams('subtitlestream')
|
||||
self.videoStreams = utils.findStreams(self.media, 'videostream')
|
||||
self.audioStreams = utils.findStreams(self.media, 'audiostream')
|
||||
self.subtitleStreams = utils.findStreams(self.media, 'subtitlestream')
|
||||
# data for active sessions
|
||||
self.sessionKey = utils.cast(int, data.attrib.get('sessionKey', NA))
|
||||
self.user = self._findUser(data)
|
||||
self.player = self._findPlayer(data)
|
||||
self.transcodeSession = self._findTranscodeSession(data)
|
||||
self.user = utils.findUser(data, self.initpath)
|
||||
self.player = utils.findPlayer(self.server, data)
|
||||
self.transcodeSession = utils.findTranscodeSession(self.server, data)
|
||||
|
||||
@property
|
||||
def actors(self):
|
||||
|
@ -113,7 +113,7 @@ class Show(Video):
|
|||
self.duration = utils.cast(int, data.attrib.get('duration', NA))
|
||||
self.guid = data.attrib.get('guid', NA)
|
||||
self.leafCount = utils.cast(int, data.attrib.get('leafCount', NA))
|
||||
self.location = self._findLocation(data)
|
||||
self.location = utils.findLocation(data)
|
||||
self.originallyAvailableAt = utils.toDatetime(data.attrib.get('originallyAvailableAt', NA), '%Y-%m-%d')
|
||||
self.rating = utils.cast(float, data.attrib.get('rating', NA))
|
||||
self.studio = data.attrib.get('studio', NA)
|
||||
|
@ -226,14 +226,14 @@ class Episode(Video):
|
|||
self.directors = [media.Director(self.server, e) for e in data if e.tag == media.Director.TYPE]
|
||||
self.media = [media.Media(self.server, e, self.initpath, self) for e in data if e.tag == media.Media.TYPE]
|
||||
self.writers = [media.Writer(self.server, e) for e in data if e.tag == media.Writer.TYPE]
|
||||
self.videoStreams = self._findStreams('videostream')
|
||||
self.audioStreams = self._findStreams('audiostream')
|
||||
self.subtitleStreams = self._findStreams('subtitlestream')
|
||||
self.videoStreams = utils.findStreams(self.media, 'videostream')
|
||||
self.audioStreams = utils.findStreams(self.media, 'audiostream')
|
||||
self.subtitleStreams = utils.findStreams(self.media, 'subtitlestream')
|
||||
# data for active sessions
|
||||
self.sessionKey = utils.cast(int, data.attrib.get('sessionKey', NA))
|
||||
self.user = self._findUser(data)
|
||||
self.player = self._findPlayer(data)
|
||||
self.transcodeSession = self._findTranscodeSession(data)
|
||||
self.user = utils.findUser(data, self.initpath)
|
||||
self.player = utils.findPlayer(self.server, data)
|
||||
self.transcodeSession = utils.findTranscodeSession(self.server, data)
|
||||
|
||||
@property
|
||||
def isWatched(self):
|
||||
|
|
|
@ -10,9 +10,8 @@ run this test suite with the following command:
|
|||
import argparse, sys, time
|
||||
from os.path import dirname, abspath
|
||||
sys.path.append(dirname(dirname(abspath(__file__))))
|
||||
from utils import log, register, run_tests
|
||||
from plexapi.client import PlexClient
|
||||
from plexapi.exceptions import NotFound
|
||||
from utils import log, register, safe_client, run_tests
|
||||
from plexapi.myplex import MyPlexUser
|
||||
from plexapi.utils import NA
|
||||
|
||||
SHOW_SECTION = 'TV Shows'
|
||||
|
@ -25,9 +24,9 @@ AUDIO_SECTION = 'Music'
|
|||
AUDIO_ARTIST = 'Beastie Boys'
|
||||
AUDIO_ALBUM = 'Licensed To Ill'
|
||||
AUDIO_TRACK = 'Brass Monkey'
|
||||
CLIENT = 'pkkid-home'
|
||||
CLIENT_BASEURL = 'http://192.168.1.131:3005'
|
||||
|
||||
PLEX_CLIENT = 'pkkid-home'
|
||||
PLEX_CLIENT_BASEURL = 'http://192.168.1.131:3005'
|
||||
|
||||
#-----------------------
|
||||
# Core
|
||||
|
@ -390,17 +389,13 @@ def test_list_clients(plex, user=None):
|
|||
|
||||
@register('client')
|
||||
def test_client_navigation(plex, user=None):
|
||||
try:
|
||||
client = plex.client(PLEX_CLIENT)
|
||||
except NotFound as err:
|
||||
log(2, 'Warning: %s' % err)
|
||||
client = PlexClient(PLEX_CLIENT_BASEURL, server=plex)
|
||||
client = safe_client(CLIENT, CLIENT_BASEURL, plex)
|
||||
_navigate(plex, client)
|
||||
|
||||
|
||||
# @register('client')
|
||||
def test_client_navigation_via_proxy(plex, user=None):
|
||||
client = plex.client(PLEX_CLIENT)
|
||||
client = safe_client(CLIENT, CLIENT_BASEURL, plex)
|
||||
client.proxyThroughServer()
|
||||
_navigate(plex, client)
|
||||
|
||||
|
@ -439,13 +434,13 @@ def _navigate(plex, client):
|
|||
|
||||
@register('client')
|
||||
def test_video_playback(plex, user=None):
|
||||
client = plex.client(PLEX_CLIENT)
|
||||
client = safe_client(CLIENT, CLIENT_BASEURL, plex)
|
||||
_video_playback(plex, client)
|
||||
|
||||
|
||||
# @register('client')
|
||||
def test_video_playback_via_proxy(plex, user=None):
|
||||
client = plex.client(PLEX_CLIENT)
|
||||
client = safe_client(CLIENT, CLIENT_BASEURL, plex)
|
||||
client.proxyThroughServer()
|
||||
_video_playback(plex, client)
|
||||
|
||||
|
@ -477,7 +472,7 @@ def _video_playback(plex, client):
|
|||
@register('client')
|
||||
def test_client_timeline(plex, user=None):
|
||||
mtype = 'video'
|
||||
client = plex.client(PLEX_CLIENT)
|
||||
client = safe_client(CLIENT, CLIENT_BASEURL, plex)
|
||||
movie = plex.library.section(MOVIE_SECTION).get(MOVIE_TITLE)
|
||||
playing = client.isPlayingMedia()
|
||||
log(2, 'Playing Media: %s' % playing)
|
||||
|
@ -539,7 +534,7 @@ def test_myplex_devices(plex, user=None):
|
|||
@register('myplex,devices')
|
||||
def test_myplex_connect_to_device(plex, user=None):
|
||||
assert user, 'Must specify username, password & resource to run this test.'
|
||||
device = user.device(PLEX_CLIENT)
|
||||
device = user.device(CLIENT)
|
||||
client = device.connect()
|
||||
log(2, 'Connected to client: %s (%s)' % (client.title, client.product))
|
||||
assert client, 'Unable to connect to device'
|
||||
|
|
|
@ -5,6 +5,8 @@ Test Library Functions
|
|||
import sys, traceback
|
||||
import datetime, time
|
||||
from plexapi import server
|
||||
from plexapi.client import PlexClient
|
||||
from plexapi.exceptions import NotFound
|
||||
from plexapi.myplex import MyPlexUser
|
||||
|
||||
COLORS = {'blue':'\033[94m', 'green':'\033[92m', 'red':'\033[91m', 'yellow':'\033[93m', 'end':'\033[0m'}
|
||||
|
@ -39,6 +41,14 @@ def fetch_server(args):
|
|||
return server.PlexServer(), None
|
||||
|
||||
|
||||
def safe_client(name, baseurl, server):
|
||||
try:
|
||||
return server.client(name)
|
||||
except NotFound as err:
|
||||
log(2, 'Warning: %s' % err)
|
||||
return PlexClient(baseurl, server=server)
|
||||
|
||||
|
||||
def iter_tests(query):
|
||||
tags = query[5:].split(',') if query and query.startswith('tags:') else ''
|
||||
for test in registered:
|
||||
|
|
Loading…
Add table
Reference in a new issue