[FEATURE] Music prebuilt presets
This commit is contained in:
parent
c149957b04
commit
d979465ff9
5 changed files with 198 additions and 57 deletions
|
|
@ -5,8 +5,6 @@ from typing import Set
|
|||
|
||||
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
|
||||
|
||||
|
||||
|
|
@ -27,3 +25,7 @@ PREBUILT_PRESET_NAMES: Set[str] = set(PREBUILT_PRESETS.keys())
|
|||
PUBLISHED_PRESET_NAMES: Set[str] = {
|
||||
name for name in PREBUILT_PRESET_NAMES if not name.startswith("_")
|
||||
}
|
||||
|
||||
|
||||
class PrebuiltPresets:
|
||||
preset_names: Set[str]
|
||||
|
|
|
|||
9
src/ytdl_sub/prebuilt_presets/music/__init__.py
Normal file
9
src/ytdl_sub/prebuilt_presets/music/__init__.py
Normal 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 = _
|
||||
147
src/ytdl_sub/prebuilt_presets/music/music.yaml
Normal file
147
src/ytdl_sub/prebuilt_presets/music/music.yaml
Normal 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}"
|
||||
|
|
@ -1,26 +1,4 @@
|
|||
from typing import Set
|
||||
|
||||
|
||||
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)
|
||||
)
|
||||
from ytdl_sub.prebuilt_presets import 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
|
||||
numbers.
|
||||
"""
|
||||
|
||||
kodi_tv_show_by_date = _
|
||||
jellyfin_tv_show_by_date = _
|
||||
plex_tv_show_by_date = _
|
||||
preset_names = {
|
||||
"kodi_tv_show_by_date",
|
||||
"jellyfin_tv_show_by_date",
|
||||
"plex_tv_show_by_date",
|
||||
}
|
||||
|
||||
|
||||
class TvShowByDateEpisodeFormattingPresets(PrebuiltPresets):
|
||||
season_by_year__episode_by_month_day = _
|
||||
season_by_year__episode_by_month_day_reversed = _
|
||||
season_by_year_month__episode_by_day = _
|
||||
season_by_year__episode_by_download_index = _
|
||||
preset_names = {
|
||||
"season_by_year__episode_by_month_day",
|
||||
"season_by_year__episode_by_month_day_reversed",
|
||||
"season_by_year_month__episode_by_day",
|
||||
"season_by_year__episode_by_download_index",
|
||||
}
|
||||
|
||||
|
||||
class TvShowCollectionPresets(PrebuiltPresets):
|
||||
"""
|
||||
Docstring for all TV SHOW URL presets
|
||||
"""
|
||||
|
||||
kodi_tv_show_collection = _
|
||||
jellyfin_tv_show_collection = _
|
||||
plex_tv_show_collection = _
|
||||
preset_names = {
|
||||
"kodi_tv_show_collection",
|
||||
"jellyfin_tv_show_collection",
|
||||
"plex_tv_show_collection",
|
||||
}
|
||||
|
||||
|
||||
class TvShowCollectionEpisodeFormattingPresets(PrebuiltPresets):
|
||||
season_by_collection__episode_by_year_month_day = _
|
||||
season_by_collection__episode_by_year_month_day_reversed = _
|
||||
season_by_collection__episode_by_playlist_index = _
|
||||
season_by_collection__episode_by_playlist_index_reversed = _
|
||||
preset_names = {
|
||||
"season_by_collection__episode_by_year_month_day",
|
||||
"season_by_collection__episode_by_year_month_day_reversed",
|
||||
"season_by_collection__episode_by_playlist_index",
|
||||
"season_by_collection__episode_by_playlist_index_reversed",
|
||||
}
|
||||
|
||||
|
||||
class TvShowCollectionSeasonPresets(PrebuiltPresets):
|
||||
collection_season_1 = _
|
||||
collection_season_2 = _
|
||||
collection_season_3 = _
|
||||
collection_season_4 = _
|
||||
collection_season_5 = _
|
||||
preset_names = {
|
||||
"collection_season_1",
|
||||
"collection_season_2",
|
||||
"collection_season_3",
|
||||
"collection_season_4",
|
||||
"collection_season_5",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import pytest
|
|||
from expected_download import assert_expected_downloads
|
||||
from expected_transaction_log import assert_transaction_log_matches
|
||||
|
||||
from ytdl_sub.prebuilt_presets import TvShowByDatePresets
|
||||
from ytdl_sub.prebuilt_presets import TvShowCollectionPresets
|
||||
from ytdl_sub.prebuilt_presets.tv_show import TvShowByDatePresets
|
||||
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 TvShowCollectionEpisodeFormattingPresets
|
||||
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
|
||||
|
||||
|
||||
@pytest.mark.parametrize("media_player_preset", TvShowByDatePresets.get_preset_names())
|
||||
@pytest.mark.parametrize("media_player_preset", TvShowByDatePresets.preset_names)
|
||||
@pytest.mark.parametrize(
|
||||
"tv_show_structure_preset", TvShowByDateEpisodeFormattingPresets.get_preset_names()
|
||||
"tv_show_structure_preset", TvShowByDateEpisodeFormattingPresets.preset_names
|
||||
)
|
||||
class TestPrebuiltTVShowPresets:
|
||||
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(
|
||||
"tv_show_structure_preset", TvShowCollectionEpisodeFormattingPresets.get_preset_names()
|
||||
"tv_show_structure_preset", TvShowCollectionEpisodeFormattingPresets.preset_names
|
||||
)
|
||||
class TestPrebuiltTvShowCollectionPresets:
|
||||
@pytest.mark.parametrize("season_preset", TvShowCollectionSeasonPresets.get_preset_names())
|
||||
@pytest.mark.parametrize("season_preset", TvShowCollectionSeasonPresets.preset_names)
|
||||
def test_compilation(
|
||||
self,
|
||||
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(
|
||||
self,
|
||||
config,
|
||||
|
|
|
|||
Loading…
Reference in a new issue