diff --git a/src/ytdl_sub/downloaders/downloader.py b/src/ytdl_sub/downloaders/downloader.py index fef21185..5d55c66f 100644 --- a/src/ytdl_sub/downloaders/downloader.py +++ b/src/ytdl_sub/downloaders/downloader.py @@ -439,7 +439,7 @@ class Downloader(DownloadArchiver, Generic[DownloaderOptionsT], ABC): if path.endswith(".info.json") ] for info_json_file in info_json_files: - os.remove(info_json_file) + FileHandler.delete(info_json_file) def _extract_entry_info_with_retry(self, entry: Entry) -> Entry: download_entry_dict = self.extract_info_with_retry( diff --git a/src/ytdl_sub/utils/ffmpeg.py b/src/ytdl_sub/utils/ffmpeg.py index bbb4a8a4..ef40a3e6 100644 --- a/src/ytdl_sub/utils/ffmpeg.py +++ b/src/ytdl_sub/utils/ffmpeg.py @@ -140,24 +140,26 @@ def set_ffmpeg_metadata_chapters( metadata_file.write("\n".join(lines)) metadata_file.flush() - FFMPEG.run( - [ - "-i", - file_path, - "-i", - metadata_file.name, - "-map", - "0", - "-map_chapters", - "1", - "-bitexact", # for reproducibility - "-codec", - "copy", - tmp_file_path, - ] - ) - FileHandler.move(tmp_file_path, file_path) - os.remove(metadata_file.name) + try: + FFMPEG.run( + [ + "-i", + file_path, + "-i", + metadata_file.name, + "-map", + "0", + "-map_chapters", + "1", + "-bitexact", # for reproducibility + "-codec", + "copy", + tmp_file_path, + ] + ) + FileHandler.move(tmp_file_path, file_path) + finally: + FileHandler.delete(metadata_file.name) def add_ffmpeg_metadata_key_values(file_path: str, key_values: Dict[str, str]) -> None: diff --git a/src/ytdl_sub/utils/thumbnail.py b/src/ytdl_sub/utils/thumbnail.py index c1408ac7..db5597cf 100644 --- a/src/ytdl_sub/utils/thumbnail.py +++ b/src/ytdl_sub/utils/thumbnail.py @@ -67,17 +67,18 @@ def convert_url_thumbnail(thumbnail_url: str, output_thumbnail_path: str) -> Opt with tempfile.NamedTemporaryFile(delete=False) as thumbnail: thumbnail.write(file.read()) - os.makedirs(os.path.dirname(output_thumbnail_path), exist_ok=True) + try: + os.makedirs(os.path.dirname(output_thumbnail_path), exist_ok=True) - tmp_output_path = FFMPEG.tmp_file_path( - relative_file_path=thumbnail.name, extension="jpg" - ) - FFMPEG.run(["-bitexact", "-i", thumbnail.name, tmp_output_path]) + tmp_output_path = FFMPEG.tmp_file_path( + relative_file_path=thumbnail.name, extension="jpg" + ) + FFMPEG.run(["-bitexact", "-i", thumbnail.name, tmp_output_path]) - # Have FileHandler handle the move to a potential cross-device - FileHandler.move(tmp_output_path, output_thumbnail_path) - FileHandler.delete(tmp_output_path) - - os.remove(thumbnail.name) + # Have FileHandler handle the move to a potential cross-device + FileHandler.move(tmp_output_path, output_thumbnail_path) + finally: + FileHandler.delete(tmp_output_path) + FileHandler.delete(thumbnail.name) return True diff --git a/tests/conftest.py b/tests/conftest.py index c5985cf1..a38e8c03 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,7 @@ import contextlib import json import logging +import os import tempfile from pathlib import Path from typing import Any @@ -11,6 +12,7 @@ from unittest.mock import patch import pytest +from ytdl_sub.utils.file_handler import FileHandler from ytdl_sub.utils.logger import Logger @@ -84,9 +86,12 @@ def preset_dict_to_subscription_yaml_generator() -> Callable: @contextlib.contextmanager def _preset_dict_to_subscription_yaml_generator(subscription_name: str, preset_dict: Dict): subscription_dict = {subscription_name: preset_dict} - with tempfile.NamedTemporaryFile(suffix=".yaml") as tmp_file: + with tempfile.NamedTemporaryFile(suffix=".yaml", delete=False) as tmp_file: tmp_file.write(json.dumps(subscription_dict).encode("utf-8")) - tmp_file.flush() + + try: yield tmp_file.name + finally: + FileHandler.delete(tmp_file.name) return _preset_dict_to_subscription_yaml_generator diff --git a/tests/e2e/conftest.py b/tests/e2e/conftest.py index de2cea83..f87b0123 100644 --- a/tests/e2e/conftest.py +++ b/tests/e2e/conftest.py @@ -15,7 +15,7 @@ from ytdl_sub.cli.main import main from ytdl_sub.config.config_file import ConfigFile from ytdl_sub.subscriptions.subscription import Subscription from ytdl_sub.subscriptions.subscription_download import SubscriptionDownload -from ytdl_sub.utils.file_handler import FileHandlerTransactionLog +from ytdl_sub.utils.file_handler import FileHandlerTransactionLog, FileHandler from ytdl_sub.utils.logger import Logger from ytdl_sub.utils.yaml import load_yaml @@ -67,10 +67,13 @@ def music_video_config(music_video_config_path, working_directory) -> ConfigFile @pytest.fixture() def music_video_config_for_cli(music_video_config) -> str: - with tempfile.NamedTemporaryFile(suffix=".yaml") as tmp_file: + with tempfile.NamedTemporaryFile(suffix=".yaml", delete=False) as tmp_file: tmp_file.write(json.dumps(music_video_config._value).encode("utf-8")) - tmp_file.flush() + + try: yield tmp_file.name + finally: + FileHandler.delete(tmp_file.name) @pytest.fixture() @@ -98,10 +101,13 @@ def timestamps_file_path(): "00:01:01 Part 5\n", ] - with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", suffix=".txt") as tmp: + with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", suffix=".txt", delete=False) as tmp: tmp.writelines(timestamps) - tmp.seek(0) + + try: yield tmp.name + finally: + FileHandler.delete(tmp.name) def mock_run_from_cli(args: str) -> List[Tuple[Subscription, FileHandlerTransactionLog]]: diff --git a/tests/unit/utils/test_yaml.py b/tests/unit/utils/test_yaml.py index 6bc4753a..c3399018 100644 --- a/tests/unit/utils/test_yaml.py +++ b/tests/unit/utils/test_yaml.py @@ -6,6 +6,7 @@ import pytest from ytdl_sub.utils.exceptions import FileNotFoundException from ytdl_sub.utils.exceptions import InvalidYamlException +from ytdl_sub.utils.file_handler import FileHandler from ytdl_sub.utils.yaml import load_yaml @@ -28,8 +29,10 @@ def bad_yaml_file_path(bad_yaml) -> str: tmp_file.write(bad_yaml.encode("utf-8")) tmp_file.flush() - yield tmp_file.name - os.remove(tmp_file.name) + try: + yield tmp_file.name + finally: + FileHandler.delete(tmp_file.name) def test_load_yaml_file_not_found():