Fix error when maintain_download_archive=False, improve error message (#39)

This commit is contained in:
Jesse Bannon 2022-05-20 14:41:05 -07:00 committed by GitHub
parent 0e8ea1f9b6
commit de5dade937
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 94 additions and 25 deletions

View file

@ -26,17 +26,37 @@ presets:
year: "{album_year}"
genre: "{genre}"
music_videos:
yt_music_video:
# A single YouTube video is our source/download strategy. However, this
# can be overwritten to download music videos from a "playlist", as we
# will see in a preset below
youtube:
download_strategy: "video"
# For advanced YTDL users only.
# It is wise to leave ignoreerrors=True to avoid errors for things
# like age-restricted videos in case you have not set your cookie.
ytdl_options:
ignoreerrors: True
# For each video downloaded, set the file and thumbnail name here.
# We set both with {music_video_name}, which is a variable we define in
# the overrides section further below to represent consistent naming format.
output_options:
file_name: "{sanitized_artist} - {sanitized_title}.{ext}"
thumbnail_name: "{sanitized_artist} - {sanitized_title}.jpg"
output_directory: "{music_video_directory}/{sanitized_artist}"
file_name: "{music_video_name}.{ext}"
thumbnail_name: "{music_video_name}.jpg"
# Always convert the video thumbnail to jpg
# TODO: always convert all thumbnails to jpg in code
convert_thumbnail:
to: "jpg"
# For each video downloaded, add a music video NFO file for it. Populate it
# with tags that Kodi will read and use to display it in the music or music
# videos section.
nfo_tags:
nfo_name: "{sanitized_artist} - {sanitized_title}.nfo"
nfo_name: "{music_video_name}.nfo"
nfo_root: "musicvideo"
tags:
artist: "{artist}"
@ -44,6 +64,33 @@ presets:
album: "Music Videos"
year: "{upload_year}"
# Overrides is a section where we can define our own variables, and use them in
# any other section. We define our music video directory and episode file name
# here, which gets reused above for the video, thumbnail, and NFO file.
overrides:
music_video_directory: "path/to/Music Videos"
music_video_name: "{sanitized_artist} - {sanitized_title}"
# It is not always ideal to download all of an artist's music videos.
# Maybe you only like one song of theirs. We can reuse our preset above
# to download a single video instead.
yt_music_video_playlist:
preset: "yt_music_video"
youtube:
download_strategy: "playlist"
# Setting maintain_download_archive=True is generally a good thing to enable
# with playlists and channels because it will store previously downloaded
# video ids to tell YTDL not to re-download them on a successive invocation.
output_options:
maintain_download_archive: True
# Setting break_on_existing=True is also a good thing anytime you are using
# a download archive, because it will tell the downloader to stop trying
# to download videos that have already been downloaded.
ytdl_options:
break_on_existing: True
yt_channel:
youtube:
download_strategy: "channel"

View file

@ -58,9 +58,9 @@ def _download_subscription_from_cli(config: ConfigFile, extra_args: List[str]) -
subscription.download()
def main():
def _main():
"""
Entrypoint for ytdl-subscribe
Entrypoint for ytdl-sub, without the error handling
"""
# If no args are provided, print help and exit
if len(sys.argv) < 2:
@ -80,18 +80,26 @@ def main():
logger.info("Download complete!")
if __name__ == "__main__":
def main():
"""
Entrypoint for ytdl-sub
"""
try:
main()
_main()
except ValidationException as validation_exception:
logger.error(validation_exception)
sys.exit(1)
except Exception as exc: # pylint: disable=broad-except
logger.exception(
"A fatal error occurred. Please copy and paste the stacktrace above and make a Github "
"issue at https://github.com/jmbannon/ytdl-subscribe/issues with your config and "
"command/subscription yaml file to reproduce. Thanks for trying ytdl-subscribe!"
except Exception: # pylint: disable=broad-except
logger.exception("An uncaught error occurred:")
logger.error(
"Please copy and paste the stacktrace above and make a Github "
"issue at https://github.com/jmbannon/ytdl-sub/issues with your config and "
"command/subscription yaml file to reproduce. Thanks for trying ytdl-sub!"
)
sys.exit(1)
sys.exit(0)
if __name__ == "__main__":
main()

View file

@ -1,5 +1,6 @@
from abc import ABC
from typing import Generic
from typing import Optional
from typing import Type
from typing import TypeVar
from typing import final
@ -33,7 +34,7 @@ class Plugin(Generic[PluginOptionsT], ABC):
plugin_options: PluginOptionsT,
output_directory: str,
overrides: Overrides,
enhanced_download_archive: EnhancedDownloadArchive,
enhanced_download_archive: Optional[EnhancedDownloadArchive],
):
self.plugin_options = plugin_options
self.output_directory = output_directory
@ -46,6 +47,7 @@ class Plugin(Generic[PluginOptionsT], ABC):
def archive_entry_file_name(self, entry: Entry, relative_file_path: str) -> None:
"""
Adds an entry and a file name that belongs to it into the archive mapping.
If maintain_download_archive is False for the subscription, this method will do nothing.
Parameters
----------
@ -54,9 +56,10 @@ class Plugin(Generic[PluginOptionsT], ABC):
relative_file_path:
The name of the file path relative to the output directory
"""
self.__enhanced_download_archive.mapping.add_entry(
entry=entry, entry_file_path=relative_file_path
)
if self.__enhanced_download_archive:
self.__enhanced_download_archive.mapping.add_entry(
entry=entry, entry_file_path=relative_file_path
)
def post_process_entry(self, entry: Entry):
"""

View file

@ -131,12 +131,17 @@ class Subscription:
"""
return self.overrides.apply_formatter(formatter=self.output_options.output_directory)
def _copy_file_to_output_directory(self, source_file_path: str, output_file_name: str):
def _copy_file_to_output_directory(
self, entry: Entry, source_file_path: str, output_file_name: str
):
"""
Helper function to move a file from the working directory to the output directory.
Will add it to the download archive mapping if the archive is being maintained.
Parameters
----------
entry:
Entry that the file belongs to
source_file_path:
Path to the source file
output_file_name:
@ -146,6 +151,9 @@ class Subscription:
os.makedirs(os.path.dirname(destination_file_path), exist_ok=True)
copyfile(source_file_path, destination_file_path)
if self.output_options.maintain_download_archive:
self._enhanced_download_archive.mapping.add_entry(entry, output_file_name)
def _copy_entry_files_to_output_directory(self, entry: Entry):
"""
Helper function to move the media file and optionally thumbnail file to the output directory
@ -160,23 +168,22 @@ class Subscription:
output_file_name = self.overrides.apply_formatter(
formatter=self.output_options.file_name, entry=entry
)
self._enhanced_download_archive.mapping.add_entry(entry, output_file_name)
self._copy_file_to_output_directory(
source_file_path=entry.get_download_file_path(), output_file_name=output_file_name
entry=entry,
source_file_path=entry.get_download_file_path(),
output_file_name=output_file_name,
)
if self.output_options.thumbnail_name:
output_thumbnail_name = self.overrides.apply_formatter(
formatter=self.output_options.thumbnail_name, entry=entry
)
self._enhanced_download_archive.mapping.add_entry(entry, output_thumbnail_name)
self._copy_file_to_output_directory(
entry=entry,
source_file_path=entry.get_download_thumbnail_path(),
output_file_name=output_thumbnail_name,
)
self._enhanced_download_archive.mapping.add_entry(entry, output_file_name)
@contextlib.contextmanager
def _prepare_working_directory(self):
"""
@ -221,7 +228,9 @@ class Subscription:
plugin_options=plugin_options,
output_directory=self.output_directory,
overrides=self.overrides,
enhanced_download_archive=self._enhanced_download_archive,
enhanced_download_archive=self._enhanced_download_archive
if self.output_options.maintain_download_archive
else None,
)
plugins.append(plugin)
@ -238,7 +247,9 @@ class Subscription:
working_directory=self.working_directory,
download_options=self.downloader_options,
ytdl_options=self.ytdl_options.dict,
download_archive_file_name=self._enhanced_download_archive.archive_file_name,
download_archive_file_name=self._enhanced_download_archive.archive_file_name
if self.output_options.maintain_download_archive
else None,
)
entries = downloader.download()