mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-10 06:04:15 +00:00
Dont include token in URLs unless show_secrets set in config; All functions that return a URL such as stream urls and thumbnails still include token
This commit is contained in:
parent
68f73e151e
commit
61ede66ad5
9 changed files with 40 additions and 35 deletions
|
@ -29,7 +29,7 @@ class AlertListener(threading.Thread):
|
|||
|
||||
def run(self):
|
||||
# create the websocket connection
|
||||
url = self._server.url(self.key).replace('http', 'ws')
|
||||
url = self._server.url(self.key, includeToken=True).replace('http', 'ws')
|
||||
log.info('Starting AlertListener: %s', url)
|
||||
self._ws = websocket.WebSocketApp(url, on_message=self._onMessage,
|
||||
on_error=self._onError)
|
||||
|
|
|
@ -45,18 +45,17 @@ class Audio(PlexPartialObject):
|
|||
def thumbUrl(self):
|
||||
""" Return url to for the thumbnail image. """
|
||||
key = self.firstAttr('thumb', 'parentThumb', 'granparentThumb')
|
||||
return self._server.url(key) if key else None
|
||||
return self._server.url(key, includeToken=True) if key else None
|
||||
|
||||
@property
|
||||
def artUrl(self):
|
||||
""" Return the first first art url starting on the most specific for that item."""
|
||||
""" Return the first art url starting on the most specific for that item."""
|
||||
art = self.firstAttr('art', 'grandparentArt')
|
||||
return self._server.url(art) if art else None
|
||||
return self._server.url(art, includeToken=True) if art else None
|
||||
|
||||
def url(self, part):
|
||||
""" Returns the full URL for something. Typically used for getting a specific image. """
|
||||
if part:
|
||||
return self._server.url(part)
|
||||
""" Returns the full URL for this audio item. Typically used for getting a specific track. """
|
||||
return self._server.url(part, includeToken=True) if part else None
|
||||
|
||||
|
||||
@utils.registerPlexObject
|
||||
|
|
|
@ -479,7 +479,7 @@ class Playable(object):
|
|||
# sort the keys since the randomness fucks with my tests..
|
||||
sorted_params = sorted(params.items(), key=lambda val: val[0])
|
||||
return self._server.url('/%s/:/transcode/universal/start.m3u8?%s' %
|
||||
(streamtype, urlencode(sorted_params)))
|
||||
(streamtype, urlencode(sorted_params)), includeToken=True)
|
||||
|
||||
def iterParts(self):
|
||||
""" Iterates over the parts of this media item. """
|
||||
|
@ -530,9 +530,8 @@ class Playable(object):
|
|||
download_url = self.getStreamURL(**kwargs)
|
||||
else:
|
||||
download_url = self._server.url('%s?download=1' % location.key)
|
||||
|
||||
filepath = utils.download(download_url, filename=filename,
|
||||
savepath=savepath, session=self._server._session)
|
||||
filepath = utils.download(download_url, self._server._token, filename=filename,
|
||||
savepath=savepath, session=self._server._session)
|
||||
if filepath:
|
||||
filepaths.append(filepath)
|
||||
return filepaths
|
||||
|
|
|
@ -65,6 +65,7 @@ class PlexClient(PlexObject):
|
|||
super(PlexClient, self).__init__(server, data, initpath)
|
||||
self._baseurl = baseurl.strip('/') if baseurl else None
|
||||
self._token = logfilter.add_secret(token)
|
||||
self._showSecrets = CONFIG.get('log.show_secrets', '').lower() == 'true'
|
||||
server_session = server._session if server else None
|
||||
self._session = session or server_session or requests.Session()
|
||||
self._proxyThroughServer = False
|
||||
|
@ -193,11 +194,13 @@ class PlexClient(PlexObject):
|
|||
return self._server.query(key, headers=headers)
|
||||
return self.query(key, headers=headers)
|
||||
|
||||
def url(self, key):
|
||||
""" Build a URL string with proper token argument. """
|
||||
def url(self, key, includeToken=False):
|
||||
""" Build a URL string with proper token argument. Token will be appended to the URL
|
||||
if either includeToken is True or CONFIG.log.show_secrets is 'true'.
|
||||
"""
|
||||
if not self._baseurl:
|
||||
raise BadRequest('PlexClient object missing baseurl.')
|
||||
if self._token:
|
||||
if self._token and (includeToken or self._showSecrets):
|
||||
delim = '&' if '?' in key else '?'
|
||||
return '%s%s%sX-Plex-Token=%s' % (self._baseurl, key, delim, self._token)
|
||||
return '%s%s' % (self._baseurl, key)
|
||||
|
|
|
@ -94,6 +94,7 @@ class PlexServer(PlexObject):
|
|||
def __init__(self, baseurl=None, token=None, session=None, timeout=None):
|
||||
self._baseurl = baseurl or CONFIG.get('auth.server_baseurl', 'http://localhost:32400')
|
||||
self._token = logfilter.add_secret(token or CONFIG.get('auth.server_token'))
|
||||
self._showSecrets = CONFIG.get('log.show_secrets', '').lower() == 'true'
|
||||
self._session = session or requests.Session()
|
||||
self._library = None # cached library
|
||||
self._settings = None # cached settings
|
||||
|
@ -265,7 +266,7 @@ class PlexServer(PlexObject):
|
|||
unpack (bool): Unpack the zip file.
|
||||
"""
|
||||
url = self.url('/diagnostics/databases')
|
||||
filepath = utils.download(url, None, savepath, self._session, unpack=unpack)
|
||||
filepath = utils.download(url, self._token, None, savepath, self._session, unpack=unpack)
|
||||
return filepath
|
||||
|
||||
def downloadLogs(self, savepath=None, unpack=False):
|
||||
|
@ -276,7 +277,7 @@ class PlexServer(PlexObject):
|
|||
unpack (bool): Unpack the zip file.
|
||||
"""
|
||||
url = self.url('/diagnostics/logs')
|
||||
filepath = utils.download(url, None, savepath, self._session, unpack=unpack)
|
||||
filepath = utils.download(url, self._token, None, savepath, self._session, unpack=unpack)
|
||||
return filepath
|
||||
|
||||
def check_for_update(self, force=True, download=False):
|
||||
|
@ -410,11 +411,13 @@ class PlexServer(PlexObject):
|
|||
if media:
|
||||
transcode_url = '/photo/:/transcode?height=%s&width=%s&opacity=%s&saturation=%s&url=%s' % (
|
||||
height, width, opacity, saturation, media)
|
||||
return self.url(transcode_url)
|
||||
return self.url(transcode_url, includeToken=True)
|
||||
|
||||
def url(self, key):
|
||||
""" Build a URL string with proper token argument. """
|
||||
if self._token:
|
||||
def url(self, key, includeToken=None):
|
||||
""" Build a URL string with proper token argument. Token will be appended to the URL
|
||||
if either includeToken is True or CONFIG.log.show_secrets is 'true'.
|
||||
"""
|
||||
if self._token and (includeToken or self._showSecrets):
|
||||
delim = '&' if '?' in key else '?'
|
||||
return '%s%s%sX-Plex-Token=%s' % (self._baseurl, key, delim, self._token)
|
||||
return '%s%s' % (self._baseurl, key)
|
||||
|
|
|
@ -223,13 +223,14 @@ def downloadSessionImages(server, filename=None, height=150, width=150,
|
|||
return info
|
||||
|
||||
|
||||
def download(url, filename=None, savepath=None, session=None, chunksize=4024,
|
||||
def download(url, token, filename=None, savepath=None, session=None, chunksize=4024,
|
||||
unpack=False, mocked=False, showstatus=False):
|
||||
""" Helper to download a thumb, videofile or other media item. Returns the local
|
||||
path to the downloaded file.
|
||||
|
||||
Parameters:
|
||||
url (str): URL where the content be reached.
|
||||
token (str): Plex auth token to include in headers.
|
||||
filename (str): Filename of the downloaded file, default None.
|
||||
savepath (str): Defaults to current working dir.
|
||||
chunksize (int): What chunksize read/write at the time.
|
||||
|
@ -245,7 +246,8 @@ def download(url, filename=None, savepath=None, session=None, chunksize=4024,
|
|||
from plexapi import log
|
||||
# fetch the data to be saved
|
||||
session = session or requests.Session()
|
||||
response = session.get(url, stream=True)
|
||||
headers = {'X-Plex-Token': token}
|
||||
response = session.get(url, headers=headers, stream=True)
|
||||
# make sure the savepath directory exists
|
||||
savepath = savepath or os.getcwd()
|
||||
compat.makedirs(savepath, exist_ok=True)
|
||||
|
|
|
@ -53,18 +53,17 @@ class Video(PlexPartialObject):
|
|||
the most specific thumbnail for that item.
|
||||
"""
|
||||
thumb = self.firstAttr('thumb', 'parentThumb', 'granparentThumb')
|
||||
return self._server.url(thumb) if thumb else None
|
||||
return self._server.url(thumb, includeToken=True) if thumb else None
|
||||
|
||||
@property
|
||||
def artUrl(self):
|
||||
""" Return the first first art url starting on the most specific for that item."""
|
||||
art = self.firstAttr('art', 'grandparentArt')
|
||||
return self._server.url(art) if art else None
|
||||
return self._server.url(art, includeToken=True) if art else None
|
||||
|
||||
def url(self, part):
|
||||
""" Returns the full url for something. Typically used for getting a specific image. """
|
||||
if part:
|
||||
return self._server.url(part)
|
||||
return self._server.url(part, includeToken=True) if part else None
|
||||
|
||||
def markWatched(self):
|
||||
""" Mark video as watched. """
|
||||
|
@ -193,10 +192,10 @@ class Movie(Video, Playable):
|
|||
url = self.getStreamURL(**kwargs)
|
||||
else:
|
||||
self._server.url('%s?download=1' % location.key)
|
||||
filepath = utils.download(url, filename=name, savepath=savepath, session=self._server._session)
|
||||
filepath = utils.download(url, self._server._token, filename=name,
|
||||
savepath=savepath, session=self._server._session)
|
||||
if filepath:
|
||||
filepaths.append(filepath)
|
||||
|
||||
return filepaths
|
||||
|
||||
|
||||
|
|
|
@ -58,9 +58,9 @@ def test_server_transcodeImage(tmpdir, plex, show):
|
|||
width, height = 500, 500
|
||||
imgurl = plex.transcodeImage(show.banner, height, width)
|
||||
gray = imgurl = plex.transcodeImage(show.banner, height, width, saturation=0)
|
||||
resized_img = download(imgurl, savepath=str(tmpdir), filename='resize_image')
|
||||
original_img = download(show._server.url(show.banner), savepath=str(tmpdir), filename='original_img')
|
||||
grayscale_img = download(gray, savepath=str(tmpdir), filename='grayscale_img')
|
||||
resized_img = download(imgurl, plex._token, savepath=str(tmpdir), filename='resize_image')
|
||||
original_img = download(show._server.url(show.banner), plex._token, savepath=str(tmpdir), filename='original_img')
|
||||
grayscale_img = download(gray, plex._token, savepath=str(tmpdir), filename='grayscale_img')
|
||||
with Image.open(resized_img) as image:
|
||||
assert width, height == image.size
|
||||
with Image.open(original_img) as image:
|
||||
|
|
|
@ -60,10 +60,10 @@ def test_utils_cast():
|
|||
bool_str = utils.cast(bool, 'kek')
|
||||
|
||||
|
||||
def test_utils_download(episode):
|
||||
def test_utils_download(plex, episode):
|
||||
url = episode.getStreamURL()
|
||||
locations = episode.locations[0]
|
||||
session = episode._server._session
|
||||
assert utils.download(url, filename=locations, mocked=True)
|
||||
assert utils.download(url, filename=locations, session=session, mocked=True)
|
||||
assert utils.download(episode.thumbUrl, filename=episode.title, mocked=True)
|
||||
assert utils.download(url, plex._token, filename=locations, mocked=True)
|
||||
assert utils.download(url, plex._token, filename=locations, session=session, mocked=True)
|
||||
assert utils.download(episode.thumbUrl, plex._token, filename=episode.title, mocked=True)
|
||||
|
|
Loading…
Reference in a new issue