diff --git a/tests/unit/entries/conftest.py b/tests/unit/entries/conftest.py index 4864ad46..9ba72040 100644 --- a/tests/unit/entries/conftest.py +++ b/tests/unit/entries/conftest.py @@ -116,7 +116,7 @@ def mock_entry_kwargs( @pytest.fixture def mock_entry(mock_entry_kwargs): - return Entry(**mock_entry_kwargs) + return Entry(entry_dict=mock_entry_kwargs) @pytest.fixture diff --git a/tests/unit/entries/test_soundcloud_entries.py b/tests/unit/entries/test_soundcloud_entries.py index 4748e966..9a76d19c 100644 --- a/tests/unit/entries/test_soundcloud_entries.py +++ b/tests/unit/entries/test_soundcloud_entries.py @@ -52,7 +52,7 @@ def mock_soundcloud_track_kwargs(mock_entry_kwargs, url): @pytest.fixture def mock_soundcloud_track(mock_soundcloud_track_kwargs): - return SoundcloudTrack(**mock_soundcloud_track_kwargs) + return SoundcloudTrack(entry_dict=mock_soundcloud_track_kwargs) @pytest.fixture diff --git a/ytdl_subscribe/config/preset_options.py b/ytdl_subscribe/config/preset_options.py index b6807617..32770991 100644 --- a/ytdl_subscribe/config/preset_options.py +++ b/ytdl_subscribe/config/preset_options.py @@ -1,5 +1,3 @@ -from abc import ABC -from typing import Any from typing import Optional from yt_dlp.utils import sanitize_filename @@ -12,7 +10,6 @@ from ytdl_subscribe.validators.string_formatter_validators import OverridesStrin from ytdl_subscribe.validators.string_formatter_validators import StringFormatterValidator from ytdl_subscribe.validators.validators import BoolValidator from ytdl_subscribe.validators.validators import LiteralDictValidator -from ytdl_subscribe.validators.validators import StringValidator class YTDLOptions(LiteralDictValidator): diff --git a/ytdl_subscribe/downloaders/soundcloud_downloader.py b/ytdl_subscribe/downloaders/soundcloud_downloader.py index 83890c88..41a1265f 100644 --- a/ytdl_subscribe/downloaders/soundcloud_downloader.py +++ b/ytdl_subscribe/downloaders/soundcloud_downloader.py @@ -66,7 +66,8 @@ class SoundcloudDownloader( info = self.extract_info(url=artist_albums_url) albums = [ - SoundcloudAlbum(working_direcotry=self.working_directory, **e) for e in info["entries"] + SoundcloudAlbum(entry_dict=e, working_directory=self.working_directory) + for e in info["entries"] ] return [album for album in albums if album.track_count > 0] @@ -79,7 +80,7 @@ class SoundcloudDownloader( info = self.extract_info(url=artist_tracks_url) return [ - SoundcloudTrack(working_directory=self.working_directory, kwargs=e) + SoundcloudTrack(entry_dict=e, working_directory=self.working_directory) for e in info["entries"] ] diff --git a/ytdl_subscribe/downloaders/youtube_downloader.py b/ytdl_subscribe/downloaders/youtube_downloader.py index a7fce100..002ef7bd 100644 --- a/ytdl_subscribe/downloaders/youtube_downloader.py +++ b/ytdl_subscribe/downloaders/youtube_downloader.py @@ -80,16 +80,22 @@ class YoutubeDownloader( # Load the entries from info.json, ignore the playlist entry for file_name in os.listdir(self.working_directory): - if file_name.endswith(".info.json") and not file_name.startswith(ignore_prefix): - with open(Path(self.working_directory) / file_name, "r", encoding="utf-8") as file: - entries.append(YoutubeVideo(**json.load(file))) + if file_name.startswith(ignore_prefix) or not file_name.endswith(".info.json"): + continue + + with open(Path(self.working_directory) / file_name, "r", encoding="utf-8") as file: + entries.append( + YoutubeVideo( + entry_dict=json.load(file), working_directory=self.working_directory + ) + ) return entries def download_video(self, video_id: str) -> YoutubeVideo: """Download a single Youtube video""" entry = self.extract_info(url=self.video_url(video_id)) - return YoutubeVideo(**entry) + return YoutubeVideo(entry_dict=entry, working_directory=self.working_directory) def download_playlist(self, playlist_id: str) -> List[YoutubeVideo]: """ diff --git a/ytdl_subscribe/entries/entry.py b/ytdl_subscribe/entries/entry.py index 08974557..de82a195 100644 --- a/ytdl_subscribe/entries/entry.py +++ b/ytdl_subscribe/entries/entry.py @@ -24,19 +24,19 @@ class BaseEntry(ABC): Abstract entry object to represent anything download from ytdl (playlist metadata, media, etc). """ - def __init__(self, working_directory: Optional[str] = None, **kwargs): + def __init__(self, entry_dict: Dict, working_directory: Optional[str] = None): """ Initialize the entry using ytdl metadata Parameters ---------- + entry_dict + Entry metadata working_directory Optional. Directory that the entry is downloaded to - kwargs - Entry metadata """ self._working_directory = working_directory - self._kwargs = kwargs + self._kwargs = entry_dict def kwargs_contains(self, key: str) -> bool: """Returns whether internal kwargs contains the specified key""" diff --git a/ytdl_subscribe/entries/soundcloud.py b/ytdl_subscribe/entries/soundcloud.py index 504c7b73..6b0b581d 100644 --- a/ytdl_subscribe/entries/soundcloud.py +++ b/ytdl_subscribe/entries/soundcloud.py @@ -69,16 +69,16 @@ class SoundcloudAlbumTrack(SoundcloudTrack): def __init__( self, + entry_dict: Dict, working_directory: str, album: str, album_year: int, playlist_metadata: PlaylistMetadata, - **kwargs, ): """ Initialize the album track using album metadata and ytdl metadata for the specific track. """ - super().__init__(working_directory=working_directory, **kwargs) + super().__init__(entry_dict=entry_dict, working_directory=working_directory) self._album = album self._album_year = album_year self._playlist_metadata = playlist_metadata @@ -111,11 +111,11 @@ class SoundcloudAlbumTrack(SoundcloudTrack): playlist_metadata: PlaylistMetadata, ) -> "SoundcloudAlbumTrack": return SoundcloudAlbumTrack( + entry_dict=soundcloud_track._kwargs, # pylint: disable=protected-access working_directory=soundcloud_track.working_directory, album=album, album_year=album_year, playlist_metadata=playlist_metadata, - **soundcloud_track._kwargs, # pylint: disable=protected-access ) @@ -131,7 +131,7 @@ class SoundcloudAlbum(Entry): data needed from the tracks before representing it as an album track. """ return [ - SoundcloudTrack(working_directory=self._working_directory, **entry) + SoundcloudTrack(entry_dict=entry, working_directory=self._working_directory) for entry in self.kwargs("entries") ] diff --git a/ytdl_subscribe/plugins/convert_thumbnail.py b/ytdl_subscribe/plugins/convert_thumbnail.py index e79f01e3..a8fd553c 100644 --- a/ytdl_subscribe/plugins/convert_thumbnail.py +++ b/ytdl_subscribe/plugins/convert_thumbnail.py @@ -1,6 +1,7 @@ import os from PIL.Image import Image +from PIL.Image import open as pil_open from ytdl_subscribe.entries.entry import Entry from ytdl_subscribe.plugins.plugin import Plugin @@ -33,7 +34,7 @@ class ConvertThumbnailPlugin(Plugin[ConvertThumbnailOptions]): if not os.path.isfile(entry.download_thumbnail_path): raise ValueError("Thumbnail not found") - image = Image.open(entry.download_thumbnail_path).convert("RGB") + image: Image = pil_open(entry.download_thumbnail_path).convert("RGB") # Pillow likes the formal 'jpeg' name and not 'jpg' thumbnail_format = self.plugin_options.convert_to.value diff --git a/ytdl_subscribe/subscriptions/subscription.py b/ytdl_subscribe/subscriptions/subscription.py index d7efe03b..5c5f128e 100644 --- a/ytdl_subscribe/subscriptions/subscription.py +++ b/ytdl_subscribe/subscriptions/subscription.py @@ -127,9 +127,10 @@ class Subscription: def _prepare_working_directory(self): os.makedirs(self.working_directory, exist_ok=True) - yield - - shutil.rmtree(self.working_directory) + try: + yield + finally: + shutil.rmtree(self.working_directory) @contextlib.contextmanager def _maintain_archive_file(self): diff --git a/ytdl_subscribe/validators/strict_dict_validator.py b/ytdl_subscribe/validators/strict_dict_validator.py index 417cf7a5..2c1406a5 100644 --- a/ytdl_subscribe/validators/strict_dict_validator.py +++ b/ytdl_subscribe/validators/strict_dict_validator.py @@ -1,7 +1,6 @@ from typing import List from typing import Set -from ytdl_subscribe.utils.exceptions import ValidationException from ytdl_subscribe.validators.validators import DictValidator diff --git a/ytdl_subscribe/validators/string_datetime.py b/ytdl_subscribe/validators/string_datetime.py index ec7f2acf..272a1b3a 100644 --- a/ytdl_subscribe/validators/string_datetime.py +++ b/ytdl_subscribe/validators/string_datetime.py @@ -1,6 +1,5 @@ from yt_dlp.utils import datetime_from_str -from ytdl_subscribe.utils.exceptions import ValidationException from ytdl_subscribe.validators.validators import Validator