diff --git a/config.yaml b/config.yaml index 127a37be..3da8e6f6 100644 --- a/config.yaml +++ b/config.yaml @@ -33,7 +33,6 @@ presets: ignoreerrors: True output_options: file_name: "{sanitized_artist} - {sanitized_title}.{ext}" - convert_thumbnail: "jpeg" thumbnail_name: "{sanitized_artist} - {sanitized_title}.jpg" convert_thumbnail: to: "jpg" @@ -53,7 +52,6 @@ presets: ignoreerrors: True output_options: file_name: "{output_file_name}.{ext}" - convert_thumbnail: "jpeg" thumbnail_name: "{output_file_name}.jpg" convert_thumbnail: to: "jpg" diff --git a/subscriptions.yaml b/subscriptions.yaml index 397fe554..343d6c6d 100644 --- a/subscriptions.yaml +++ b/subscriptions.yaml @@ -18,13 +18,13 @@ # artist: "DeLorra" # genre: "Synthwave / Electronic" # -bl00dwave: - preset: "soundcloud_with_id3_tags" - soundcloud: - username: bl00dwave - overrides: - artist: "bl00dwave" - genre: "Synthwave / Electronic" +#bl00dwave: +# preset: "soundcloud_with_id3_tags" +# soundcloud: +# username: bl00dwave +# overrides: +# artist: "bl00dwave" +# genre: "Synthwave / Electronic" # #tom_petty: # preset: "music_videos" @@ -56,15 +56,17 @@ bl00dwave: # overrides: # artist: "The Gogos" -#recent_channel_test: -# preset: "yt_channel" -# ytdl_options: -# break_on_reject: True -# youtube: -# download_strategy: "channel" -# channel_id: "UCRcCVDu_4oARsAKFkKYydAQ" -# after: today-2days -# output_options: -# output_directory: "/tmp/dunkey" -# overrides: -# tv_show_name: "Youtube: Dunkey" \ No newline at end of file +recent_channel_test: + preset: "yt_channel" + ytdl_options: + break_on_reject: True + youtube: + download_strategy: "channel" + channel_id: "UCsvn_Po0SmunchJYOWpOxMg" + after: today-13days + output_options: + output_directory: "/tmp/dunkey" + keep_files: + after: today-3days + overrides: + tv_show_name: "Youtube: Dunkey" \ No newline at end of file diff --git a/ytdl_subscribe/config/preset_options.py b/ytdl_subscribe/config/preset_options.py index 32770991..4b656768 100644 --- a/ytdl_subscribe/config/preset_options.py +++ b/ytdl_subscribe/config/preset_options.py @@ -52,7 +52,7 @@ class OutputOptions(StrictDictValidator): _optional_keys = { "thumbnail_name", "maintain_download_archive", - "maintain_stale_file_deletion", + "keep_files", } def __init__(self, name, value): @@ -75,11 +75,11 @@ class OutputOptions(StrictDictValidator): self.maintain_download_archive = self._validate_key_if_present( key="maintain_download_archive", validator=BoolValidator, default=False ) - self.maintain_stale_file_deletion = self._validate_key_if_present( - key="maintain_stale_file_deletion", validator=DateRangeValidator + self.delete_stale_files = self._validate_key_if_present( + key="keep_files", validator=DateRangeValidator ) - if self.maintain_stale_file_deletion and not self.maintain_download_archive: + if self.delete_stale_files and not self.maintain_download_archive: raise self._validation_exception( - "maintain_stale_file_deletion requires maintain_download_archive set to True" + "keep_files requires maintain_download_archive set to True" ) diff --git a/ytdl_subscribe/entries/youtube.py b/ytdl_subscribe/entries/youtube.py index c4efe197..36834af6 100644 --- a/ytdl_subscribe/entries/youtube.py +++ b/ytdl_subscribe/entries/youtube.py @@ -1,3 +1,6 @@ +import os.path +from pathlib import Path + from ytdl_subscribe.entries.entry import Entry @@ -17,3 +20,26 @@ class YoutubeVideo(Entry): return self.kwargs("track") return super().title + + @property + def download_thumbnail_path(self) -> str: + """ + Returns + ------- + The entry's thumbnail's file path to where it was downloaded. Ytdl has a bug where the + thumbnail entry is not the actual thumbnail it downloaded. So check all the possible + extensions that it may have downloaded, and see if that thumbnail's extension exists. + + TODO: move this into the init so the thumbnail_ext variable can be set accordingly + """ + thumbnails = self.kwargs("thumbnails") + possible_thumbnail_exts = set() + for thumbnail in thumbnails: + possible_thumbnail_exts.add(thumbnail["url"].split(".")[-1]) + + for ext in possible_thumbnail_exts: + possible_thumbnail_path = str(Path(self.working_directory) / f"{self.uid}.{ext}") + if os.path.isfile(possible_thumbnail_path): + return possible_thumbnail_path + + return super().download_thumbnail_path diff --git a/ytdl_subscribe/plugins/nfo_tags.py b/ytdl_subscribe/plugins/nfo_tags.py index 99e059e3..4f39ecf8 100644 --- a/ytdl_subscribe/plugins/nfo_tags.py +++ b/ytdl_subscribe/plugins/nfo_tags.py @@ -1,3 +1,4 @@ +import os from pathlib import Path import dicttoxml @@ -53,6 +54,7 @@ class NfoTagsPlugin(Plugin[NfoTagsOptions]): # Save the nfo's XML to file nfo_file_path = Path(self.output_directory) / nfo_file_name + os.makedirs(os.path.dirname(nfo_file_path), exist_ok=True) with open(nfo_file_path, "wb") as nfo_file: nfo_file.write(xml) diff --git a/ytdl_subscribe/plugins/output_directory_nfo_tags.py b/ytdl_subscribe/plugins/output_directory_nfo_tags.py index 54130cbb..ee300f96 100644 --- a/ytdl_subscribe/plugins/output_directory_nfo_tags.py +++ b/ytdl_subscribe/plugins/output_directory_nfo_tags.py @@ -1,3 +1,4 @@ +import os from pathlib import Path import dicttoxml @@ -53,5 +54,6 @@ class OutputDirectoryNfoTagsPlugin(Plugin[OutputDirectoryNfoTagsOptions]): # Save the nfo's XML to file nfo_file_path = Path(self.output_directory) / nfo_file_name + os.makedirs(os.path.dirname(nfo_file_path), exist_ok=True) with open(nfo_file_path, "wb") as nfo_file: nfo_file.write(xml) diff --git a/ytdl_subscribe/subscriptions/subscription.py b/ytdl_subscribe/subscriptions/subscription.py index 5c5f128e..76f4181e 100644 --- a/ytdl_subscribe/subscriptions/subscription.py +++ b/ytdl_subscribe/subscriptions/subscription.py @@ -134,21 +134,20 @@ class Subscription: @contextlib.contextmanager def _maintain_archive_file(self): - if not self.output_options.maintain_download_archive: - return - - self._enhanced_download_archive.prepare_download_archive() + if self.output_options.maintain_download_archive: + self._enhanced_download_archive.prepare_download_archive() yield # If output options maintains stale file deletion, perform the delete here prior to saving # the download archive - if self.output_options.maintain_stale_file_deletion: - self._enhanced_download_archive.remove_stale_files( - date_range=self.output_options.maintain_stale_file_deletion.get_date_range() - ) + if self.output_options.maintain_download_archive: + if self.output_options.delete_stale_files: + self._enhanced_download_archive.remove_stale_files( + date_range=self.output_options.delete_stale_files.get_date_range() + ) - self._enhanced_download_archive.save_download_archive() + self._enhanced_download_archive.save_download_archive() def _initialize_plugins(self) -> List[Plugin]: plugins: List[Plugin] = [] diff --git a/ytdl_subscribe/validators/date_range_validator.py b/ytdl_subscribe/validators/date_range_validator.py index 89d0cdaf..d727acb6 100644 --- a/ytdl_subscribe/validators/date_range_validator.py +++ b/ytdl_subscribe/validators/date_range_validator.py @@ -1,4 +1,3 @@ -from abc import ABC from typing import Optional from yt_dlp import DateRange @@ -7,8 +6,8 @@ from ytdl_subscribe.validators.strict_dict_validator import StrictDictValidator from ytdl_subscribe.validators.string_datetime import StringDatetimeValidator -class DateRangeValidator(StrictDictValidator, ABC): - optional_keys = {"before", "after"} +class DateRangeValidator(StrictDictValidator): + _optional_keys = {"before", "after"} def __init__(self, name, value): super().__init__(name, value)