mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-10 06:04:15 +00:00
Cleanup download methods (#847)
* Add utils.cleanFilename * Refactor download methods * Add option to download episodes, tracks, photos into subfolders * Update download tests * Test download keep_original_filename
This commit is contained in:
parent
34a42185ac
commit
01131c95cf
9 changed files with 153 additions and 164 deletions
|
@ -1,4 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
from urllib.parse import quote_plus
|
||||
|
||||
from plexapi import library, media, utils
|
||||
|
@ -205,23 +206,20 @@ class Artist(Audio, AdvancedSettingsMixin, ArtMixin, PosterMixin, RatingMixin, S
|
|||
""" Alias of :func:`~plexapi.audio.Artist.track`. """
|
||||
return self.track(title, album, track)
|
||||
|
||||
def download(self, savepath=None, keep_original_name=False, **kwargs):
|
||||
""" Downloads all tracks for the artist to the specified location.
|
||||
def download(self, savepath=None, keep_original_name=False, subfolders=False, **kwargs):
|
||||
""" Download all tracks from the artist. See :func:`~plexapi.base.Playable.download` for details.
|
||||
|
||||
Parameters:
|
||||
savepath (str): Title of the track to return.
|
||||
keep_original_name (bool): Set True to keep the original filename as stored in
|
||||
the Plex server. False will create a new filename with the format
|
||||
"<Atrist> - <Album> <Track>".
|
||||
kwargs (dict): If specified, a :func:`~plexapi.audio.Track.getStreamURL` will
|
||||
be returned and the additional arguments passed in will be sent to that
|
||||
function. If kwargs is not specified, the media items will be downloaded
|
||||
and saved to disk.
|
||||
savepath (str): Defaults to current working dir.
|
||||
keep_original_name (bool): True to keep the original filename otherwise
|
||||
a friendlier filename is generated.
|
||||
subfolders (bool): True to separate tracks in to album folders.
|
||||
**kwargs: Additional options passed into :func:`~plexapi.base.PlexObject.getStreamURL`.
|
||||
"""
|
||||
filepaths = []
|
||||
for album in self.albums():
|
||||
for track in album.tracks():
|
||||
filepaths += track.download(savepath, keep_original_name, **kwargs)
|
||||
for track in self.tracks():
|
||||
_savepath = os.path.join(savepath, track.parentTitle) if subfolders else savepath
|
||||
filepaths += track.download(_savepath, keep_original_name, **kwargs)
|
||||
return filepaths
|
||||
|
||||
|
||||
|
@ -314,17 +312,13 @@ class Album(Audio, ArtMixin, PosterMixin, RatingMixin, UnmatchMatchMixin,
|
|||
return self.fetchItem(self.parentKey)
|
||||
|
||||
def download(self, savepath=None, keep_original_name=False, **kwargs):
|
||||
""" Downloads all tracks for the artist to the specified location.
|
||||
""" Download all tracks from the album. See :func:`~plexapi.base.Playable.download` for details.
|
||||
|
||||
Parameters:
|
||||
savepath (str): Title of the track to return.
|
||||
keep_original_name (bool): Set True to keep the original filename as stored in
|
||||
the Plex server. False will create a new filename with the format
|
||||
"<Atrist> - <Album> <Track>".
|
||||
kwargs (dict): If specified, a :func:`~plexapi.audio.Track.getStreamURL` will
|
||||
be returned and the additional arguments passed in will be sent to that
|
||||
function. If kwargs is not specified, the media items will be downloaded
|
||||
and saved to disk.
|
||||
savepath (str): Defaults to current working dir.
|
||||
keep_original_name (bool): True to keep the original filename otherwise
|
||||
a friendlier filename is generated.
|
||||
**kwargs: Additional options passed into :func:`~plexapi.base.PlexObject.getStreamURL`.
|
||||
"""
|
||||
filepaths = []
|
||||
for track in self.tracks():
|
||||
|
@ -398,7 +392,8 @@ class Track(Audio, Playable, ArtUrlMixin, PosterUrlMixin, RatingMixin,
|
|||
|
||||
def _prettyfilename(self):
|
||||
""" Returns a filename for use in download. """
|
||||
return '%s - %s %s' % (self.grandparentTitle, self.parentTitle, self.title)
|
||||
return '%s - %s - %s - %s' % (
|
||||
self.grandparentTitle, self.parentTitle, str(self.trackNumber).zfill(2), self.title)
|
||||
|
||||
def album(self):
|
||||
""" Return the track's :class:`~plexapi.audio.Album`. """
|
||||
|
|
|
@ -681,34 +681,50 @@ class Playable(object):
|
|||
client.playMedia(self)
|
||||
|
||||
def download(self, savepath=None, keep_original_name=False, **kwargs):
|
||||
""" Downloads this items media to the specified location. Returns a list of
|
||||
""" Downloads the media item to the specified location. Returns a list of
|
||||
filepaths that have been saved to disk.
|
||||
|
||||
Parameters:
|
||||
savepath (str): Title of the track to return.
|
||||
keep_original_name (bool): Set True to keep the original filename as stored in
|
||||
the Plex server. False will create a new filename with the format
|
||||
"<Artist> - <Album> <Track>".
|
||||
kwargs (dict): If specified, a :func:`~plexapi.audio.Track.getStreamURL` will
|
||||
be returned and the additional arguments passed in will be sent to that
|
||||
function. If kwargs is not specified, the media items will be downloaded
|
||||
and saved to disk.
|
||||
savepath (str): Defaults to current working dir.
|
||||
keep_original_name (bool): True to keep the original filename otherwise
|
||||
a friendlier filename is generated. See filenames below.
|
||||
**kwargs (dict): Additional options passed into :func:`~plexapi.audio.Track.getStreamURL`
|
||||
to download a transcoded stream, otherwise the media item will be downloaded
|
||||
as-is and saved to disk.
|
||||
|
||||
**Filenames**
|
||||
|
||||
* Movie: ``<title> (<year>)``
|
||||
* Episode: ``<show title> - s00e00 - <episode title>``
|
||||
* Track: ``<artist title> - <album title> - 00 - <track title>``
|
||||
* Photo: ``<photoalbum title> - <photo/clip title>`` or ``<photo/clip title>``
|
||||
"""
|
||||
filepaths = []
|
||||
locations = [i for i in self.iterParts() if i]
|
||||
for location in locations:
|
||||
filename = location.file
|
||||
if keep_original_name is False:
|
||||
filename = '%s.%s' % (self._prettyfilename(), location.container)
|
||||
# So this seems to be a alot slower but allows transcode.
|
||||
parts = [i for i in self.iterParts() if i]
|
||||
|
||||
for part in parts:
|
||||
if not keep_original_name:
|
||||
filename = utils.cleanFilename('%s.%s' % (self._prettyfilename(), part.container))
|
||||
else:
|
||||
filename = part.file
|
||||
|
||||
if kwargs:
|
||||
# So this seems to be a alot slower but allows transcode.
|
||||
download_url = self.getStreamURL(**kwargs)
|
||||
else:
|
||||
download_url = self._server.url('%s?download=1' % location.key)
|
||||
filepath = utils.download(download_url, self._server._token, filename=filename,
|
||||
savepath=savepath, session=self._server._session)
|
||||
download_url = self._server.url('%s?download=1' % part.key)
|
||||
|
||||
filepath = utils.download(
|
||||
download_url,
|
||||
self._server._token,
|
||||
filename=filename,
|
||||
savepath=savepath,
|
||||
session=self._server._session
|
||||
)
|
||||
|
||||
if filepath:
|
||||
filepaths.append(filepath)
|
||||
|
||||
return filepaths
|
||||
|
||||
def stop(self, reason=''):
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
from urllib.parse import quote_plus
|
||||
|
||||
from plexapi import media, utils, video
|
||||
|
@ -107,34 +108,21 @@ class Photoalbum(PlexPartialObject, ArtMixin, PosterMixin, RatingMixin):
|
|||
""" Alias to :func:`~plexapi.photo.Photoalbum.photo`. """
|
||||
return self.episode(title)
|
||||
|
||||
def iterParts(self):
|
||||
""" Iterates over the parts of the media item. """
|
||||
for album in self.albums():
|
||||
for photo in album.photos():
|
||||
for part in photo.iterParts():
|
||||
yield part
|
||||
|
||||
def download(self, savepath=None, keep_original_name=False, showstatus=False):
|
||||
""" Download photo files to specified directory.
|
||||
def download(self, savepath=None, keep_original_name=False, subfolders=False):
|
||||
""" Download all photos and clips from the photo ablum. See :func:`~plexapi.base.Playable.download` for details.
|
||||
|
||||
Parameters:
|
||||
savepath (str): Defaults to current working dir.
|
||||
keep_original_name (bool): True to keep the original file name otherwise
|
||||
a friendlier is generated.
|
||||
showstatus(bool): Display a progressbar.
|
||||
keep_original_name (bool): True to keep the original filename otherwise
|
||||
a friendlier filename is generated.
|
||||
subfolders (bool): True to separate photos/clips in to photo album folders.
|
||||
"""
|
||||
filepaths = []
|
||||
locations = [i for i in self.iterParts() if i]
|
||||
for location in locations:
|
||||
name = location.file
|
||||
if not keep_original_name:
|
||||
title = self.title.replace(' ', '.')
|
||||
name = '%s.%s' % (title, location.container)
|
||||
url = self._server.url('%s?download=1' % location.key)
|
||||
filepath = utils.download(url, self._server._token, filename=name, showstatus=showstatus,
|
||||
savepath=savepath, session=self._server._session)
|
||||
if filepath:
|
||||
filepaths.append(filepath)
|
||||
for album in self.albums():
|
||||
_savepath = os.path.join(savepath, album.title) if subfolders else savepath
|
||||
filepaths += album.download(_savepath, keep_original_name)
|
||||
for photo in self.photos() + self.clips():
|
||||
filepaths += photo.download(savepath, keep_original_name)
|
||||
return filepaths
|
||||
|
||||
def _getWebURL(self, base=None):
|
||||
|
@ -218,6 +206,12 @@ class Photo(PlexPartialObject, Playable, ArtUrlMixin, PosterUrlMixin, RatingMixi
|
|||
self.userRating = utils.cast(float, data.attrib.get('userRating'))
|
||||
self.year = utils.cast(int, data.attrib.get('year'))
|
||||
|
||||
def _prettyfilename(self):
|
||||
""" Returns a filename for use in download. """
|
||||
if self.parentTitle:
|
||||
return '%s - %s' % (self.parentTitle, self.title)
|
||||
return self.title
|
||||
|
||||
def photoalbum(self):
|
||||
""" Return the photo's :class:`~plexapi.photo.Photoalbum`. """
|
||||
return self.fetchItem(self.parentKey)
|
||||
|
@ -241,12 +235,6 @@ class Photo(PlexPartialObject, Playable, ArtUrlMixin, PosterUrlMixin, RatingMixi
|
|||
"""
|
||||
return [part.file for item in self.media for part in item.parts if part]
|
||||
|
||||
def iterParts(self):
|
||||
""" Iterates over the parts of the media item. """
|
||||
for item in self.media:
|
||||
for part in item.parts:
|
||||
yield part
|
||||
|
||||
def sync(self, resolution, client=None, clientId=None, limit=None, title=None):
|
||||
""" Add current photo as sync item for specified device.
|
||||
See :func:`~plexapi.myplex.MyPlexAccount.sync` for possible exceptions.
|
||||
|
@ -283,29 +271,6 @@ class Photo(PlexPartialObject, Playable, ArtUrlMixin, PosterUrlMixin, RatingMixi
|
|||
|
||||
return myplex.sync(sync_item, client=client, clientId=clientId)
|
||||
|
||||
def download(self, savepath=None, keep_original_name=False, showstatus=False):
|
||||
""" Download photo files to specified directory.
|
||||
|
||||
Parameters:
|
||||
savepath (str): Defaults to current working dir.
|
||||
keep_original_name (bool): True to keep the original file name otherwise
|
||||
a friendlier is generated.
|
||||
showstatus(bool): Display a progressbar.
|
||||
"""
|
||||
filepaths = []
|
||||
locations = [i for i in self.iterParts() if i]
|
||||
for location in locations:
|
||||
name = location.file
|
||||
if not keep_original_name:
|
||||
title = self.title.replace(' ', '.')
|
||||
name = '%s.%s' % (title, location.container)
|
||||
url = self._server.url('%s?download=1' % location.key)
|
||||
filepath = utils.download(url, self._server._token, filename=name, showstatus=showstatus,
|
||||
savepath=savepath, session=self._server._session)
|
||||
if filepath:
|
||||
filepaths.append(filepath)
|
||||
return filepaths
|
||||
|
||||
def _getWebURL(self, base=None):
|
||||
""" Get the Plex Web URL with the correct parameters. """
|
||||
return self._server._buildWebURL(base=base, endpoint='details', key=self.parentKey, legacy=1)
|
||||
|
|
|
@ -4,7 +4,9 @@ import functools
|
|||
import logging
|
||||
import os
|
||||
import re
|
||||
import string
|
||||
import time
|
||||
import unicodedata
|
||||
import warnings
|
||||
import zipfile
|
||||
from datetime import datetime
|
||||
|
@ -251,6 +253,13 @@ def toList(value, itemcast=None, delim=','):
|
|||
return [itemcast(item) for item in value.split(delim) if item != '']
|
||||
|
||||
|
||||
def cleanFilename(filename, replace='_'):
|
||||
whitelist = "-_.()[] {}{}".format(string.ascii_letters, string.digits)
|
||||
cleaned_filename = unicodedata.normalize('NFKD', filename).encode('ASCII', 'ignore').decode()
|
||||
cleaned_filename = ''.join(c if c in whitelist else replace for c in cleaned_filename)
|
||||
return cleaned_filename
|
||||
|
||||
|
||||
def downloadSessionImages(server, filename=None, height=150, width=150,
|
||||
opacity=100, saturation=100): # pragma: no cover
|
||||
""" Helper to download a bif image or thumb.url from plex.server.sessions.
|
||||
|
|
|
@ -357,8 +357,8 @@ class Movie(Video, Playable, AdvancedSettingsMixin, ArtMixin, PosterMixin, Ratin
|
|||
return any(part.hasPreviewThumbnails for media in self.media for part in media.parts)
|
||||
|
||||
def _prettyfilename(self):
|
||||
# This is just for compat.
|
||||
return self.title
|
||||
""" Returns a filename for use in download. """
|
||||
return '%s (%s)' % (self.title, self.year)
|
||||
|
||||
def reviews(self):
|
||||
""" Returns a list of :class:`~plexapi.media.Review` objects. """
|
||||
|
@ -375,32 +375,6 @@ class Movie(Video, Playable, AdvancedSettingsMixin, ArtMixin, PosterMixin, Ratin
|
|||
data = self._server.query(self._details_key)
|
||||
return self.findItems(data, library.Hub, rtag='Related')
|
||||
|
||||
def download(self, savepath=None, keep_original_name=False, **kwargs):
|
||||
""" Download video files to specified directory.
|
||||
|
||||
Parameters:
|
||||
savepath (str): Defaults to current working dir.
|
||||
keep_original_name (bool): True to keep the original file name otherwise
|
||||
a friendlier is generated.
|
||||
**kwargs: Additional options passed into :func:`~plexapi.base.PlexObject.getStreamURL`.
|
||||
"""
|
||||
filepaths = []
|
||||
locations = [i for i in self.iterParts() if i]
|
||||
for location in locations:
|
||||
name = location.file
|
||||
if not keep_original_name:
|
||||
title = self.title.replace(' ', '.')
|
||||
name = '%s.%s' % (title, location.container)
|
||||
if kwargs is not None:
|
||||
url = self.getStreamURL(**kwargs)
|
||||
else:
|
||||
self._server.url('%s?download=1' % location.key)
|
||||
filepath = utils.download(url, self._server._token, filename=name,
|
||||
savepath=savepath, session=self._server._session)
|
||||
if filepath:
|
||||
filepaths.append(filepath)
|
||||
return filepaths
|
||||
|
||||
|
||||
@utils.registerPlexObject
|
||||
class Show(Video, AdvancedSettingsMixin, ArtMixin, BannerMixin, PosterMixin, RatingMixin, SplitMergeMixin, UnmatchMatchMixin,
|
||||
|
@ -582,18 +556,20 @@ class Show(Video, AdvancedSettingsMixin, ArtMixin, BannerMixin, PosterMixin, Rat
|
|||
""" Returns list of unwatched :class:`~plexapi.video.Episode` objects. """
|
||||
return self.episodes(viewCount=0)
|
||||
|
||||
def download(self, savepath=None, keep_original_name=False, **kwargs):
|
||||
""" Download video files to specified directory.
|
||||
def download(self, savepath=None, keep_original_name=False, subfolders=False, **kwargs):
|
||||
""" Download all episodes from the show. See :func:`~plexapi.base.Playable.download` for details.
|
||||
|
||||
Parameters:
|
||||
savepath (str): Defaults to current working dir.
|
||||
keep_original_name (bool): True to keep the original file name otherwise
|
||||
a friendlier is generated.
|
||||
keep_original_name (bool): True to keep the original filename otherwise
|
||||
a friendlier filename is generated.
|
||||
subfolders (bool): True to separate episodes in to season folders.
|
||||
**kwargs: Additional options passed into :func:`~plexapi.base.PlexObject.getStreamURL`.
|
||||
"""
|
||||
filepaths = []
|
||||
for episode in self.episodes():
|
||||
filepaths += episode.download(savepath, keep_original_name, **kwargs)
|
||||
_savepath = os.path.join(savepath, 'Season %s' % str(episode.seasonNumber).zfill(2)) if subfolders else savepath
|
||||
filepaths += episode.download(_savepath, keep_original_name, **kwargs)
|
||||
return filepaths
|
||||
|
||||
|
||||
|
@ -714,12 +690,12 @@ class Season(Video, ArtMixin, PosterMixin, RatingMixin, CollectionMixin):
|
|||
return self.episodes(viewCount=0)
|
||||
|
||||
def download(self, savepath=None, keep_original_name=False, **kwargs):
|
||||
""" Download video files to specified directory.
|
||||
""" Download all episodes from the season. See :func:`~plexapi.base.Playable.download` for details.
|
||||
|
||||
Parameters:
|
||||
savepath (str): Defaults to current working dir.
|
||||
keep_original_name (bool): True to keep the original file name otherwise
|
||||
a friendlier is generated.
|
||||
keep_original_name (bool): True to keep the original filename otherwise
|
||||
a friendlier filename is generated.
|
||||
**kwargs: Additional options passed into :func:`~plexapi.base.PlexObject.getStreamURL`.
|
||||
"""
|
||||
filepaths = []
|
||||
|
@ -839,8 +815,8 @@ class Episode(Video, Playable, ArtMixin, PosterMixin, RatingMixin,
|
|||
] if p])
|
||||
|
||||
def _prettyfilename(self):
|
||||
""" Returns a human friendly filename. """
|
||||
return '%s.%s' % (self.grandparentTitle.replace(' ', '.'), self.seasonEpisode)
|
||||
""" Returns a filename for use in download. """
|
||||
return '%s - %s - %s' % (self.grandparentTitle, self.seasonEpisode, self.title)
|
||||
|
||||
@property
|
||||
def actors(self):
|
||||
|
@ -953,6 +929,7 @@ class Clip(Video, Playable, ArtUrlMixin, PosterUrlMixin):
|
|||
return [part.file for part in self.iterParts() if part]
|
||||
|
||||
def _prettyfilename(self):
|
||||
""" Returns a filename for use in download. """
|
||||
return self.title
|
||||
|
||||
|
||||
|
@ -968,4 +945,5 @@ class Extra(Clip):
|
|||
self.librarySectionTitle = parent.librarySectionTitle
|
||||
|
||||
def _prettyfilename(self):
|
||||
""" Returns a filename for use in download. """
|
||||
return '%s (%s)' % (self.title, self.subtype)
|
||||
|
|
|
@ -117,7 +117,7 @@ def test_audio_Artist_media_tags(artist):
|
|||
test_media.tag_style(artist)
|
||||
|
||||
|
||||
def test_video_Artist_PlexWebURL(plex, artist):
|
||||
def test_audio_Artist_PlexWebURL(plex, artist):
|
||||
url = artist.getWebURL()
|
||||
assert url.startswith('https://app.plex.tv/desktop')
|
||||
assert plex.machineIdentifier in url
|
||||
|
@ -224,7 +224,7 @@ def test_audio_Album_media_tags(album):
|
|||
test_media.tag_style(album)
|
||||
|
||||
|
||||
def test_video_Album_PlexWebURL(plex, album):
|
||||
def test_audio_Album_PlexWebURL(plex, album):
|
||||
url = album.getWebURL()
|
||||
assert url.startswith('https://app.plex.tv/desktop')
|
||||
assert plex.machineIdentifier in url
|
||||
|
@ -375,7 +375,7 @@ def test_audio_Track_media_tags(track):
|
|||
test_media.tag_mood(track)
|
||||
|
||||
|
||||
def test_video_Track_PlexWebURL(plex, track):
|
||||
def test_audio_Track_PlexWebURL(plex, track):
|
||||
url = track.getWebURL()
|
||||
assert url.startswith('https://app.plex.tv/desktop')
|
||||
assert plex.machineIdentifier in url
|
||||
|
@ -390,16 +390,20 @@ def test_audio_Audio_section(artist, album, track):
|
|||
assert track.section().key == album.section().key == artist.section().key
|
||||
|
||||
|
||||
def test_audio_Artist_download(monkeydownload, tmpdir, artist):
|
||||
total = len(artist.tracks())
|
||||
filepaths = artist.download(savepath=str(tmpdir))
|
||||
assert len(filepaths) == total
|
||||
subfolders = artist.download(savepath=str(tmpdir), subfolders=True)
|
||||
assert len(subfolders) == total
|
||||
|
||||
|
||||
def test_audio_Album_download(monkeydownload, tmpdir, album):
|
||||
total = len(album.tracks())
|
||||
filepaths = album.download(savepath=str(tmpdir))
|
||||
assert len(filepaths) == total
|
||||
|
||||
|
||||
def test_audio_Track_download(monkeydownload, tmpdir, track):
|
||||
f = track.download(savepath=str(tmpdir))
|
||||
assert f
|
||||
|
||||
|
||||
def test_audio_album_download(monkeydownload, album, tmpdir):
|
||||
f = album.download(savepath=str(tmpdir))
|
||||
assert len(f) == 1
|
||||
|
||||
|
||||
def test_audio_Artist_download(monkeydownload, artist, tmpdir):
|
||||
f = artist.download(savepath=str(tmpdir))
|
||||
assert len(f) == 1
|
||||
filepaths = track.download(savepath=str(tmpdir))
|
||||
assert len(filepaths) == 1
|
||||
|
|
|
@ -26,7 +26,7 @@ def test_photo_Photoalbum_mixins_rating(photoalbum):
|
|||
test_mixins.edit_rating(photoalbum)
|
||||
|
||||
|
||||
def test_video_Photoalbum_PlexWebURL(plex, photoalbum):
|
||||
def test_photo_Photoalbum_PlexWebURL(plex, photoalbum):
|
||||
url = photoalbum.getWebURL()
|
||||
assert url.startswith('https://app.plex.tv/desktop')
|
||||
assert plex.machineIdentifier in url
|
||||
|
@ -48,10 +48,27 @@ def test_photo_Photo_media_tags(photo):
|
|||
test_media.tag_tag(photo)
|
||||
|
||||
|
||||
def test_video_Photo_PlexWebURL(plex, photo):
|
||||
def test_photo_Photo_PlexWebURL(plex, photo):
|
||||
url = photo.getWebURL()
|
||||
assert url.startswith('https://app.plex.tv/desktop')
|
||||
assert plex.machineIdentifier in url
|
||||
assert 'details' in url
|
||||
assert quote_plus(photo.parentKey) in url
|
||||
assert 'legacy=1' in url
|
||||
|
||||
|
||||
def test_photo_Photoalbum_download(monkeydownload, tmpdir, photoalbum):
|
||||
total = 0
|
||||
for album in photoalbum.albums():
|
||||
total += len(album.photos()) + len(album.clips())
|
||||
total += len(photoalbum.photos())
|
||||
total += len(photoalbum.clips())
|
||||
filepaths = photoalbum.download(savepath=str(tmpdir))
|
||||
assert len(filepaths) == total
|
||||
subfolders = photoalbum.download(savepath=str(tmpdir), subfolders=True)
|
||||
assert len(subfolders) == total
|
||||
|
||||
|
||||
def test_photo_Photo_download(monkeydownload, tmpdir, photo):
|
||||
filepaths = photo.download(savepath=str(tmpdir))
|
||||
assert len(filepaths) == 1
|
||||
|
|
|
@ -78,7 +78,8 @@ def test_utils_download(plex, episode):
|
|||
url = episode.getStreamURL()
|
||||
locations = episode.locations[0]
|
||||
session = episode._server._session
|
||||
assert utils.download(url, plex._token, filename=locations, mocked=True)
|
||||
assert utils.download(
|
||||
url, plex._token, filename=locations, mocked=True)
|
||||
assert utils.download(
|
||||
url, plex._token, filename=locations, session=session, mocked=True
|
||||
)
|
||||
|
@ -87,7 +88,6 @@ def test_utils_download(plex, episode):
|
|||
)
|
||||
|
||||
|
||||
|
||||
def test_millisecondToHumanstr():
|
||||
res = utils.millisecondToHumanstr(1000)
|
||||
assert res == "00:00:01.0000"
|
||||
|
|
|
@ -143,10 +143,14 @@ def test_video_Movie_iterParts(movie):
|
|||
|
||||
|
||||
def test_video_Movie_download(monkeydownload, tmpdir, movie):
|
||||
filepaths1 = movie.download(savepath=str(tmpdir))
|
||||
assert len(filepaths1) >= 1
|
||||
filepaths2 = movie.download(savepath=str(tmpdir), videoResolution="500x300")
|
||||
assert len(filepaths2) >= 1
|
||||
filepaths = movie.download(savepath=str(tmpdir))
|
||||
assert len(filepaths) == 1
|
||||
with_resolution = movie.download(
|
||||
savepath=str(tmpdir), keep_original_filename=True, videoResolution="500x300"
|
||||
)
|
||||
assert len(with_resolution) == 1
|
||||
filename = os.path.basename(movie.media[0].parts[0].file)
|
||||
assert filename in with_resolution[0]
|
||||
|
||||
|
||||
def test_video_Movie_subtitlestreams(movie):
|
||||
|
@ -728,24 +732,25 @@ def test_video_Show_episodes(tvshows):
|
|||
|
||||
|
||||
def test_video_Show_download(monkeydownload, tmpdir, show):
|
||||
episodes = show.episodes()
|
||||
total = len(show.episodes())
|
||||
filepaths = show.download(savepath=str(tmpdir))
|
||||
assert len(filepaths) == len(episodes)
|
||||
assert len(filepaths) == total
|
||||
subfolders = show.download(savepath=str(tmpdir), subfolders=True)
|
||||
assert len(subfolders) == total
|
||||
|
||||
|
||||
def test_video_Season_download(monkeydownload, tmpdir, show):
|
||||
season = show.season("Season 1")
|
||||
season = show.season(1)
|
||||
total = len(season.episodes())
|
||||
filepaths = season.download(savepath=str(tmpdir))
|
||||
assert len(filepaths) >= 4
|
||||
assert len(filepaths) == total
|
||||
|
||||
|
||||
def test_video_Episode_download(monkeydownload, tmpdir, episode):
|
||||
f = episode.download(savepath=str(tmpdir))
|
||||
assert len(f) == 1
|
||||
with_sceen_size = episode.download(
|
||||
savepath=str(tmpdir), **{"videoResolution": "500x300"}
|
||||
)
|
||||
assert len(with_sceen_size) == 1
|
||||
filepaths = episode.download(savepath=str(tmpdir))
|
||||
assert len(filepaths) == 1
|
||||
with_resolution = episode.download(savepath=str(tmpdir), videoResolution="500x300")
|
||||
assert len(with_resolution) == 1
|
||||
|
||||
|
||||
# Analyze seems to fail intermittently
|
||||
|
|
Loading…
Reference in a new issue