From c08c78e074adc4a29861498156ac70360c907ad1 Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Sun, 24 Oct 2021 15:16:37 -0700 Subject: [PATCH 1/5] Add utils.cleanFilename --- plexapi/utils.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plexapi/utils.py b/plexapi/utils.py index 310200f69..92d642993 100644 --- a/plexapi/utils.py +++ b/plexapi/utils.py @@ -4,7 +4,9 @@ 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. From 8ce0c40ba7208dbde9acddc60b4ccadab1a04210 Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Sun, 24 Oct 2021 15:41:04 -0700 Subject: [PATCH 2/5] Refactor download methods --- plexapi/audio.py | 36 ++++++++++---------------- plexapi/base.py | 52 +++++++++++++++++++++++++------------- plexapi/photo.py | 66 ++++++++++-------------------------------------- plexapi/video.py | 48 +++++++++-------------------------- 4 files changed, 74 insertions(+), 128 deletions(-) diff --git a/plexapi/audio.py b/plexapi/audio.py index 20a70ffa0..ebc7644ed 100644 --- a/plexapi/audio.py +++ b/plexapi/audio.py @@ -206,22 +206,17 @@ def get(self, title=None, album=None, track=None): 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. + """ 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 - " - ". - 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 album in self.albums(): - for track in album.tracks(): - filepaths += track.download(savepath, keep_original_name, **kwargs) + for track in self.tracks(): + filepaths += track.download(savepath, keep_original_name, **kwargs) return filepaths @@ -314,17 +309,13 @@ def artist(self): 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 - " - ". - 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 +389,8 @@ def _loadData(self, data): 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`. """ diff --git a/plexapi/base.py b/plexapi/base.py index ab1bef44d..94bfe2ad5 100644 --- a/plexapi/base.py +++ b/plexapi/base.py @@ -681,34 +681,50 @@ def play(self, client): 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 - " - ". - 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: `` (<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=''): diff --git a/plexapi/photo.py b/plexapi/photo.py index 6a60db811..9dfea2431 100644 --- a/plexapi/photo.py +++ b/plexapi/photo.py @@ -107,34 +107,19 @@ def get(self, title): """ 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): + """ 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. """ 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(): + 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 +203,12 @@ def _loadData(self, data): 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 +232,6 @@ def locations(self): """ 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 +268,6 @@ def sync(self, resolution, client=None, clientId=None, limit=None, title=None): 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) diff --git a/plexapi/video.py b/plexapi/video.py index 090d9502b..c31043933 100644 --- a/plexapi/video.py +++ b/plexapi/video.py @@ -357,8 +357,8 @@ def hasPreviewThumbnails(self): 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 @@ def hubs(self): 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, @@ -583,12 +557,12 @@ def unwatched(self): 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 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. **kwargs: Additional options passed into :func:`~plexapi.base.PlexObject.getStreamURL`. """ filepaths = [] @@ -714,12 +688,12 @@ def unwatched(self): 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 +813,8 @@ def __repr__(self): ] 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 +927,7 @@ def locations(self): 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 +943,5 @@ def _loadData(self, data): self.librarySectionTitle = parent.librarySectionTitle def _prettyfilename(self): + """ Returns a filename for use in download. """ return '%s (%s)' % (self.title, self.subtype) From db05411be245f85cf26cb750f99d8a6e8e8aa884 Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Sun, 24 Oct 2021 16:03:31 -0700 Subject: [PATCH 3/5] Add option to download episodes, tracks, photos into subfolders --- plexapi/audio.py | 7 +++++-- plexapi/photo.py | 7 +++++-- plexapi/video.py | 6 ++++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/plexapi/audio.py b/plexapi/audio.py index ebc7644ed..656b9250a 100644 --- a/plexapi/audio.py +++ b/plexapi/audio.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import os from urllib.parse import quote_plus from plexapi import library, media, utils @@ -205,18 +206,20 @@ def get(self, title=None, album=None, track=None): """ Alias of :func:`~plexapi.audio.Artist.track`. """ return self.track(title, album, track) - def download(self, savepath=None, keep_original_name=False, **kwargs): + 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): 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 track in self.tracks(): - filepaths += track.download(savepath, keep_original_name, **kwargs) + _savepath = os.path.join(savepath, track.parentTitle) if subfolders else savepath + filepaths += track.download(_savepath, keep_original_name, **kwargs) return filepaths diff --git a/plexapi/photo.py b/plexapi/photo.py index 9dfea2431..c24d7fb16 100644 --- a/plexapi/photo.py +++ b/plexapi/photo.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import os from urllib.parse import quote_plus from plexapi import media, utils, video @@ -107,17 +108,19 @@ def get(self, title): """ Alias to :func:`~plexapi.photo.Photoalbum.photo`. """ return self.episode(title) - def download(self, savepath=None, keep_original_name=False): + 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 filename otherwise a friendlier filename is generated. + subfolders (bool): True to separate photos/clips in to photo album folders. """ filepaths = [] for album in self.albums(): - filepaths += album.download(savepath, keep_original_name) + _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 diff --git a/plexapi/video.py b/plexapi/video.py index c31043933..4049d6c53 100644 --- a/plexapi/video.py +++ b/plexapi/video.py @@ -556,18 +556,20 @@ def unwatched(self): """ Returns list of unwatched :class:`~plexapi.video.Episode` objects. """ return self.episodes(viewCount=0) - def download(self, savepath=None, keep_original_name=False, **kwargs): + 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 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 From e4fb5aa65f3d3241436951f228dbcbbc2c1a3e2e Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Sun, 24 Oct 2021 16:03:41 -0700 Subject: [PATCH 4/5] Update download tests --- tests/test_audio.py | 28 ++++++++++++++++------------ tests/test_photo.py | 21 +++++++++++++++++++-- tests/test_utils.py | 4 ++-- tests/test_video.py | 29 +++++++++++++++-------------- 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/tests/test_audio.py b/tests/test_audio.py index 356afa954..0c873a566 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -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_Track_download(monkeydownload, tmpdir, track): - f = track.download(savepath=str(tmpdir)) - assert f +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, album, tmpdir): - f = album.download(savepath=str(tmpdir)) - assert len(f) == 1 +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_Artist_download(monkeydownload, artist, tmpdir): - f = artist.download(savepath=str(tmpdir)) - assert len(f) == 1 +def test_audio_Track_download(monkeydownload, tmpdir, track): + filepaths = track.download(savepath=str(tmpdir)) + assert len(filepaths) == 1 diff --git a/tests/test_photo.py b/tests/test_photo.py index 1ca422db8..b0d36753a 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -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 diff --git a/tests/test_utils.py b/tests/test_utils.py index 0e62535da..24396e0b6 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -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" diff --git a/tests/test_video.py b/tests/test_video.py index d76bb8241..6426f651a 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -143,10 +143,10 @@ 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), videoResolution="500x300") + assert len(with_resolution) == 1 def test_video_Movie_subtitlestreams(movie): @@ -728,24 +728,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 From c644424c953c779613d3efa6c057ab82f145e004 Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Sun, 24 Oct 2021 19:55:17 -0700 Subject: [PATCH 5/5] Test download keep_original_filename --- tests/test_video.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_video.py b/tests/test_video.py index 6426f651a..cec32f821 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -145,8 +145,12 @@ def test_video_Movie_iterParts(movie): def test_video_Movie_download(monkeydownload, tmpdir, movie): filepaths = movie.download(savepath=str(tmpdir)) assert len(filepaths) == 1 - with_resolution = movie.download(savepath=str(tmpdir), videoResolution="500x300") + 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):