Fix validators and output directory
This commit is contained in:
parent
3a22a9bf10
commit
374021d027
8 changed files with 61 additions and 50 deletions
44
config.yaml
44
config.yaml
|
|
@ -8,17 +8,21 @@ presets:
|
|||
skip_premiere_tracks: True
|
||||
ytdl_options:
|
||||
format: 'bestaudio[ext=mp3]'
|
||||
post_process:
|
||||
output_options:
|
||||
file_name: "[{album_year}] {sanitized_album}/{track_number_padded} - {sanitized_title}.{ext}"
|
||||
thumbnail_name: "[{album_year}] {sanitized_album}/folder.{thumbnail_ext}"
|
||||
tagging:
|
||||
artist: "{artist}"
|
||||
albumartist: "{artist}"
|
||||
title: "{title}"
|
||||
album: "{album}"
|
||||
tracknumber: "{track_number}"
|
||||
year: "{album_year}"
|
||||
genre: "{genre}"
|
||||
convert_thumbnail: "jpeg"
|
||||
thumbnail_name: "[{album_year}] {sanitized_album}/folder.jpeg"
|
||||
metadata_options:
|
||||
id3:
|
||||
id3_version: "2.4"
|
||||
tags:
|
||||
artist: "{artist}"
|
||||
albumartist: "{artist}"
|
||||
title: "{title}"
|
||||
album: "{album}"
|
||||
tracknumber: "{track_number}"
|
||||
year: "{album_year}"
|
||||
genre: "{genre}"
|
||||
|
||||
music_videos:
|
||||
youtube:
|
||||
|
|
@ -26,14 +30,16 @@ presets:
|
|||
ytdl_options:
|
||||
format: 'best'
|
||||
ignoreerrors: True
|
||||
post_process:
|
||||
output_options:
|
||||
file_name: "{sanitized_artist} - {sanitized_title}.{ext}"
|
||||
convert_thumbnail: "jpg"
|
||||
thumbnail_name: "{sanitized_artist} - {sanitized_title}.jpg"
|
||||
nfo_name: "{sanitized_artist} - {sanitized_title}.nfo"
|
||||
nfo_root: "musicvideo"
|
||||
convert_thumbnail: "jpeg"
|
||||
thumbnail_name: "{sanitized_artist} - {sanitized_title}.jpeg"
|
||||
metadata_options:
|
||||
nfo:
|
||||
artist: "{artist}"
|
||||
title: "{title}"
|
||||
album: "Music Videos"
|
||||
year: "{upload_year}"
|
||||
nfo_name: "{sanitized_artist} - {sanitized_title}.nfo"
|
||||
nfo_root: "musicvideo"
|
||||
tags:
|
||||
artist: "{artist}"
|
||||
title: "{title}"
|
||||
album: "Music Videos"
|
||||
year: "{upload_year}"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ ALISON:
|
|||
preset: "soundcloud_with_id3_tags"
|
||||
soundcloud:
|
||||
username: alis_on
|
||||
output_path: "/mnt/nas/Downloads/ytdl/music/ALISON"
|
||||
output_options:
|
||||
output_directory: "/tmp/ALISON"
|
||||
overrides:
|
||||
artist: "A.L.I.S.O.N."
|
||||
genre: "Synthwave / Electronic"
|
||||
|
|
@ -11,7 +12,8 @@ delorra:
|
|||
preset: "soundcloud_with_id3_tags"
|
||||
soundcloud:
|
||||
username: delorra
|
||||
output_path: "/mnt/nas/Downloads/ytdl/music/DeLorra"
|
||||
output_options:
|
||||
output_directory: "/tmp/DeLorra"
|
||||
overrides:
|
||||
artist: "DeLorra"
|
||||
genre: "Synthwave / Electronic"
|
||||
|
|
@ -20,23 +22,26 @@ bl00dwave:
|
|||
preset: "soundcloud_with_id3_tags"
|
||||
soundcloud:
|
||||
username: bl00dwave
|
||||
output_path: "/tmp/bl00dwave"
|
||||
output_options:
|
||||
output_directory: "/tmp/bl00dwave"
|
||||
overrides:
|
||||
artist: "bl00dwave"
|
||||
genre: "Synthwave / Electronic"
|
||||
|
||||
tom_petty:
|
||||
preset: "music_videos"
|
||||
youtube:
|
||||
playlist_id: PLoopXDarluPBnuxs4PTC55Sc_2ShAXC0i
|
||||
preset: "music_videos"
|
||||
output_path: "/tmp/Tom Petty"
|
||||
output_options:
|
||||
output_directory: "/tmp/Tom Petty"
|
||||
overrides:
|
||||
artist: "Tom Petty and the Heartbreakers"
|
||||
|
||||
rammstein:
|
||||
preset: "music_videos"
|
||||
youtube:
|
||||
playlist_id: "PLVTLbc6i-h_iuhdwUfuPDLFLXG2QQnz-x"
|
||||
preset: "music_videos"
|
||||
output_path: "/mnt/nas/Downloads/ytdl/music_videos/Rammstein"
|
||||
output_options:
|
||||
output_directory: "/tmp/Rammstein"
|
||||
overrides:
|
||||
artist: "Rammstein"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
from pathlib import Path
|
||||
from shutil import copyfile
|
||||
from typing import Type
|
||||
from typing import TypeVar
|
||||
|
|
@ -129,38 +130,44 @@ class Subscription(object):
|
|||
relative_directory=self.config_options.working_directory.value
|
||||
)
|
||||
|
||||
entry_destination_file_path = entry.apply_formatter(
|
||||
output_directory = entry.apply_formatter(
|
||||
format_string=self.output_options.output_directory.format_string,
|
||||
overrides=self.overrides.dict
|
||||
)
|
||||
output_file_name = entry.apply_formatter(
|
||||
format_string=self.output_options.file_name.format_string,
|
||||
overrides=self.overrides.dict,
|
||||
)
|
||||
entry_destination_file_path = Path(output_directory) / Path(output_file_name)
|
||||
|
||||
os.makedirs(os.path.dirname(entry_destination_file_path), exist_ok=True)
|
||||
copyfile(entry_source_file_path, entry_destination_file_path)
|
||||
|
||||
# Download the thumbnail if its present
|
||||
if self.output_options.thumbnail_name:
|
||||
thumbnail_source_path = entry.thumbnail_path(
|
||||
source_thumbnail_path = entry.thumbnail_path(
|
||||
relative_directory=self.config_options.working_directory.value
|
||||
)
|
||||
|
||||
thumbnail_destination_path = entry.apply_formatter(
|
||||
output_thumbnail_name = entry.apply_formatter(
|
||||
format_string=self.output_options.thumbnail_name.format_string,
|
||||
overrides=self.overrides.dict,
|
||||
)
|
||||
output_thumbnail_path = Path(output_directory) / Path(output_thumbnail_name)
|
||||
|
||||
os.makedirs(os.path.dirname(entry_destination_file_path), exist_ok=True)
|
||||
os.makedirs(os.path.dirname(output_thumbnail_path), exist_ok=True)
|
||||
|
||||
# If the thumbnail is to be converted, then save the converted thumbnail to the
|
||||
# output filepath
|
||||
if self.output_options.convert_thumbnail:
|
||||
im = Image.open(thumbnail_source_path).convert("RGB")
|
||||
im = Image.open(source_thumbnail_path).convert("RGB")
|
||||
im.save(
|
||||
fp=thumbnail_destination_path,
|
||||
fp=output_thumbnail_name,
|
||||
format=self.output_options.convert_thumbnail.value,
|
||||
)
|
||||
# Otherwise, just copy the downloaded thumbnail
|
||||
else:
|
||||
copyfile(thumbnail_source_path, thumbnail_destination_path)
|
||||
copyfile(source_thumbnail_path, output_thumbnail_name)
|
||||
|
||||
if self.metadata_options.nfo:
|
||||
self._post_process_nfo(entry)
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ class StringFormatterValidator(StringValidator):
|
|||
|
||||
return format_variables
|
||||
|
||||
def __init__(self, name, format_string: str):
|
||||
super().__init__(name=name, value=format_string)
|
||||
def __init__(self, name, value: str):
|
||||
super().__init__(name=name, value=value)
|
||||
self.format_variables = self.__validate_and_get_format_variables()
|
||||
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ class StringSelectValidator(StringValidator):
|
|||
|
||||
select_values: Set[str] = set()
|
||||
|
||||
def __init__(self, name, format_string: str):
|
||||
super().__init__(name=name, value=format_string)
|
||||
def __init__(self, name, value: str):
|
||||
super().__init__(name=name, value=value)
|
||||
|
||||
if self.value not in self.select_values:
|
||||
raise self._validation_exception(
|
||||
|
|
|
|||
|
|
@ -16,11 +16,3 @@ class MetadataOptionsValidator(StrictDictValidator):
|
|||
|
||||
self.id3 = self.validate_key_if_present(key="id3", validator=Id3Validator)
|
||||
self.nfo = self.validate_key_if_present(key="nfo", validator=NFOValidator)
|
||||
|
||||
self.output_directory: StringFormatterValidator = self.validate_key(
|
||||
key="output_directory", validator=StringFormatterValidator
|
||||
)
|
||||
|
||||
self.file_name: StringFormatterValidator = self.validate_key(
|
||||
key="file_name", validator=StringFormatterValidator
|
||||
)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class OverridesValidator(DictFormatterValidator):
|
|||
def dict(self) -> dict:
|
||||
"""For overrides, create sanitized versions of each entry for convenience"""
|
||||
output_dict = copy.deepcopy(super().dict)
|
||||
for key in self.keys:
|
||||
for key in list(output_dict.keys()):
|
||||
output_dict[f"sanitized_{key}"] = sanitize_filename.sanitize(
|
||||
output_dict[key]
|
||||
)
|
||||
|
|
@ -47,8 +47,9 @@ class OverridesValidator(DictFormatterValidator):
|
|||
|
||||
|
||||
class PresetValidator(StrictDictValidator):
|
||||
required_keys = {"output_options, metadata_options"}
|
||||
required_keys = {"output_options"}
|
||||
optional_keys = {
|
||||
"metadata_options",
|
||||
"ytdl_options",
|
||||
"overrides",
|
||||
*SubscriptionSourceName.all(),
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ from ytdl_subscribe.validators.config.config_validator import ConfigValidator
|
|||
from ytdl_subscribe.validators.config.preset_validator import OverridesValidator
|
||||
from ytdl_subscribe.validators.config.preset_validator import PresetValidator
|
||||
from ytdl_subscribe.validators.config.sources.soundcloud_validators import (
|
||||
SoundcloudSourceValidator,
|
||||
SoundcloudSourceValidator, SoundcloudAlbumsAndSinglesDownloadValidator,
|
||||
)
|
||||
from ytdl_subscribe.validators.config.sources.youtube_validators import (
|
||||
YoutubePlaylistDownloadValidator,
|
||||
|
|
@ -64,14 +64,14 @@ class SubscriptionValidator(StrictDictValidator):
|
|||
del preset_dict["preset"]
|
||||
|
||||
self.preset = PresetValidator(
|
||||
name=self.name,
|
||||
name=f"{self.name}.{preset_name}",
|
||||
value=preset_dict,
|
||||
)
|
||||
|
||||
def to_subscription(self) -> Subscription:
|
||||
if isinstance(
|
||||
self.preset.subscription_source.download_strategy,
|
||||
SoundcloudAlbumsAndSinglesSubscription,
|
||||
SoundcloudAlbumsAndSinglesDownloadValidator,
|
||||
):
|
||||
subscription_class = SoundcloudAlbumsAndSinglesSubscription
|
||||
elif isinstance(
|
||||
|
|
|
|||
Loading…
Reference in a new issue