[FEATURE] Music prebuilt presets

This commit is contained in:
Jesse Bannon 2023-10-22 22:59:29 -07:00
parent c149957b04
commit d979465ff9
5 changed files with 198 additions and 57 deletions

View file

@ -5,8 +5,6 @@ from typing import Set
import mergedeep import mergedeep
from ytdl_sub.prebuilt_presets.tv_show import TvShowByDatePresets
from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionPresets
from ytdl_sub.utils.yaml import load_yaml from ytdl_sub.utils.yaml import load_yaml
@ -27,3 +25,7 @@ PREBUILT_PRESET_NAMES: Set[str] = set(PREBUILT_PRESETS.keys())
PUBLISHED_PRESET_NAMES: Set[str] = { PUBLISHED_PRESET_NAMES: Set[str] = {
name for name in PREBUILT_PRESET_NAMES if not name.startswith("_") name for name in PREBUILT_PRESET_NAMES if not name.startswith("_")
} }
class PrebuiltPresets:
preset_names: Set[str]

View file

@ -0,0 +1,9 @@
from ytdl_sub.prebuilt_presets import _, PrebuiltPresets
class MusicPresets(PrebuiltPresets):
kodi_tv_show_by_date = _
jellyfin_tv_show_by_date = _
plex_tv_show_by_date = _

View file

@ -0,0 +1,147 @@
presets:
_music_base:
output_options:
output_directory: "{music_directory}"
file_name: "{track_full_path}"
thumbnail_name: "{album_cover_path}"
download_archive_name: ".{subscription_name_sanitized}-download-archive.json"
maintain_download_archive: True
ytdl_options:
break_on_existing: True
format: "ba[ext=webm]/ba"
audio_extract:
codec: "best"
music_tags:
artist: "{track_artist}"
albumartist: "{track_album_artist}"
title: "{track_title}"
album: "{track_album}"
track: "{track_number}"
tracktotal: "{track_total}"
year: "{track_year}"
# multi-tags
artists:
- "{track_artist}"
albumartists:
- "{track_album_artist}"
genre:
- "{track_genre}"
overrides:
# Subscription overrides
subscription_indent_1: "Unset" # genre
url: "{subscription_value}"
# Track Overrides
track_title: "{title}"
track_album: "Singles"
track_artist: "{channel}"
track_album_artist: "{track_artist}"
track_number: "1"
track_number_padded: "01"
track_total: "1"
track_year: "{upload_year}"
track_genre: "{subscription_indent_1}"
# Directory Overrides
music_directory: "/music/tagged_manual"
artist_dir: "{track_artist_sanitized}"
album_dir: "[{track_year}] {track_album_sanitized}"
track_file_name: "{track_number_padded} - {track_title_sanitized}.{ext}"
track_full_path: "{artist_dir}/{album_dir}/{track_file_name}"
album_cover_path: "{artist_dir}/{album_dir}/folder.{thumbnail_ext}"
"Single":
preset:
- "_music_base"
download:
- "{url}"
_albums_from_playlists:
preset:
- "Single"
overrides:
track_album: "{playlist_title}"
track_number: "{playlist_index}"
track_number_padded: "{playlist_index_padded}"
track_total: "{playlist_count}"
track_year: "{playlist_max_upload_year}"
_albums_from_chapters:
preset: "Single"
chapters:
embed_chapters: True
split_by_chapters:
when_no_chapters: "pass"
overrides:
track_title: "{chapter_title}" # Chapter title is the track title
track_album: "{title}" # Video's title is the album title
track_number: "{chapter_index}"
track_number_padded: "{chapter_index_padded}"
track_total: "{chapter_count}"
"SoundCloud Discography":
preset: "_music_base"
# Download using the multi_url strategy
download:
download_strategy: "multi_url"
urls:
# The first URL will be all the artist's tracks.
# Treat these as singles - an album with a single track
- url: "{url}/tracks"
variables:
sc_track_album: "{title}"
sc_track_number: "1"
sc_track_number_padded: "01"
sc_track_total: "1"
sc_track_year: "{upload_year}"
# Set the second URL to the artist's albums. If a track belongs to both
# to an album and tracks (in the URL above), it will resolve to this
# URL and include the album metadata we set below.
- url: "{url}/albums"
variables:
sc_track_album: "{playlist_title}"
sc_track_number: "{playlist_index}"
sc_track_number_padded: "{playlist_index_padded}"
sc_track_total: "{playlist_count}"
sc_track_year: "{playlist_max_upload_year}"
# Override various track properties using playlist variables.
overrides:
track_album: "{sc_track_album}"
track_number: "{sc_track_number}"
track_number_padded: "{sc_track_number_padded}"
track_total: "{sc_track_total}"
track_year: "{sc_track_year}"
"YouTube Releases":
preset:
- "_albums_from_playlists"
"Bandcamp":
preset:
- "_albums_from_playlists"
regex:
from:
title:
match:
- ".*? - (.*)" # Captures 'Some - Song' from 'Emily Hopkins - Some - Song'
capture_group_names:
- "captured_track_title"
capture_group_defaults:
- "{title}"
overrides:
track_title: "{captured_track_title}"

View file

@ -1,26 +1,4 @@
from typing import Set from ytdl_sub.prebuilt_presets import PrebuiltPresets
class PrebuiltPreset:
"""placeholder"""
_ = PrebuiltPreset()
class PrebuiltPresets:
@classmethod
def get_preset_names(cls) -> Set[str]:
"""
Returns
-------
Preset names in the set
"""
return set(
preset_name
for preset_name in dir(cls)
if isinstance(getattr(cls, preset_name), PrebuiltPreset)
)
class TvShowByDatePresets(PrebuiltPresets): class TvShowByDatePresets(PrebuiltPresets):
@ -28,39 +6,44 @@ class TvShowByDatePresets(PrebuiltPresets):
TV Show by Date presets create a TV show from a single URL using upload dates as season/episode TV Show by Date presets create a TV show from a single URL using upload dates as season/episode
numbers. numbers.
""" """
preset_names = {
kodi_tv_show_by_date = _ "kodi_tv_show_by_date",
jellyfin_tv_show_by_date = _ "jellyfin_tv_show_by_date",
plex_tv_show_by_date = _ "plex_tv_show_by_date",
}
class TvShowByDateEpisodeFormattingPresets(PrebuiltPresets): class TvShowByDateEpisodeFormattingPresets(PrebuiltPresets):
season_by_year__episode_by_month_day = _ preset_names = {
season_by_year__episode_by_month_day_reversed = _ "season_by_year__episode_by_month_day",
season_by_year_month__episode_by_day = _ "season_by_year__episode_by_month_day_reversed",
season_by_year__episode_by_download_index = _ "season_by_year_month__episode_by_day",
"season_by_year__episode_by_download_index",
}
class TvShowCollectionPresets(PrebuiltPresets): class TvShowCollectionPresets(PrebuiltPresets):
""" preset_names = {
Docstring for all TV SHOW URL presets "kodi_tv_show_collection",
""" "jellyfin_tv_show_collection",
"plex_tv_show_collection",
kodi_tv_show_collection = _ }
jellyfin_tv_show_collection = _
plex_tv_show_collection = _
class TvShowCollectionEpisodeFormattingPresets(PrebuiltPresets): class TvShowCollectionEpisodeFormattingPresets(PrebuiltPresets):
season_by_collection__episode_by_year_month_day = _ preset_names = {
season_by_collection__episode_by_year_month_day_reversed = _ "season_by_collection__episode_by_year_month_day",
season_by_collection__episode_by_playlist_index = _ "season_by_collection__episode_by_year_month_day_reversed",
season_by_collection__episode_by_playlist_index_reversed = _ "season_by_collection__episode_by_playlist_index",
"season_by_collection__episode_by_playlist_index_reversed",
}
class TvShowCollectionSeasonPresets(PrebuiltPresets): class TvShowCollectionSeasonPresets(PrebuiltPresets):
collection_season_1 = _ preset_names = {
collection_season_2 = _ "collection_season_1",
collection_season_3 = _ "collection_season_2",
collection_season_4 = _ "collection_season_3",
collection_season_5 = _ "collection_season_4",
"collection_season_5",
}

View file

@ -6,8 +6,8 @@ import pytest
from expected_download import assert_expected_downloads from expected_download import assert_expected_downloads
from expected_transaction_log import assert_transaction_log_matches from expected_transaction_log import assert_transaction_log_matches
from ytdl_sub.prebuilt_presets import TvShowByDatePresets from ytdl_sub.prebuilt_presets.tv_show import TvShowByDatePresets
from ytdl_sub.prebuilt_presets import TvShowCollectionPresets from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionPresets
from ytdl_sub.prebuilt_presets.tv_show import TvShowByDateEpisodeFormattingPresets from ytdl_sub.prebuilt_presets.tv_show import TvShowByDateEpisodeFormattingPresets
from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionEpisodeFormattingPresets from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionEpisodeFormattingPresets
from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionSeasonPresets from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionSeasonPresets
@ -15,9 +15,9 @@ from ytdl_sub.subscriptions.subscription import Subscription
from ytdl_sub.utils.exceptions import ValidationException from ytdl_sub.utils.exceptions import ValidationException
@pytest.mark.parametrize("media_player_preset", TvShowByDatePresets.get_preset_names()) @pytest.mark.parametrize("media_player_preset", TvShowByDatePresets.preset_names)
@pytest.mark.parametrize( @pytest.mark.parametrize(
"tv_show_structure_preset", TvShowByDateEpisodeFormattingPresets.get_preset_names() "tv_show_structure_preset", TvShowByDateEpisodeFormattingPresets.preset_names
) )
class TestPrebuiltTVShowPresets: class TestPrebuiltTVShowPresets:
def test_compilation( def test_compilation(
@ -179,12 +179,12 @@ class TestPrebuiltTVShowPresets:
) )
@pytest.mark.parametrize("media_player_preset", TvShowCollectionPresets.get_preset_names()) @pytest.mark.parametrize("media_player_preset", TvShowCollectionPresets.preset_names)
@pytest.mark.parametrize( @pytest.mark.parametrize(
"tv_show_structure_preset", TvShowCollectionEpisodeFormattingPresets.get_preset_names() "tv_show_structure_preset", TvShowCollectionEpisodeFormattingPresets.preset_names
) )
class TestPrebuiltTvShowCollectionPresets: class TestPrebuiltTvShowCollectionPresets:
@pytest.mark.parametrize("season_preset", TvShowCollectionSeasonPresets.get_preset_names()) @pytest.mark.parametrize("season_preset", TvShowCollectionSeasonPresets.preset_names)
def test_compilation( def test_compilation(
self, self,
config, config,
@ -208,7 +208,7 @@ class TestPrebuiltTvShowCollectionPresets:
}, },
) )
@pytest.mark.parametrize("season_preset", TvShowCollectionSeasonPresets.get_preset_names()) @pytest.mark.parametrize("season_preset", TvShowCollectionSeasonPresets.preset_names)
def test_compilation_errors_missing_one( def test_compilation_errors_missing_one(
self, self,
config, config,