fix playlist last thumbnail move to copy

This commit is contained in:
Jesse Bannon 2022-11-29 23:31:12 -08:00
parent 8dd57beebc
commit 1e3961a9c6
6 changed files with 78 additions and 21 deletions

View file

@ -579,9 +579,9 @@ class Downloader(DownloadArchiver, Generic[DownloaderOptionsT], ABC):
"Beginning downloads for %s", self.overrides.apply_formatter(collection_url.url) "Beginning downloads for %s", self.overrides.apply_formatter(collection_url.url)
) )
for entry in self._download(parents=parents, orphans=orphan_entries): for entry in self._download(parents=parents, orphans=orphan_entries):
yield entry
# Update thumbnails in case of last_entry # Update thumbnails in case of last_entry
self._download_url_thumbnails(collection_url=collection_url, entry=entry) self._download_url_thumbnails(collection_url=collection_url, entry=entry)
yield entry
@classmethod @classmethod
def _download_thumbnail( def _download_thumbnail(
@ -630,6 +630,7 @@ class Downloader(DownloadArchiver, Generic[DownloaderOptionsT], ABC):
self.save_file( self.save_file(
file_name=entry.get_download_thumbnail_name(), file_name=entry.get_download_thumbnail_name(),
output_file_name=thumbnail_name, output_file_name=thumbnail_name,
copy_file=True,
) )
self._url_state.thumbnails_downloaded.add(thumbnail_name) self._url_state.thumbnails_downloaded.add(thumbnail_name)
continue continue

View file

@ -10,6 +10,7 @@ from typing import Optional
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.utils.file_handler import FileHandler
from ytdl_sub.utils.file_handler import FileMetadata from ytdl_sub.utils.file_handler import FileMetadata
from ytdl_sub.utils.xml import XmlElement from ytdl_sub.utils.xml import XmlElement
from ytdl_sub.utils.xml import to_max_3_byte_utf8_dict from ytdl_sub.utils.xml import to_max_3_byte_utf8_dict
@ -171,6 +172,8 @@ class SharedNfoTagsPlugin(Plugin[SharedNfoTagsOptions], ABC):
else: else:
self.save_file(file_name=nfo_file_name, file_metadata=nfo_metadata) self.save_file(file_name=nfo_file_name, file_metadata=nfo_metadata)
FileHandler.delete(nfo_file_path)
class NfoTagsOptions(SharedNfoTagsOptions): class NfoTagsOptions(SharedNfoTagsOptions):
""" """

View file

@ -11,6 +11,7 @@ from ytdl_sub.subscriptions.base_subscription import BaseSubscription
from ytdl_sub.subscriptions.subscription_ytdl_options import SubscriptionYTDLOptions from ytdl_sub.subscriptions.subscription_ytdl_options import SubscriptionYTDLOptions
from ytdl_sub.utils.datetime import to_date_range from ytdl_sub.utils.datetime import to_date_range
from ytdl_sub.utils.exceptions import ValidationException from ytdl_sub.utils.exceptions import ValidationException
from ytdl_sub.utils.file_handler import FileHandler
from ytdl_sub.utils.file_handler import FileHandlerTransactionLog from ytdl_sub.utils.file_handler import FileHandlerTransactionLog
from ytdl_sub.utils.file_handler import FileMetadata from ytdl_sub.utils.file_handler import FileMetadata
from ytdl_sub.utils.thumbnail import convert_download_thumbnail from ytdl_sub.utils.thumbnail import convert_download_thumbnail
@ -94,6 +95,10 @@ class SubscriptionDownload(BaseSubscription, ABC):
entry=entry, entry=entry,
) )
def _delete_working_directory(self, is_error: bool) -> None:
_ = is_error
shutil.rmtree(self.working_directory)
@contextlib.contextmanager @contextlib.contextmanager
def _prepare_working_directory(self): def _prepare_working_directory(self):
""" """
@ -104,8 +109,11 @@ class SubscriptionDownload(BaseSubscription, ABC):
try: try:
yield yield
finally: except Exception as exc:
shutil.rmtree(self.working_directory) self._delete_working_directory(is_error=True)
raise exc
else:
self._delete_working_directory(is_error=False)
@contextlib.contextmanager @contextlib.contextmanager
def _maintain_archive_file(self): def _maintain_archive_file(self):
@ -268,6 +276,10 @@ class SubscriptionDownload(BaseSubscription, ABC):
plugins=plugins, dry_run=dry_run, entry=entry, entry_metadata=entry_metadata plugins=plugins, dry_run=dry_run, entry=entry, entry_metadata=entry_metadata
) )
FileHandler.delete(entry.get_download_file_path())
FileHandler.delete(entry.get_download_thumbnail_path())
FileHandler.delete(entry.get_download_info_json_path())
for plugin in plugins: for plugin in plugins:
plugin.post_process_subscription() plugin.post_process_subscription()

View file

@ -3,7 +3,6 @@ import json
import logging import logging
import shutil import shutil
import tempfile import tempfile
from pathlib import Path
from typing import Any from typing import Any
from typing import Callable from typing import Callable
from typing import Dict from typing import Dict
@ -11,9 +10,13 @@ from typing import List
from unittest.mock import patch from unittest.mock import patch
import pytest import pytest
from expected_download import _get_files_in_directory
from ytdl_sub.subscriptions.subscription_download import SubscriptionDownload
from ytdl_sub.utils.logger import Logger from ytdl_sub.utils.logger import Logger
logger = Logger.get("test")
@pytest.fixture() @pytest.fixture()
def output_directory(): def output_directory():
@ -23,8 +26,27 @@ def output_directory():
@pytest.fixture @pytest.fixture
def working_directory() -> str: def working_directory() -> str:
"""
Any time the working directory is used, ensure no files remain on cleaning it up
"""
with tempfile.TemporaryDirectory() as temp_dir: with tempfile.TemporaryDirectory() as temp_dir:
yield temp_dir
def _assert_working_directory_empty(self, is_error: bool):
files = [str(file_path) for file_path in _get_files_in_directory(temp_dir)]
num_files = len(files)
shutil.rmtree(temp_dir)
if not is_error:
if num_files > 0:
logger.error("left-over files in working dir:\n%s", "\n".join(files))
assert num_files == 0
with patch.object(
SubscriptionDownload,
"_delete_working_directory",
new=_assert_working_directory_empty,
):
yield temp_dir
@contextlib.contextmanager @contextlib.contextmanager

View file

@ -1,3 +1,4 @@
import json
import sys import sys
import tempfile import tempfile
from typing import List from typing import List
@ -10,6 +11,7 @@ from ytdl_sub.cli.main import main
from ytdl_sub.config.config_file import ConfigFile from ytdl_sub.config.config_file import ConfigFile
from ytdl_sub.subscriptions.subscription import Subscription from ytdl_sub.subscriptions.subscription import Subscription
from ytdl_sub.utils.file_handler import FileHandlerTransactionLog from ytdl_sub.utils.file_handler import FileHandlerTransactionLog
from ytdl_sub.utils.yaml import load_yaml
@pytest.fixture() @pytest.fixture()
@ -17,29 +19,46 @@ def music_video_config_path():
return "examples/music_videos_config.yaml" return "examples/music_videos_config.yaml"
@pytest.fixture() def _load_config(config_path: str, working_directory: str) -> ConfigFile:
def music_video_config(music_video_config_path): config_dict = load_yaml(file_path=config_path)
return ConfigFile.from_file_path(config_path=music_video_config_path) config_dict["configuration"]["working_directory"] = working_directory
return ConfigFile.from_dict(config_dict)
@pytest.fixture() @pytest.fixture()
def channel_as_tv_show_config(): def music_video_config(music_video_config_path, working_directory) -> ConfigFile:
return ConfigFile.from_file_path(config_path="examples/tv_show_config.yaml") return _load_config(music_video_config_path, working_directory)
@pytest.fixture()
def music_video_config_for_cli(music_video_config) -> str:
with tempfile.NamedTemporaryFile(suffix=".yaml") as tmp_file:
tmp_file.write(json.dumps(music_video_config._value).encode("utf-8"))
tmp_file.flush()
yield tmp_file.name
@pytest.fixture()
def channel_as_tv_show_config(working_directory) -> ConfigFile:
return _load_config(
config_path="examples/tv_show_config.yaml", working_directory=working_directory
)
@pytest.fixture @pytest.fixture
def soundcloud_discography_config(): def soundcloud_discography_config(working_directory) -> ConfigFile:
return ConfigFile.from_file_path(config_path="examples/soundcloud_discography_config.yaml") return _load_config(
config_path="examples/soundcloud_discography_config.yaml",
working_directory=working_directory,
)
@pytest.fixture() @pytest.fixture()
def youtube_audio_config_path(): def youtube_audio_config(working_directory) -> ConfigFile:
return "examples/music_audio_from_videos.yaml" return _load_config(
config_path="examples/music_audio_from_videos.yaml", working_directory=working_directory
)
@pytest.fixture()
def youtube_audio_config(youtube_audio_config_path):
return ConfigFile.from_file_path(config_path=youtube_audio_config_path)
@pytest.fixture @pytest.fixture

View file

@ -97,7 +97,7 @@ class TestPlaylist:
def test_playlist_download_from_cli_sub( def test_playlist_download_from_cli_sub(
self, self,
preset_dict_to_subscription_yaml_generator, preset_dict_to_subscription_yaml_generator,
music_video_config_path, music_video_config_for_cli,
playlist_preset_dict, playlist_preset_dict,
output_directory, output_directory,
dry_run, dry_run,
@ -106,7 +106,7 @@ class TestPlaylist:
subscription_name="music_video_playlist_test", preset_dict=playlist_preset_dict subscription_name="music_video_playlist_test", preset_dict=playlist_preset_dict
) as subscription_path: ) as subscription_path:
args = "--dry-run " if dry_run else "" args = "--dry-run " if dry_run else ""
args += f"--config {music_video_config_path} " args += f"--config {music_video_config_for_cli} "
args += f"sub {subscription_path}" args += f"sub {subscription_path}"
subscription_transaction_log = mock_run_from_cli(args=args) subscription_transaction_log = mock_run_from_cli(args=args)