[FEATURE] Prebuilt music presets (#780)
Adds the following prebuilt presets: ``` "Single" "SoundCloud Discography" "YouTube Releases" "YouTube Full Albums" "Bandcamp" ``` which require no config.yaml to use. Usage examples can be found in the `/examples` directory
This commit is contained in:
parent
c149957b04
commit
ff857c84af
42 changed files with 1058 additions and 671 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -145,5 +145,7 @@ docker/testing/volumes
|
|||
|
||||
.local/
|
||||
|
||||
.ytdl-sub-working-directory
|
||||
|
||||
ffmpeg.exe
|
||||
ffprobe.exe
|
||||
ffprobe.exe
|
||||
|
|
|
|||
|
|
@ -1,194 +0,0 @@
|
|||
# This config builds presets to download and format the following use-cases:
|
||||
# - YouTube
|
||||
# - Songs
|
||||
# - From a single video
|
||||
# - Albums
|
||||
# - From a video, where each song is represented by chapters
|
||||
# - From a playlist where each video is a song on the album
|
||||
# - Discographies
|
||||
# - From a channel or a channel's set of playlists
|
||||
# - Bandcamp
|
||||
# - Track, Album, Artist URL as a Discography
|
||||
# - Soundcloud
|
||||
# - Track, Album, Artist URL as a Discography
|
||||
#
|
||||
# All files will look like:
|
||||
#
|
||||
# music_directory/
|
||||
# Artist/
|
||||
# [2022] Some Single/
|
||||
# 01 - Some Single.mp3
|
||||
# folder.jpg
|
||||
# [2023] Latest Album/
|
||||
# 01 - Track Title.mp3
|
||||
# 02 - Another Track.mp3
|
||||
# folder.jpg
|
||||
#
|
||||
# The idea is to format files under music_directory as `Artist/Album/Song`. Singles that do not
|
||||
# belong to an album will be represented like albums with a single track.
|
||||
#
|
||||
# Each file will be properly tagged regardless of file extension (suppers flac, ogg, mp3, etc)
|
||||
# and should show up nicely in music players that take advantage of tags.
|
||||
configuration:
|
||||
working_directory: '.ytdl-sub-downloads'
|
||||
umask: "002"
|
||||
|
||||
presets:
|
||||
|
||||
# The `base` preset that represents how all files will be structured after downloading.
|
||||
# Every other preset afterwards will inherit this preset.
|
||||
base:
|
||||
# Store all music under our music_directory (to be set as an override variable).
|
||||
# Store each resulting file with its full track path, and treat thumbnails as the album covers.
|
||||
#
|
||||
# Maintain a download archive. This will produce a hidden file in your music directory
|
||||
# containing an archive of all audio previously downloaded. This makes it so we do not
|
||||
# re-download files we already have.
|
||||
output_options:
|
||||
output_directory: "{music_directory}"
|
||||
file_name: "{track_full_path}"
|
||||
thumbnail_name: "{album_cover_path}"
|
||||
maintain_download_archive: True
|
||||
|
||||
# Set break_on_existing to True. This will stop fetching any more metadata once we
|
||||
# hit a video/audio that we already have downloaded.
|
||||
ytdl_options:
|
||||
break_on_existing: True
|
||||
|
||||
# Extract any audio from files using this codec and quality.
|
||||
audio_extract:
|
||||
codec: "mp3"
|
||||
quality: 320
|
||||
|
||||
# Set these music tags on every resulting audio file.
|
||||
# It is recommended to keep most of this as-is, and use override
|
||||
# variables to set them to be what you want.
|
||||
music_tags:
|
||||
artist: "{track_artist}"
|
||||
artists: "{track_artist}"
|
||||
albumartist: "{track_artist}"
|
||||
albumartists: "{track_artist}"
|
||||
title: "{track_title}"
|
||||
album: "{track_album}"
|
||||
track: "{track_number}"
|
||||
tracktotal: "{track_total}"
|
||||
year: "{track_year}"
|
||||
genre: "{track_genre}"
|
||||
|
||||
# Optionally embed the thumbnail into the track
|
||||
embed_thumbnail: False
|
||||
|
||||
# For every configurable field, make it an override variable,
|
||||
# so we can carefully tune different use-cases by only modifying override variables.
|
||||
overrides:
|
||||
# Track Overrides. By default, set overrides to make each song its own album
|
||||
track_title: "{title}"
|
||||
track_album: "{title}"
|
||||
track_artist: "{channel}"
|
||||
track_number: "1"
|
||||
track_number_padded: "01"
|
||||
track_total: "1"
|
||||
track_year: "{upload_year}"
|
||||
track_genre: "Unset"
|
||||
# Filename Overrides
|
||||
track_file_name: "{track_number_padded} - {track_title_sanitized}.{ext}"
|
||||
album_file_name: "folder.{thumbnail_ext}"
|
||||
# Directory Name Overrides
|
||||
music_directory: "OVERRIDE THIS WITH YOUR MUSIC DIRECTORY"
|
||||
artist_dir: "{track_artist_sanitized}"
|
||||
album_dir: "[{track_year}] {track_album_sanitized}"
|
||||
# Full Filepath Overrides
|
||||
track_full_path: "{artist_dir}/{album_dir}/{track_file_name}"
|
||||
album_cover_path: "{artist_dir}/{album_dir}/{album_file_name}"
|
||||
|
||||
####################################################################################################
|
||||
|
||||
# Make the 'single` preset accept a single URL using the override variable 'url'
|
||||
# Each audio file will reside in its own album.
|
||||
single:
|
||||
# Inherit from `base`
|
||||
preset: "base"
|
||||
|
||||
download:
|
||||
url: "{url}"
|
||||
|
||||
####################################################################################################
|
||||
|
||||
# Make the 'albums_from_playlists' preset format audio files to reside under albums, where
|
||||
# each album is a playlist. If a file downloaded using this preset is not part of a playlist,
|
||||
# it will default to how it'd look as a `single`.
|
||||
albums_from_playlists:
|
||||
# Inherit from single
|
||||
preset: "single"
|
||||
|
||||
# Override various track properties using playlist variables.
|
||||
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}"
|
||||
|
||||
####################################################################################################
|
||||
|
||||
# Make the 'albums_from_chapters' preset format audio files to reside under an album, where the
|
||||
# video itself is an album containing all the songs in it represented by chapters.
|
||||
albums_from_chapters:
|
||||
# Inherit from single
|
||||
preset: "single"
|
||||
|
||||
# Embed chapters if present. If no chapters are present, allow parsing comments that contain
|
||||
# timestamps to each song, and use those as chapters.
|
||||
chapters:
|
||||
embed_chapters: True
|
||||
allow_chapters_from_comments: True
|
||||
|
||||
# Split each file by its chapters. If a file does not have chapters, simply 'pass' on it and
|
||||
# process the next audio/video file.
|
||||
split_by_chapters:
|
||||
when_no_chapters: "pass"
|
||||
|
||||
# Override various track properties using chapter variables.
|
||||
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}"
|
||||
|
||||
####################################################################################################
|
||||
|
||||
# Make the 'soundcloud_discography' preset specially made for ripping SoundCloud artists.
|
||||
# We will use the 'multi_url' approach to download both albums and non-album tracks
|
||||
soundcloud_discography:
|
||||
preset: "base"
|
||||
|
||||
# Download using the multi_url strategy
|
||||
download:
|
||||
# The first URL will be all the artist's tracks.
|
||||
# Treat these as singles - an album with a single track
|
||||
- url: "{sc_artist_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: "{sc_artist_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}"
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
# Define any number of subscriptions in a single file, or use multiple
|
||||
# files to organize (i.e by use-case, website, genre, etc)
|
||||
#
|
||||
# Each example show-cases every use case:
|
||||
# - YouTube
|
||||
# - Songs
|
||||
# - From a single video
|
||||
# - Albums
|
||||
# - From a video, where each song is represented by chapters
|
||||
# - From a playlist where each video is a song on the album
|
||||
# - Discographies
|
||||
# - From a channel or a channel's set of playlists
|
||||
# - Bandcamp
|
||||
# - Track, Album, Artist URL as a Discography
|
||||
# - Soundcloud
|
||||
# - Track, Album, Artist URL as a Discography
|
||||
#
|
||||
####################################################################################################
|
||||
# YOUTUBE - PLAYLIST OF ALBUMS
|
||||
# See https://www.youtube.com/playlist?list=PLBsm_SagFMmdWnCnrNtLjA9kzfrRkto4i
|
||||
#
|
||||
# Downloads the GameChops Albums' playlist. Each video in the playlist is an album with
|
||||
# chapters representing songs.
|
||||
game_chops:
|
||||
preset: "albums_from_chapters"
|
||||
|
||||
# Perform regex to extract title from the chapter's title to not include the track number.
|
||||
# Configuring this hard is a bit overkill, but I'm a perfectionist :-)
|
||||
regex:
|
||||
from:
|
||||
chapter_title:
|
||||
match:
|
||||
- "^\\d+\\.\\.(.*)" # Captures 'title' from '1..title'
|
||||
capture_group_names:
|
||||
- "captured_track_title"
|
||||
capture_group_defaults:
|
||||
- "{chapter_title}"
|
||||
|
||||
# Explicitly set the URL, track artist, and genre.
|
||||
# Override various track properties using the regex variables we extracted.
|
||||
overrides:
|
||||
url: "https://www.youtube.com/playlist?list=PLBsm_SagFMmdWnCnrNtLjA9kzfrRkto4i"
|
||||
track_artist: "GameChops"
|
||||
track_genre: "Lofi"
|
||||
track_title: "{captured_track_title}"
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# YOUTUBE - MANY ALBUMS FROM MANY ARTISTS UPLOADED BY A CHANNEL
|
||||
# See https://www.youtube.com/@heavymetalofeasternbloc
|
||||
#
|
||||
# Downloads the entire 'Heavy Metal from the Eastern Bloc' channel. Each video they upload
|
||||
# is an album from Eastern Europe with chapters representing songs.
|
||||
eastern_bloc:
|
||||
# Inherit albums from chapters
|
||||
preset: "albums_from_chapters"
|
||||
|
||||
# Perform regex on many fields (title, description, chapter title) to extract as much
|
||||
# metadata as possible
|
||||
regex:
|
||||
skip_if_match_fails: False # Error if regex match fails
|
||||
from:
|
||||
title:
|
||||
match:
|
||||
- "^(.*) - (.*) \\|\\|.*" # Captures artist, album from 'artist - album ||...'
|
||||
- "^(.*) - (.*) \\[.*" # Captures artist, ablum from 'artist - album [...'
|
||||
- "^(.*) - (.*)" # Captures artist, ablum from 'artist - album'
|
||||
capture_group_names:
|
||||
- "captured_track_artist"
|
||||
- "captured_track_album"
|
||||
description:
|
||||
match:
|
||||
- "Genre:\\s*(.*)\\s*\n(?:Rec.+|Year):\\s*.*(\\d{4})\\s*\\n" # Captures genre and recorded year
|
||||
capture_group_names:
|
||||
- "captured_track_genre"
|
||||
- "captured_track_year"
|
||||
chapter_title:
|
||||
match:
|
||||
- "^(?:\\d+\\.\\s*|)(.*)" # Captures title from '1. title'
|
||||
capture_group_names:
|
||||
- "captured_track_title"
|
||||
capture_group_defaults:
|
||||
- "{chapter_title}"
|
||||
|
||||
# Explicitly set the URL.
|
||||
# Override various track properties using the regex variables we extracted.
|
||||
overrides:
|
||||
url: "https://www.youtube.com/@heavymetalofeasternbloc"
|
||||
track_artist: "{captured_track_artist}"
|
||||
track_album: "{captured_track_album}"
|
||||
track_title: "{captured_track_title}"
|
||||
track_year: "{captured_track_year}"
|
||||
track_genre: "Eastern Bloc {captured_track_genre}"
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# BANDCAMP - DISCOGRAPHY
|
||||
# See https://emilyharpist.bandcamp.com/
|
||||
#
|
||||
# Downloads Emily's entire bandcamp discography. yt-dlp represents albums as playlist.
|
||||
emily_hopkins:
|
||||
preset: "albums_from_playlists"
|
||||
regex:
|
||||
from:
|
||||
title:
|
||||
match:
|
||||
- "^Emily Hopkins - (.*)" # Captures 'title' from 'Emily Hopkins - title'
|
||||
capture_group_names:
|
||||
- "captured_track_title"
|
||||
capture_group_defaults:
|
||||
- "{title}"
|
||||
|
||||
# Explicitly set the URL, track artist, and genre.
|
||||
# Override various track properties using the regex variables we extracted.
|
||||
overrides:
|
||||
url: "https://emilyharpist.bandcamp.com/"
|
||||
track_artist: "Emily Hopkins"
|
||||
track_genre: "Lofi"
|
||||
track_title: "{captured_track_title}"
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# SOUNDCLOUD - DISCOGRAPHY
|
||||
# See https://soundcloud.com/jessebannon
|
||||
#
|
||||
# Downloads my acoustic 'album' and various tracks from SoundCloud using the soundcloud
|
||||
# discography preset. I'm not very good so keep your expectations low :-)
|
||||
jmbannon:
|
||||
# Inherit soundcloud_discography preset
|
||||
preset: "soundcloud_discography"
|
||||
|
||||
# Explicitly set the SoundCloud artist url, track artist, and genre.
|
||||
overrides:
|
||||
sc_artist_url: "sc_artist_url"
|
||||
track_artist: "jmbannon"
|
||||
track_genre: "Acoustic"
|
||||
|
||||
52
examples/music_subscriptions.yaml
Normal file
52
examples/music_subscriptions.yaml
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# Files will be stored in the form of:
|
||||
#
|
||||
# music_directory/
|
||||
# Artist/
|
||||
# [2022] Some Single/
|
||||
# 01 - Some Single.mp3
|
||||
# folder.jpg
|
||||
# [2023] Latest Album/
|
||||
# 01 - Track Title.mp3
|
||||
# 02 - Another Track.mp3
|
||||
# folder.jpg
|
||||
|
||||
# Overrides to the prebuilt presets
|
||||
__preset__:
|
||||
overrides:
|
||||
music_directory: "/music"
|
||||
|
||||
# Supports downloading YouTube /releases tab. Also works for any playlist (or playlist of playlists)
|
||||
# where each video is a single track.
|
||||
YouTube Releases:
|
||||
= Jazz: # Sets genre tag to "Jazz"
|
||||
"Lester Young": "https://www.youtube.com/channel/UCsItMF6_fP754ihIsSRLk5A/playlists"
|
||||
"Thelonious Monk": "https://www.youtube.com/@theloniousmonk3870/releases"
|
||||
"Stan Getz": "https://www.youtube.com/@stangetzofficial/releases"
|
||||
"Art Blakey": "https://www.youtube.com/channel/UCMki-b0zfAQiMQ0nbsrIuBQ/playlists"
|
||||
|
||||
# Supports downloading playlists or individual videos where a single video is a full album.
|
||||
# ytdl-sub will split the album based on video chapters, and make each chapter a track.
|
||||
YouTube Full Albums:
|
||||
= Lofi:
|
||||
"Game Chops": "https://www.youtube.com/playlist?list=PLBsm_SagFMmdWnCnrNtLjA9kzfrRkto4i"
|
||||
|
||||
# Supports downloading a SoundCloud's artists albums + singles. Be sure to not include
|
||||
# any extension after the SoundCloud artist's name in the URL.
|
||||
SoundCloud Discography:
|
||||
= Chill Hop:
|
||||
"UKNOWY": "https://soundcloud.com/uknowymunich"
|
||||
= Electronic:
|
||||
"Italo Brutalo": "https://soundcloud.com/italobrutalo"
|
||||
"SURVIVE": "https://soundcloud.com/s-u-r-v-i-v-e"
|
||||
"French79": "https://soundcloud.com/french79music"
|
||||
"VHS Dreams": "https://soundcloud.com/vhsdreamsofficial"
|
||||
= Synthwave:
|
||||
"Lazerdiscs Records": "https://soundcloud.com/lazerdiscsrecords"
|
||||
"Earmake": "https://soundcloud.com/earmake"
|
||||
"Poly Poly": "https://soundcloud.com/poly_poly"
|
||||
|
||||
# Supports downloading a Bandcamp artist
|
||||
Bandcamp:
|
||||
= Lofi:
|
||||
"Emily Hopkins": "https://emilyharpist.bandcamp.com/"
|
||||
|
||||
|
|
@ -22,15 +22,3 @@ TV Show Full Archive:
|
|||
TV Show Only Recent:
|
||||
= News | TV-14:
|
||||
"BBC": "https://www.youtube.com/@BBCNews"
|
||||
|
||||
|
||||
# ADVANCED USAGE:
|
||||
# Subscriptions can use the same format as a preset found within a config.
|
||||
"Equivalent to BBC":
|
||||
preset:
|
||||
- "TV Show Only Recent"
|
||||
overrides:
|
||||
tv_show_name: "BBC"
|
||||
url: "https://www.youtube.com/@BBCNews"
|
||||
tv_show_genre: "News"
|
||||
tv_show_content_rating: "TV-14"
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ def main() -> List[Subscription]:
|
|||
config = ConfigFile.from_file_path(DEFAULT_CONFIG_FILE_NAME)
|
||||
else:
|
||||
logger.info("No config specified, using defaults.")
|
||||
config = ConfigFile(name="default_config", value={})
|
||||
config = ConfigFile.default()
|
||||
|
||||
subscriptions: List[Subscription] = []
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,15 @@ class ConfigFile(ConfigValidator):
|
|||
|
||||
return ConfigFile.from_dict(name=config_path, config_dict=config_dict)
|
||||
|
||||
@classmethod
|
||||
def default(cls) -> "ConfigFile":
|
||||
"""
|
||||
Returns
|
||||
-------
|
||||
Config initialized with all defaults
|
||||
"""
|
||||
return ConfigFile(name="default_config", value={})
|
||||
|
||||
def as_dict(self) -> Dict[str, Any]:
|
||||
"""
|
||||
Returns
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
11
src/ytdl_sub/prebuilt_presets/music/__init__.py
Normal file
11
src/ytdl_sub/prebuilt_presets/music/__init__.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
from ytdl_sub.prebuilt_presets import PrebuiltPresets
|
||||
|
||||
|
||||
class MusicPresets(PrebuiltPresets):
|
||||
preset_names = {
|
||||
"Single",
|
||||
"SoundCloud Discography",
|
||||
"YouTube Releases",
|
||||
"YouTube Full Albums",
|
||||
"Bandcamp",
|
||||
}
|
||||
150
src/ytdl_sub/prebuilt_presets/music/music.yaml
Normal file
150
src/ytdl_sub/prebuilt_presets/music/music.yaml
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
presets:
|
||||
|
||||
_music_base:
|
||||
output_options:
|
||||
output_directory: "{music_directory}"
|
||||
file_name: "{track_full_path}"
|
||||
thumbnail_name: "{album_cover_path}"
|
||||
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: "{title}"
|
||||
track_artist: "{subscription_name}"
|
||||
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"
|
||||
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"
|
||||
|
||||
"YouTube Full Albums":
|
||||
preset:
|
||||
- "_albums_from_chapters"
|
||||
|
||||
"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):
|
||||
|
|
@ -29,38 +7,44 @@ class TvShowByDatePresets(PrebuiltPresets):
|
|||
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",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,6 +186,9 @@ def tv_show_subscriptions_path() -> Path:
|
|||
|
||||
@pytest.fixture()
|
||||
def music_audio_config(working_directory) -> ConfigFile:
|
||||
return _load_config(
|
||||
config_path=Path("examples/music_audio_config.yaml"), working_directory=working_directory
|
||||
)
|
||||
return ConfigFile.from_dict({"configuration": {"working_directory": working_directory}})
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def music_subscriptions_path() -> Path:
|
||||
return Path("examples/music_subscriptions.yaml")
|
||||
|
|
|
|||
|
|
@ -10,27 +10,15 @@ from ytdl_sub.subscriptions.subscription import Subscription
|
|||
@pytest.fixture
|
||||
def subscription_dict(output_directory):
|
||||
return {
|
||||
"preset": "albums_from_playlists",
|
||||
"regex": {
|
||||
"skip_if_match_fails": False, # Error if regex match fails
|
||||
"from": {
|
||||
"title": {
|
||||
"match": ["^(.*) - (.*)"], # Captures 'title' from 'Emily Hopkins - title'
|
||||
"capture_group_names": [
|
||||
"captured_track_artist",
|
||||
"captured_track_title",
|
||||
],
|
||||
}
|
||||
},
|
||||
},
|
||||
"preset": "Bandcamp",
|
||||
"ytdl_options": {
|
||||
"max_downloads": 15,
|
||||
},
|
||||
"date_range": {"before": "20230101"},
|
||||
"audio_extract": {"codec": "mp3", "quality": 320},
|
||||
"date_range": {"after": "20210110"},
|
||||
"overrides": {
|
||||
"url": "https://funkypselicave.bandcamp.com/",
|
||||
"track_title": "{captured_track_title}",
|
||||
"track_artist": "{captured_track_artist}",
|
||||
"subscription_value": "https://sithuayemusic.bandcamp.com/",
|
||||
"subscription_indent_1": "Progressive Metal",
|
||||
"music_directory": output_directory,
|
||||
},
|
||||
}
|
||||
|
|
@ -38,7 +26,7 @@ def subscription_dict(output_directory):
|
|||
|
||||
class TestBandcamp:
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_download_artist_url(
|
||||
def test_prebuilt_preset_download(
|
||||
self,
|
||||
subscription_dict,
|
||||
music_audio_config,
|
||||
|
|
@ -47,7 +35,7 @@ class TestBandcamp:
|
|||
):
|
||||
discography_subscription = Subscription.from_dict(
|
||||
preset_dict=subscription_dict,
|
||||
preset_name="jb",
|
||||
preset_name="Sithu Aye",
|
||||
config=music_audio_config,
|
||||
)
|
||||
transaction_log = discography_subscription.download(dry_run=dry_run)
|
||||
|
|
|
|||
|
|
@ -6,16 +6,18 @@ from ytdl_sub.subscriptions.subscription import Subscription
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def single_song_preset_dict_old_format(output_directory):
|
||||
def single_preset_dict_old_format(output_directory):
|
||||
return {
|
||||
"preset": "single",
|
||||
"preset": "Single",
|
||||
# test multi-tags
|
||||
"music_tags": {"embed_thumbnail": True, "tags": {"genres": ["multi_tag_1", "multi_tag_2"]}},
|
||||
"format": "worst[ext=mp4]", # download the worst format so it is fast
|
||||
"format": "worst[ext=mp4]",
|
||||
"audio_extract": {"codec": "mp3", "quality": 320},
|
||||
"ytdl_options": {
|
||||
"postprocessor_args": {"ffmpeg": ["-bitexact"]}, # Must add this for reproducibility
|
||||
},
|
||||
"overrides": {
|
||||
"track_artist": "YouTube",
|
||||
"url": "https://www.youtube.com/watch?v=2lAe1cqCOXo",
|
||||
"music_directory": output_directory,
|
||||
},
|
||||
|
|
@ -23,18 +25,20 @@ def single_song_preset_dict_old_format(output_directory):
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def single_song_preset_dict(output_directory):
|
||||
def single_preset_dict(output_directory):
|
||||
return {
|
||||
"preset": "single",
|
||||
"preset": "Single",
|
||||
# test multi-tags
|
||||
"music_tags": {"genres": ["multi_tag_1", "multi_tag_2"]},
|
||||
# test the new embed_thumbnail plugin
|
||||
"embed_thumbnail": True,
|
||||
"format": "worst[ext=mp4]", # download the worst format so it is fast
|
||||
"format": "worst[ext=mp4]",
|
||||
"audio_extract": {"codec": "mp3", "quality": 320},
|
||||
"ytdl_options": {
|
||||
"postprocessor_args": {"ffmpeg": ["-bitexact"]}, # Must add this for reproducibility
|
||||
},
|
||||
"overrides": {
|
||||
"track_artist": "YouTube",
|
||||
"url": "https://www.youtube.com/watch?v=2lAe1cqCOXo",
|
||||
"music_directory": output_directory,
|
||||
},
|
||||
|
|
@ -42,20 +46,21 @@ def single_song_preset_dict(output_directory):
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def single_song_best_format_preset_dict(single_song_preset_dict):
|
||||
return dict(single_song_preset_dict, **{"audio_extract": {"codec": "best"}})
|
||||
def single_best_format_preset_dict(single_preset_dict):
|
||||
return dict(single_preset_dict, **{"audio_extract": {"codec": "best"}})
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def multiple_songs_preset_dict(output_directory):
|
||||
def youtube_release_preset_dict(output_directory):
|
||||
return {
|
||||
"preset": "albums_from_playlists",
|
||||
"preset": "YouTube Releases",
|
||||
"audio_extract": {"codec": "vorbis", "quality": 140},
|
||||
"format": "worst[ext=mp4]", # download the worst format so it is fast
|
||||
"ytdl_options": {
|
||||
"postprocessor_args": {"ffmpeg": ["-bitexact"]}, # Must add this for reproducibility
|
||||
},
|
||||
"overrides": {
|
||||
"track_artist": "Project Zombie",
|
||||
"url": "https://youtube.com/playlist?list=PL5BC0FC26BECA5A35",
|
||||
"music_directory": output_directory,
|
||||
},
|
||||
|
|
@ -67,14 +72,14 @@ class TestAudioExtract:
|
|||
def test_audio_extract_single_song_old_format(
|
||||
self,
|
||||
music_audio_config,
|
||||
single_song_preset_dict_old_format,
|
||||
single_preset_dict_old_format,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
subscription = Subscription.from_dict(
|
||||
config=music_audio_config,
|
||||
preset_name="single_song_test",
|
||||
preset_dict=single_song_preset_dict_old_format,
|
||||
preset_dict=single_preset_dict_old_format,
|
||||
)
|
||||
|
||||
transaction_log = subscription.download(dry_run=dry_run)
|
||||
|
|
@ -93,14 +98,14 @@ class TestAudioExtract:
|
|||
def test_audio_extract_single_song(
|
||||
self,
|
||||
music_audio_config,
|
||||
single_song_preset_dict,
|
||||
single_preset_dict,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
subscription = Subscription.from_dict(
|
||||
config=music_audio_config,
|
||||
preset_name="single_song_test",
|
||||
preset_dict=single_song_preset_dict,
|
||||
preset_dict=single_preset_dict,
|
||||
)
|
||||
|
||||
transaction_log = subscription.download(dry_run=dry_run)
|
||||
|
|
@ -119,14 +124,14 @@ class TestAudioExtract:
|
|||
def test_audio_extract_single_song_best_format(
|
||||
self,
|
||||
music_audio_config,
|
||||
single_song_best_format_preset_dict,
|
||||
single_best_format_preset_dict,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
subscription = Subscription.from_dict(
|
||||
config=music_audio_config,
|
||||
preset_name="single_song_best_test",
|
||||
preset_dict=single_song_best_format_preset_dict,
|
||||
preset_dict=single_best_format_preset_dict,
|
||||
)
|
||||
|
||||
transaction_log = subscription.download(dry_run=dry_run)
|
||||
|
|
@ -145,14 +150,14 @@ class TestAudioExtract:
|
|||
def test_audio_extract_multiple_songs(
|
||||
self,
|
||||
music_audio_config,
|
||||
multiple_songs_preset_dict,
|
||||
youtube_release_preset_dict,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
subscription = Subscription.from_dict(
|
||||
config=music_audio_config,
|
||||
preset_name="multiple_songs_test",
|
||||
preset_dict=multiple_songs_preset_dict,
|
||||
preset_dict=youtube_release_preset_dict,
|
||||
)
|
||||
|
||||
transaction_log = subscription.download(dry_run=dry_run)
|
||||
|
|
|
|||
|
|
@ -12,13 +12,14 @@ from ytdl_sub.utils.exceptions import ValidationException
|
|||
@pytest.fixture
|
||||
def yt_album_as_chapters_preset_dict(output_directory):
|
||||
return {
|
||||
"preset": "albums_from_chapters",
|
||||
"format": "worst[ext=mp4]", # download the worst format so it is fast
|
||||
"preset": "YouTube Full Albums",
|
||||
"format": "worst[ext=mp4]",
|
||||
"audio_extract": {"codec": "mp3", "quality": 320},
|
||||
"ytdl_options": {
|
||||
"postprocessor_args": {"ffmpeg": ["-bitexact"]}, # Must add this for reproducibility
|
||||
},
|
||||
"overrides": {
|
||||
"url": "https://www.youtube.com/watch?v=zeR2_YjlXWA",
|
||||
"subscription_value": "https://www.youtube.com/watch?v=zeR2_YjlXWA",
|
||||
"music_directory": output_directory,
|
||||
},
|
||||
}
|
||||
|
|
@ -76,7 +77,7 @@ class TestSplitByChapters:
|
|||
):
|
||||
subscription = Subscription.from_dict(
|
||||
config=music_audio_config,
|
||||
preset_name="split_by_chapters_video",
|
||||
preset_name="Proved Records",
|
||||
preset_dict=yt_album_as_chapters_preset_dict,
|
||||
)
|
||||
|
||||
|
|
@ -106,7 +107,7 @@ class TestSplitByChapters:
|
|||
):
|
||||
subscription = Subscription.from_dict(
|
||||
config=music_audio_config,
|
||||
preset_name="split_by_chapters_with_regex_video",
|
||||
preset_name="split_by_chapters_with_regex_video_preset",
|
||||
preset_dict=yt_album_as_chapters_with_regex_preset_dict,
|
||||
)
|
||||
|
||||
|
|
@ -142,7 +143,7 @@ class TestSplitByChapters:
|
|||
|
||||
subscription = Subscription.from_dict(
|
||||
config=music_audio_config,
|
||||
preset_name="split_by_chapters_with_regex_video",
|
||||
preset_name="split_by_chapters_with_regex_video_no_chapters",
|
||||
preset_dict=yt_album_as_chapters_with_regex_preset_dict,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ from ytdl_sub.subscriptions.subscription import Subscription
|
|||
@pytest.fixture
|
||||
def subscription_dict(output_directory):
|
||||
return {
|
||||
"preset": "soundcloud_discography",
|
||||
"format": "worst[ext=mp3]", # download the worst format so it is fast
|
||||
"preset": "SoundCloud Discography",
|
||||
"audio_extract": {"codec": "mp3", "quality": 320},
|
||||
"overrides": {
|
||||
"track_artist": "j_b",
|
||||
"sc_artist_url": "https://soundcloud.com/jessebannon",
|
||||
"subscription_value": "https://soundcloud.com/jessebannon",
|
||||
"subscription_indent_1": "Acoustic",
|
||||
"music_directory": output_directory,
|
||||
},
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ class TestSoundcloudDiscography:
|
|||
):
|
||||
discography_subscription = Subscription.from_dict(
|
||||
preset_dict=subscription_dict,
|
||||
preset_name="jb",
|
||||
preset_name="j_b",
|
||||
config=music_audio_config,
|
||||
)
|
||||
transaction_log = discography_subscription.download(dry_run=dry_run)
|
||||
|
|
|
|||
|
|
@ -1,19 +1,20 @@
|
|||
{
|
||||
".ytdl-sub-jb-download-archive.json": "9f5ca17dc0d842ac4c296054c0011ace",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/01 - Spark it.mp3": "f1fcc87884ced84be016391e3989b5c1",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/02 - Astronomikal Funk.mp3": "d07701404b8ddaa2e38eb51f7e2ac2d8",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/03 - Impulse.mp3": "43118db203e1d9427036102cfb39a1e3",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/04 - September.mp3": "3d75c5068e3dbb93dd86fc650c7ca84d",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/05 - Interlune.mp3": "63897d8af920f31af2183a17bc697c11",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/06 - Ninjutsu Techniques.mp3": "a500409583ee30e4cb68d64af2b32596",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/07 - Space Funk Flow.mp3": "1e1a12a5a42a607abf342ec4f301f471",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/08 - Cellar Groove.mp3": "a18ceff8785e8849d166eb2710caafa4",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/09 - Solar Wind.mp3": "a41665337e3fe05d7c7d9d8e6ddde737",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/10 - Interlune II.mp3": "8d2f3158ac9bac51aafbdbe6eb43154b",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/11 - Ghetto Anthem.mp3": "39085bae1b0f8544acd08f74f88cacfd",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/12 - Street Degree.mp3": "561f0d8fbc62f87f2149c17ee0a53ce2",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/13 - Trouble World.mp3": "1ad07dc6a2d6ced78449bc46a2909335",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/14 - Relaxation.mp3": "ba8addb0d59f26a84bbb79a6cdd1af11",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/15 - Journey From Within.mp3": "bd97135290482c6bbe6eac7d3a700f11",
|
||||
"El Jazzy Chavo/[2022] S950 Funk/folder.jpg": "62e51365dd309e76a6323f927f6fcc94"
|
||||
".ytdl-sub-Sithu Aye-download-archive.json": "0c58919b660f699f6aea2ec523c812c5",
|
||||
"Sithu Aye/[2021] 10 Years: Remixes and Reimaginings/01 - Double Helix Reimagined.mp3": "a627cfc0964be6a7e668fd8289326140",
|
||||
"Sithu Aye/[2021] 10 Years: Remixes and Reimaginings/02 - Skye Reimagined.mp3": "94127e3d82f5d33d920b82f90d4f9657",
|
||||
"Sithu Aye/[2021] 10 Years: Remixes and Reimaginings/03 - Baryofusion.mp3": "dcf4b30e3fdeb29154b3888838986c1e",
|
||||
"Sithu Aye/[2021] 10 Years: Remixes and Reimaginings/04 - Mandalay Reimagined.mp3": "8304b012a8a8306c80e3f7f7cb0f35e7",
|
||||
"Sithu Aye/[2021] 10 Years: Remixes and Reimaginings/05 - Messenger EDM Remix.mp3": "0a7e4c613a055e571142182717fc684e",
|
||||
"Sithu Aye/[2021] 10 Years: Remixes and Reimaginings/folder.jpg": "bf6f70d51557a71b69fed85b2cb476f0",
|
||||
"Sithu Aye/[2022] Re:Invent the Universe (10th Anniversary Remaster)/01 - Invent the Universe.mp3": "d723a2e1f2ec75b3d20f1a0de616a191",
|
||||
"Sithu Aye/[2022] Re:Invent the Universe (10th Anniversary Remaster)/02 - Grand Unification (feat. David Maxim Micic).mp3": "0e550ebe93f8b5349eb07c7554ad22d9",
|
||||
"Sithu Aye/[2022] Re:Invent the Universe (10th Anniversary Remaster)/03 - Expansion.mp3": "6324f012f09a2e7028ca923fdff3a89a",
|
||||
"Sithu Aye/[2022] Re:Invent the Universe (10th Anniversary Remaster)/04 - Baryogenesis.mp3": "d30de9d811f56c2179fd86c6bede2fc5",
|
||||
"Sithu Aye/[2022] Re:Invent the Universe (10th Anniversary Remaster)/05 - Particles Collide (feat. Plini).mp3": "f869f1948b376f2ad98381b0c77d447f",
|
||||
"Sithu Aye/[2022] Re:Invent the Universe (10th Anniversary Remaster)/06 - Nucleosynthesis.mp3": "23d6ceb9865d6d6030d8659a2eed5698",
|
||||
"Sithu Aye/[2022] Re:Invent the Universe (10th Anniversary Remaster)/07 - Recombination.mp3": "4ae97dc8457e48fa7aad9a64b927bf1d",
|
||||
"Sithu Aye/[2022] Re:Invent the Universe (10th Anniversary Remaster)/08 - Dark Ages.mp3": "922e8a54e3e543bbf9b866e2f4a53607",
|
||||
"Sithu Aye/[2022] Re:Invent the Universe (10th Anniversary Remaster)/09 - Formation.mp3": "fd7ce4553df5323355bc95e6528e1515",
|
||||
"Sithu Aye/[2022] Re:Invent the Universe (10th Anniversary Remaster)/10 - Pale Blue Dot.mp3": "6328960f01a118d84fa1f1ab3565bf90",
|
||||
"Sithu Aye/[2022] Re:Invent the Universe (10th Anniversary Remaster)/folder.jpg": "d8cffeca026afaa619f641a95143f803"
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
".ytdl-sub-split_by_chapters_video-download-archive.json": "c3fb0b4f31caaa10ac7954ea93da33c4",
|
||||
".ytdl-sub-Proved Records-download-archive.json": "c3fb0b4f31caaa10ac7954ea93da33c4",
|
||||
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/01 - 01. Intro (Feat. Racheal Ofori & Barney Artist).mp3": "8827ac62201abeb94f44a46d91628aa8",
|
||||
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/02 - 02. Answers (Feat. Rick David & Kaya Thomas - Dyke).mp3": "f17e02119bf073c4ed98da2a960b85d3",
|
||||
"Proved Records/[2017] Alfa Mist - Nocturne [Full Album]/03 - 03. Blaze (Feat. Kaya Thomas - Dyke).mp3": "63c0bc97cbdaf35203011378b1860418",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
".ytdl-sub-split_by_chapters_with_regex_video-download-archive.json": "4008e43668447f1a3a6a55520a6ff475",
|
||||
".ytdl-sub-split_by_chapters_with_regex_video_no_chapters-download-archive.json": "4008e43668447f1a3a6a55520a6ff475",
|
||||
"Project Zombie/[2010] Oblivion Mod "Falcor" p.1/01 - Oblivion Mod "Falcor" p.1.mp3": "8fc765ce55304814942c1f38fe9e38e2",
|
||||
"Project Zombie/[2010] Oblivion Mod "Falcor" p.1/folder.jpg": "fb95b510681676e81c321171fc23143e"
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
".ytdl-sub-split_by_chapters_with_regex_video-download-archive.json": "9798e8289742586d0efd295a97c6c906",
|
||||
".ytdl-sub-split_by_chapters_with_regex_video_preset-download-archive.json": "9798e8289742586d0efd295a97c6c906",
|
||||
"Alfa Mist/[2017] Nocturne/01 - Intro (Feat. Racheal Ofori & Barney Artist).mp3": "c10cff170976c3c5139f6073eeb3e25e",
|
||||
"Alfa Mist/[2017] Nocturne/02 - Answers (Feat. Rick David & Kaya Thomas - Dyke).mp3": "881ecdbee4a0d565c0ec6eacf03115df",
|
||||
"Alfa Mist/[2017] Nocturne/03 - Blaze (Feat. Kaya Thomas - Dyke).mp3": "aa5c6fbab58dd2be2660bfb65be6a172",
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
{
|
||||
".ytdl-sub-jb-download-archive.json": "1a99156e9ece62539fb2608416a07200",
|
||||
"j_b/[2021] Baby Santana's Dorian Groove/01 - Baby Santana's Dorian Groove.mp3": "317a9ee75431d6020e3cad0883c7392f",
|
||||
".ytdl-sub-j_b-download-archive.json": "1a99156e9ece62539fb2608416a07200",
|
||||
"j_b/[2021] Baby Santana's Dorian Groove/01 - Baby Santana's Dorian Groove.mp3": "6325a6b14684f9df2d482ce27ff4d455",
|
||||
"j_b/[2021] Baby Santana's Dorian Groove/folder.jpg": "967892be44b8c47e1be73f055a7c6f08",
|
||||
"j_b/[2021] Purple Clouds/01 - Purple Clouds.mp3": "4a5971c12ca6fdc335b0185a14e829f2",
|
||||
"j_b/[2021] Purple Clouds/01 - Purple Clouds.mp3": "d7ece3072374c7cf88f44ba03a27bd26",
|
||||
"j_b/[2021] Purple Clouds/folder.jpg": "967892be44b8c47e1be73f055a7c6f08",
|
||||
"j_b/[2022] Acoustic Treats/01 - 20160426 184214.mp3": "bcc88eb579311b59ede4c13cdf24bcb9",
|
||||
"j_b/[2022] Acoustic Treats/02 - 20160502 123150.mp3": "239d10c17047662c760cce834548d91d",
|
||||
"j_b/[2022] Acoustic Treats/03 - 20160504 143832.mp3": "2d6e977e3e665012fdeaa0e8c2ee7375",
|
||||
"j_b/[2022] Acoustic Treats/04 - 20160601 221234.mp3": "9da5b26fc231dfd0c8f09a2a3d2fe116",
|
||||
"j_b/[2022] Acoustic Treats/05 - 20160601 222440.mp3": "8fb1cb262175921dbdddd6783664fa65",
|
||||
"j_b/[2022] Acoustic Treats/06 - 20170604 190236.mp3": "529846e26a18be616deb3f12d858b8ea",
|
||||
"j_b/[2022] Acoustic Treats/07 - 20170612 193646.mp3": "ba2be1ace7b0c31964bf0b8b15781b27",
|
||||
"j_b/[2022] Acoustic Treats/08 - 20170628 215206.mp3": "ad248c0392ced4f6d548a4852fd99f1f",
|
||||
"j_b/[2022] Acoustic Treats/09 - Finding Home.mp3": "52326cbd96e6f243cae77b0f68f00ef6",
|
||||
"j_b/[2022] Acoustic Treats/10 - Shallow Water WIP.mp3": "a265ed7e4d3a014d09e79ac5f4fe3fc7",
|
||||
"j_b/[2022] Acoustic Treats/11 - Untold History.mp3": "94d548773dded0089e73b26e6f923d9a",
|
||||
"j_b/[2022] Acoustic Treats/01 - 20160426 184214.mp3": "2a0232454e2ef2a12e74496d3389f1ca",
|
||||
"j_b/[2022] Acoustic Treats/02 - 20160502 123150.mp3": "cd4276f72de542b03d6e193352565603",
|
||||
"j_b/[2022] Acoustic Treats/03 - 20160504 143832.mp3": "80d9152600faca9d0dc8dee41a028cf8",
|
||||
"j_b/[2022] Acoustic Treats/04 - 20160601 221234.mp3": "2ee3c7f489ffc961e6ebc8d2ab4af000",
|
||||
"j_b/[2022] Acoustic Treats/05 - 20160601 222440.mp3": "0aeb9c6165ecdaa993de4d7958ae9b5f",
|
||||
"j_b/[2022] Acoustic Treats/06 - 20170604 190236.mp3": "eeb122552f13533a647828435dcac99e",
|
||||
"j_b/[2022] Acoustic Treats/07 - 20170612 193646.mp3": "1c387d318152e3783c06fbe040c4abf0",
|
||||
"j_b/[2022] Acoustic Treats/08 - 20170628 215206.mp3": "97a5689681217fb6da82f21953f63ffb",
|
||||
"j_b/[2022] Acoustic Treats/09 - Finding Home.mp3": "5440e42341549d2ade910ef44baf44d4",
|
||||
"j_b/[2022] Acoustic Treats/10 - Shallow Water WIP.mp3": "4029bdf1d78995aa6a961fd2ea671f41",
|
||||
"j_b/[2022] Acoustic Treats/11 - Untold History.mp3": "3687b16d0cefde103f80b76ba8490632",
|
||||
"j_b/[2022] Acoustic Treats/folder.jpg": "967892be44b8c47e1be73f055a7c6f08"
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
".ytdl-sub-subscription_test-download-archive.json": "36b3c7143ac4257489791309d802af82",
|
||||
"subscription_test/[2020] Download First/02 - Mock Entry 20-1.mp3": "7b0ff394bc1fbb8419735914692cb2e4",
|
||||
"subscription_test/[2020] Download First/03 - Mock Entry 20-2.mp3": "e3b5de70c625eb55d0eb7cacf0429fa5",
|
||||
"subscription_test/[2020] Download First/04 - Mock Entry 20-3.mp3": "31fd8d0d38139aafb74ec94ba34a53dc",
|
||||
"subscription_test/[2020] Download First/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"subscription_test/[2021] Download First/01 - Mock Entry 21-1.mp3": "3459b2735afa7e41a32c34198e780a5e",
|
||||
"subscription_test/[2021] Download First/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7"
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
".ytdl-sub-subscription_test-download-archive.json": "9f6f4458d42da4561db236473896fe71",
|
||||
"subscription_test/[2020] Mock Entry 20-1/01 - Mock Entry 20-1.mp3": "97320d70b1ccf04d4900b95b3c3645bc",
|
||||
"subscription_test/[2020] Mock Entry 20-1/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"subscription_test/[2020] Mock Entry 20-2/01 - Mock Entry 20-2.mp3": "b3ceb9fc194b524c77287e248d5860aa",
|
||||
"subscription_test/[2020] Mock Entry 20-2/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"subscription_test/[2020] Mock Entry 20-3/01 - Mock Entry 20-3.mp3": "55202bc60302d8475a3eaebc0902a253",
|
||||
"subscription_test/[2020] Mock Entry 20-3/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"subscription_test/[2021] Mock Entry 21-1/01 - Mock Entry 21-1.mp3": "2ad0d8ee1e28a2ecc726197cda67248d",
|
||||
"subscription_test/[2021] Mock Entry 21-1/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7"
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
".ytdl-sub-subscription_test-download-archive.json": "71c01e840f508dad1f7cf2b533bdb9d3",
|
||||
"subscription_test/[2020] Download First/02 - Mock Entry 20-1.mp3": "7b0ff394bc1fbb8419735914692cb2e4",
|
||||
"subscription_test/[2020] Download First/03 - Mock Entry 20-2.mp3": "e3b5de70c625eb55d0eb7cacf0429fa5",
|
||||
"subscription_test/[2020] Download First/04 - Mock Entry 20-3.mp3": "31fd8d0d38139aafb74ec94ba34a53dc",
|
||||
"subscription_test/[2020] Download First/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"subscription_test/[2020] Mock Entry 20-4/01 - Mock Entry 20-4.mp3": "5ceaa156a59d7f80dd74d9ce80cf8e5c",
|
||||
"subscription_test/[2020] Mock Entry 20-4/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"subscription_test/[2020] Mock Entry 20-5/01 - Mock Entry 20-5.mp3": "e651c65df918ab082d7051cd9b743972",
|
||||
"subscription_test/[2020] Mock Entry 20-5/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"subscription_test/[2020] Mock Entry 20-6/01 - Mock Entry 20-6.mp3": "c045e7ca79847848b4ccd905ae65c2f9",
|
||||
"subscription_test/[2020] Mock Entry 20-6/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"subscription_test/[2020] Mock Entry 20-7/01 - Mock Entry 20-7.mp3": "974fe1dc4a18a67f4b0e8c7c123397e3",
|
||||
"subscription_test/[2020] Mock Entry 20-7/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"subscription_test/[2021] Download First/01 - Mock Entry 21-1.mp3": "3459b2735afa7e41a32c34198e780a5e",
|
||||
"subscription_test/[2021] Download First/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7"
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
".ytdl-sub-subscription_test-download-archive.json": "9f6f4458d42da4561db236473896fe71",
|
||||
"subscription_test/[2020] Mock Entry 20-1/01 - Mock Entry 20-1.mp3": "97320d70b1ccf04d4900b95b3c3645bc",
|
||||
"subscription_test/[2020] Mock Entry 20-1/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"subscription_test/[2020] Mock Entry 20-2/01 - Mock Entry 20-2.mp3": "b3ceb9fc194b524c77287e248d5860aa",
|
||||
"subscription_test/[2020] Mock Entry 20-2/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"subscription_test/[2020] Mock Entry 20-3/01 - Mock Entry 20-3.mp3": "55202bc60302d8475a3eaebc0902a253",
|
||||
"subscription_test/[2020] Mock Entry 20-3/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"subscription_test/[2021] Mock Entry 21-1/01 - Mock Entry 21-1.mp3": "2ad0d8ee1e28a2ecc726197cda67248d",
|
||||
"subscription_test/[2021] Mock Entry 21-1/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7"
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
".ytdl-sub-subscription_test-download-archive.json": "36b3c7143ac4257489791309d802af82",
|
||||
"subscription_test/[2020] Download First/02 - Mock Entry 20-1.mp3": "7b0ff394bc1fbb8419735914692cb2e4",
|
||||
"subscription_test/[2020] Download First/03 - Mock Entry 20-2.mp3": "e3b5de70c625eb55d0eb7cacf0429fa5",
|
||||
"subscription_test/[2020] Download First/04 - Mock Entry 20-3.mp3": "31fd8d0d38139aafb74ec94ba34a53dc",
|
||||
"subscription_test/[2020] Download First/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"subscription_test/[2021] Download First/01 - Mock Entry 21-1.mp3": "3459b2735afa7e41a32c34198e780a5e",
|
||||
"subscription_test/[2021] Download First/folder.jpg": "e80c508c4818454300133fe1dc1a9cd7"
|
||||
}
|
||||
BIN
tests/resources/file_fixtures/sample_audio.mp3
Normal file
BIN
tests/resources/file_fixtures/sample_audio.mp3
Normal file
Binary file not shown.
|
|
@ -1,186 +1,188 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-jb-download-archive.json
|
||||
{output_directory}/El Jazzy Chavo/[2022] S950 Funk
|
||||
01 - Spark it.mp3
|
||||
.ytdl-sub-Sithu Aye-download-archive.json
|
||||
{output_directory}/Sithu Aye/[2021] 10 Years: Remixes and Reimaginings
|
||||
01 - Double Helix Reimagined.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Spark it
|
||||
album: 10 Years: Remixes and Reimaginings
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Double Helix Reimagined
|
||||
track: 1
|
||||
tracktotal: 15
|
||||
year: 2022
|
||||
02 - Astronomikal Funk.mp3
|
||||
tracktotal: 10
|
||||
year: 2021
|
||||
02 - Skye Reimagined.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Astronomikal Funk
|
||||
album: 10 Years: Remixes and Reimaginings
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Skye Reimagined
|
||||
track: 2
|
||||
tracktotal: 15
|
||||
year: 2022
|
||||
03 - Impulse.mp3
|
||||
tracktotal: 10
|
||||
year: 2021
|
||||
03 - Baryofusion.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Impulse
|
||||
album: 10 Years: Remixes and Reimaginings
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Baryofusion
|
||||
track: 3
|
||||
tracktotal: 15
|
||||
year: 2022
|
||||
04 - September.mp3
|
||||
tracktotal: 10
|
||||
year: 2021
|
||||
04 - Mandalay Reimagined.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: September
|
||||
album: 10 Years: Remixes and Reimaginings
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Mandalay Reimagined
|
||||
track: 4
|
||||
tracktotal: 15
|
||||
year: 2022
|
||||
05 - Interlune.mp3
|
||||
tracktotal: 10
|
||||
year: 2021
|
||||
05 - Messenger EDM Remix.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Interlune
|
||||
album: 10 Years: Remixes and Reimaginings
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Messenger EDM Remix
|
||||
track: 5
|
||||
tracktotal: 15
|
||||
year: 2022
|
||||
06 - Ninjutsu Techniques.mp3
|
||||
tracktotal: 10
|
||||
year: 2021
|
||||
folder.jpg
|
||||
{output_directory}/Sithu Aye/[2022] Re:Invent the Universe (10th Anniversary Remaster)
|
||||
01 - Invent the Universe.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Ninjutsu Techniques
|
||||
album: Re:Invent the Universe (10th Anniversary Remaster)
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Invent the Universe
|
||||
track: 1
|
||||
tracktotal: 10
|
||||
year: 2022
|
||||
02 - Grand Unification (feat. David Maxim Micic).mp3
|
||||
Music Tags:
|
||||
album: Re:Invent the Universe (10th Anniversary Remaster)
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Grand Unification (feat. David Maxim Micic)
|
||||
track: 2
|
||||
tracktotal: 10
|
||||
year: 2022
|
||||
03 - Expansion.mp3
|
||||
Music Tags:
|
||||
album: Re:Invent the Universe (10th Anniversary Remaster)
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Expansion
|
||||
track: 3
|
||||
tracktotal: 10
|
||||
year: 2022
|
||||
04 - Baryogenesis.mp3
|
||||
Music Tags:
|
||||
album: Re:Invent the Universe (10th Anniversary Remaster)
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Baryogenesis
|
||||
track: 4
|
||||
tracktotal: 10
|
||||
year: 2022
|
||||
05 - Particles Collide (feat. Plini).mp3
|
||||
Music Tags:
|
||||
album: Re:Invent the Universe (10th Anniversary Remaster)
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Particles Collide (feat. Plini)
|
||||
track: 5
|
||||
tracktotal: 10
|
||||
year: 2022
|
||||
06 - Nucleosynthesis.mp3
|
||||
Music Tags:
|
||||
album: Re:Invent the Universe (10th Anniversary Remaster)
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Nucleosynthesis
|
||||
track: 6
|
||||
tracktotal: 15
|
||||
tracktotal: 10
|
||||
year: 2022
|
||||
07 - Space Funk Flow.mp3
|
||||
07 - Recombination.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Space Funk Flow
|
||||
album: Re:Invent the Universe (10th Anniversary Remaster)
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Recombination
|
||||
track: 7
|
||||
tracktotal: 15
|
||||
tracktotal: 10
|
||||
year: 2022
|
||||
08 - Cellar Groove.mp3
|
||||
08 - Dark Ages.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Cellar Groove
|
||||
album: Re:Invent the Universe (10th Anniversary Remaster)
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Dark Ages
|
||||
track: 8
|
||||
tracktotal: 15
|
||||
tracktotal: 10
|
||||
year: 2022
|
||||
09 - Solar Wind.mp3
|
||||
09 - Formation.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Solar Wind
|
||||
album: Re:Invent the Universe (10th Anniversary Remaster)
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Formation
|
||||
track: 9
|
||||
tracktotal: 15
|
||||
tracktotal: 10
|
||||
year: 2022
|
||||
10 - Interlune II.mp3
|
||||
10 - Pale Blue Dot.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Interlune II
|
||||
album: Re:Invent the Universe (10th Anniversary Remaster)
|
||||
albumartist: Sithu Aye
|
||||
albumartists: Sithu Aye
|
||||
artist: Sithu Aye
|
||||
artists: Sithu Aye
|
||||
genre: Progressive Metal
|
||||
title: Pale Blue Dot
|
||||
track: 10
|
||||
tracktotal: 15
|
||||
year: 2022
|
||||
11 - Ghetto Anthem.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Ghetto Anthem
|
||||
track: 11
|
||||
tracktotal: 15
|
||||
year: 2022
|
||||
12 - Street Degree.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Street Degree
|
||||
track: 12
|
||||
tracktotal: 15
|
||||
year: 2022
|
||||
13 - Trouble World.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Trouble World
|
||||
track: 13
|
||||
tracktotal: 15
|
||||
year: 2022
|
||||
14 - Relaxation.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Relaxation
|
||||
track: 14
|
||||
tracktotal: 15
|
||||
year: 2022
|
||||
15 - Journey From Within.mp3
|
||||
Music Tags:
|
||||
album: S950 Funk
|
||||
albumartist: El Jazzy Chavo
|
||||
albumartists: El Jazzy Chavo
|
||||
artist: El Jazzy Chavo
|
||||
artists: El Jazzy Chavo
|
||||
genre: Unset
|
||||
title: Journey From Within
|
||||
track: 15
|
||||
tracktotal: 15
|
||||
tracktotal: 10
|
||||
year: 2022
|
||||
folder.jpg
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-split_by_chapters_video-download-archive.json
|
||||
.ytdl-sub-Proved Records-download-archive.json
|
||||
{output_directory}/Proved Records/[2017] Alfa Mist - Nocturne [Full Album]
|
||||
01 - 01. Intro (Feat. Racheal Ofori & Barney Artist).mp3
|
||||
From Chapter Split:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-split_by_chapters_video-download-archive.json
|
||||
.ytdl-sub-Proved Records-download-archive.json
|
||||
{output_directory}/Proved Records/[2017] Alfa Mist - Nocturne [Full Album]
|
||||
01 - 01. Intro (Feat. Racheal Ofori & Barney Artist).mp3
|
||||
From Chapter Split:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-split_by_chapters_with_regex_video-download-archive.json
|
||||
.ytdl-sub-split_by_chapters_with_regex_video_no_chapters-download-archive.json
|
||||
{output_directory}/Project Zombie/[2010] Oblivion Mod "Falcor" p.1
|
||||
01 - Oblivion Mod "Falcor" p.1.mp3
|
||||
Music Tags:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-split_by_chapters_with_regex_video-download-archive.json
|
||||
.ytdl-sub-split_by_chapters_with_regex_video_preset-download-archive.json
|
||||
{output_directory}/Alfa Mist/[2017] Nocturne
|
||||
01 - Intro (Feat. Racheal Ofori & Barney Artist).mp3
|
||||
From Chapter Split:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-split_by_chapters_with_regex_video-download-archive.json
|
||||
.ytdl-sub-split_by_chapters_with_regex_video_preset-download-archive.json
|
||||
{output_directory}/Alfa Mist/[2017] Nocturne
|
||||
01 - Intro (Feat. Racheal Ofori & Barney Artist).mp3
|
||||
From Chapter Split:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-jb-download-archive.json
|
||||
.ytdl-sub-j_b-download-archive.json
|
||||
{output_directory}/j_b/[2021] Baby Santana's Dorian Groove
|
||||
01 - Baby Santana's Dorian Groove.mp3
|
||||
Music Tags:
|
||||
|
|
@ -10,7 +10,7 @@ Files created:
|
|||
albumartists: j_b
|
||||
artist: j_b
|
||||
artists: j_b
|
||||
genre: Unset
|
||||
genre: Acoustic
|
||||
title: Baby Santana's Dorian Groove
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
|
|
@ -24,7 +24,7 @@ Files created:
|
|||
albumartists: j_b
|
||||
artist: j_b
|
||||
artists: j_b
|
||||
genre: Unset
|
||||
genre: Acoustic
|
||||
title: Purple Clouds
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
|
|
@ -38,7 +38,7 @@ Files created:
|
|||
albumartists: j_b
|
||||
artist: j_b
|
||||
artists: j_b
|
||||
genre: Unset
|
||||
genre: Acoustic
|
||||
title: 20160426 184214
|
||||
track: 1
|
||||
tracktotal: 11
|
||||
|
|
@ -50,7 +50,7 @@ Files created:
|
|||
albumartists: j_b
|
||||
artist: j_b
|
||||
artists: j_b
|
||||
genre: Unset
|
||||
genre: Acoustic
|
||||
title: 20160502 123150
|
||||
track: 2
|
||||
tracktotal: 11
|
||||
|
|
@ -62,7 +62,7 @@ Files created:
|
|||
albumartists: j_b
|
||||
artist: j_b
|
||||
artists: j_b
|
||||
genre: Unset
|
||||
genre: Acoustic
|
||||
title: 20160504 143832
|
||||
track: 3
|
||||
tracktotal: 11
|
||||
|
|
@ -74,7 +74,7 @@ Files created:
|
|||
albumartists: j_b
|
||||
artist: j_b
|
||||
artists: j_b
|
||||
genre: Unset
|
||||
genre: Acoustic
|
||||
title: 20160601 221234
|
||||
track: 4
|
||||
tracktotal: 11
|
||||
|
|
@ -86,7 +86,7 @@ Files created:
|
|||
albumartists: j_b
|
||||
artist: j_b
|
||||
artists: j_b
|
||||
genre: Unset
|
||||
genre: Acoustic
|
||||
title: 20160601 222440
|
||||
track: 5
|
||||
tracktotal: 11
|
||||
|
|
@ -98,7 +98,7 @@ Files created:
|
|||
albumartists: j_b
|
||||
artist: j_b
|
||||
artists: j_b
|
||||
genre: Unset
|
||||
genre: Acoustic
|
||||
title: 20170604 190236
|
||||
track: 6
|
||||
tracktotal: 11
|
||||
|
|
@ -110,7 +110,7 @@ Files created:
|
|||
albumartists: j_b
|
||||
artist: j_b
|
||||
artists: j_b
|
||||
genre: Unset
|
||||
genre: Acoustic
|
||||
title: 20170612 193646
|
||||
track: 7
|
||||
tracktotal: 11
|
||||
|
|
@ -122,7 +122,7 @@ Files created:
|
|||
albumartists: j_b
|
||||
artist: j_b
|
||||
artists: j_b
|
||||
genre: Unset
|
||||
genre: Acoustic
|
||||
title: 20170628 215206
|
||||
track: 8
|
||||
tracktotal: 11
|
||||
|
|
@ -134,7 +134,7 @@ Files created:
|
|||
albumartists: j_b
|
||||
artist: j_b
|
||||
artists: j_b
|
||||
genre: Unset
|
||||
genre: Acoustic
|
||||
title: Finding Home
|
||||
track: 9
|
||||
tracktotal: 11
|
||||
|
|
@ -146,7 +146,7 @@ Files created:
|
|||
albumartists: j_b
|
||||
artist: j_b
|
||||
artists: j_b
|
||||
genre: Unset
|
||||
genre: Acoustic
|
||||
title: Shallow Water WIP
|
||||
track: 10
|
||||
tracktotal: 11
|
||||
|
|
@ -158,7 +158,7 @@ Files created:
|
|||
albumartists: j_b
|
||||
artist: j_b
|
||||
artists: j_b
|
||||
genre: Unset
|
||||
genre: Acoustic
|
||||
title: Untold History
|
||||
track: 11
|
||||
tracktotal: 11
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-subscription_test-download-archive.json
|
||||
{output_directory}/subscription_test/[2020] Download First
|
||||
02 - Mock Entry 20-1.mp3
|
||||
Music Tags:
|
||||
album: Download First
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-1
|
||||
track: 2
|
||||
tracktotal: 4
|
||||
year: 2020
|
||||
03 - Mock Entry 20-2.mp3
|
||||
Music Tags:
|
||||
album: Download First
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-2
|
||||
track: 3
|
||||
tracktotal: 4
|
||||
year: 2020
|
||||
04 - Mock Entry 20-3.mp3
|
||||
Music Tags:
|
||||
album: Download First
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-3
|
||||
track: 4
|
||||
tracktotal: 4
|
||||
year: 2020
|
||||
folder.jpg
|
||||
{output_directory}/subscription_test/[2021] Download First
|
||||
01 - Mock Entry 21-1.mp3
|
||||
Music Tags:
|
||||
album: Download First
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 21-1
|
||||
track: 1
|
||||
tracktotal: 4
|
||||
year: 2021
|
||||
folder.jpg
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-subscription_test-download-archive.json
|
||||
{output_directory}/subscription_test/[2020] Mock Entry 20-1
|
||||
01 - Mock Entry 20-1.mp3
|
||||
Music Tags:
|
||||
album: Mock Entry 20-1
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-1
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
year: 2020
|
||||
folder.jpg
|
||||
{output_directory}/subscription_test/[2020] Mock Entry 20-2
|
||||
01 - Mock Entry 20-2.mp3
|
||||
Music Tags:
|
||||
album: Mock Entry 20-2
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-2
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
year: 2020
|
||||
folder.jpg
|
||||
{output_directory}/subscription_test/[2020] Mock Entry 20-3
|
||||
01 - Mock Entry 20-3.mp3
|
||||
Music Tags:
|
||||
album: Mock Entry 20-3
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-3
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
year: 2020
|
||||
folder.jpg
|
||||
{output_directory}/subscription_test/[2021] Mock Entry 21-1
|
||||
01 - Mock Entry 21-1.mp3
|
||||
Music Tags:
|
||||
album: Mock Entry 21-1
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 21-1
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
year: 2021
|
||||
folder.jpg
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-subscription_test-download-archive.json
|
||||
{output_directory}/subscription_test/[2020] Download First
|
||||
02 - Mock Entry 20-1.mp3
|
||||
Music Tags:
|
||||
album: Download First
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-1
|
||||
track: 2
|
||||
tracktotal: 4
|
||||
year: 2020
|
||||
03 - Mock Entry 20-2.mp3
|
||||
Music Tags:
|
||||
album: Download First
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-2
|
||||
track: 3
|
||||
tracktotal: 4
|
||||
year: 2020
|
||||
04 - Mock Entry 20-3.mp3
|
||||
Music Tags:
|
||||
album: Download First
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-3
|
||||
track: 4
|
||||
tracktotal: 4
|
||||
year: 2020
|
||||
folder.jpg
|
||||
{output_directory}/subscription_test/[2020] Mock Entry 20-4
|
||||
01 - Mock Entry 20-4.mp3
|
||||
Music Tags:
|
||||
album: Mock Entry 20-4
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-4
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
year: 2020
|
||||
folder.jpg
|
||||
{output_directory}/subscription_test/[2020] Mock Entry 20-5
|
||||
01 - Mock Entry 20-5.mp3
|
||||
Music Tags:
|
||||
album: Mock Entry 20-5
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-5
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
year: 2020
|
||||
folder.jpg
|
||||
{output_directory}/subscription_test/[2020] Mock Entry 20-6
|
||||
01 - Mock Entry 20-6.mp3
|
||||
Music Tags:
|
||||
album: Mock Entry 20-6
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-6
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
year: 2020
|
||||
folder.jpg
|
||||
{output_directory}/subscription_test/[2020] Mock Entry 20-7
|
||||
01 - Mock Entry 20-7.mp3
|
||||
Music Tags:
|
||||
album: Mock Entry 20-7
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-7
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
year: 2020
|
||||
folder.jpg
|
||||
{output_directory}/subscription_test/[2021] Download First
|
||||
01 - Mock Entry 21-1.mp3
|
||||
Music Tags:
|
||||
album: Download First
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 21-1
|
||||
track: 1
|
||||
tracktotal: 4
|
||||
year: 2021
|
||||
folder.jpg
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-subscription_test-download-archive.json
|
||||
{output_directory}/subscription_test/[2020] Mock Entry 20-1
|
||||
01 - Mock Entry 20-1.mp3
|
||||
Music Tags:
|
||||
album: Mock Entry 20-1
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-1
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
year: 2020
|
||||
folder.jpg
|
||||
{output_directory}/subscription_test/[2020] Mock Entry 20-2
|
||||
01 - Mock Entry 20-2.mp3
|
||||
Music Tags:
|
||||
album: Mock Entry 20-2
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-2
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
year: 2020
|
||||
folder.jpg
|
||||
{output_directory}/subscription_test/[2020] Mock Entry 20-3
|
||||
01 - Mock Entry 20-3.mp3
|
||||
Music Tags:
|
||||
album: Mock Entry 20-3
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-3
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
year: 2020
|
||||
folder.jpg
|
||||
{output_directory}/subscription_test/[2021] Mock Entry 21-1
|
||||
01 - Mock Entry 21-1.mp3
|
||||
Music Tags:
|
||||
album: Mock Entry 21-1
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 21-1
|
||||
track: 1
|
||||
tracktotal: 1
|
||||
year: 2021
|
||||
folder.jpg
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
Files created:
|
||||
----------------------------------------
|
||||
{output_directory}
|
||||
.ytdl-sub-subscription_test-download-archive.json
|
||||
{output_directory}/subscription_test/[2020] Download First
|
||||
02 - Mock Entry 20-1.mp3
|
||||
Music Tags:
|
||||
album: Download First
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-1
|
||||
track: 2
|
||||
tracktotal: 4
|
||||
year: 2020
|
||||
03 - Mock Entry 20-2.mp3
|
||||
Music Tags:
|
||||
album: Download First
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-2
|
||||
track: 3
|
||||
tracktotal: 4
|
||||
year: 2020
|
||||
04 - Mock Entry 20-3.mp3
|
||||
Music Tags:
|
||||
album: Download First
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 20-3
|
||||
track: 4
|
||||
tracktotal: 4
|
||||
year: 2020
|
||||
folder.jpg
|
||||
{output_directory}/subscription_test/[2021] Download First
|
||||
01 - Mock Entry 21-1.mp3
|
||||
Music Tags:
|
||||
album: Download First
|
||||
albumartist: subscription_test
|
||||
albumartists: subscription_test
|
||||
artist: subscription_test
|
||||
artists: subscription_test
|
||||
genre: Unset
|
||||
title: Mock Entry 21-1
|
||||
track: 1
|
||||
tracktotal: 4
|
||||
year: 2021
|
||||
folder.jpg
|
||||
|
|
@ -341,7 +341,7 @@ def test_tv_show_subscriptions(
|
|||
config=channel_as_tv_show_config, subscription_path=tv_show_subscriptions_path
|
||||
)
|
||||
|
||||
assert len(subs) == 6
|
||||
assert len(subs) == 5
|
||||
assert subs[2].name == "Jake Trains"
|
||||
jake_train_overrides = subs[2].overrides.dict_with_format_strings
|
||||
|
||||
|
|
@ -349,3 +349,17 @@ def test_tv_show_subscriptions(
|
|||
assert jake_train_overrides["subscription_value"] == "https://www.youtube.com/@JakeTrains"
|
||||
assert jake_train_overrides["subscription_indent_1"] == "Kids"
|
||||
assert jake_train_overrides["subscription_indent_2"] == "TV-Y"
|
||||
|
||||
|
||||
def test_music_subscriptions(music_audio_config: ConfigFile, music_subscriptions_path: Path):
|
||||
subs = Subscription.from_file_path(
|
||||
config=music_audio_config, subscription_path=music_subscriptions_path
|
||||
)
|
||||
|
||||
assert len(subs) == 14
|
||||
assert subs[2].name == "Stan Getz"
|
||||
monk = subs[2].overrides.dict_with_format_strings
|
||||
|
||||
assert monk["subscription_name"] == "Stan Getz"
|
||||
assert monk["subscription_value"] == "https://www.youtube.com/@stangetzofficial/releases"
|
||||
assert monk["subscription_indent_1"] == "Jazz"
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ from ytdl_sub.entries.variables.kwargs import EXTRACTOR
|
|||
from ytdl_sub.entries.variables.kwargs import PLAYLIST_COUNT
|
||||
from ytdl_sub.entries.variables.kwargs import PLAYLIST_ENTRY
|
||||
from ytdl_sub.entries.variables.kwargs import PLAYLIST_INDEX
|
||||
from ytdl_sub.entries.variables.kwargs import PLAYLIST_TITLE
|
||||
from ytdl_sub.entries.variables.kwargs import TITLE
|
||||
from ytdl_sub.entries.variables.kwargs import UID
|
||||
from ytdl_sub.entries.variables.kwargs import UPLOAD_DATE
|
||||
|
|
@ -53,14 +54,17 @@ def mock_entry_dict_factory(mock_downloaded_file_path) -> Callable:
|
|||
def _mock_entry_dict_factory(
|
||||
uid: int,
|
||||
upload_date: str,
|
||||
playlist_title: str = "playlist title",
|
||||
playlist_index: int = 1,
|
||||
playlist_count: int = 1,
|
||||
is_youtube_channel: bool = False,
|
||||
mock_download_to_working_dir: bool = True,
|
||||
is_extracted_audio: bool = False,
|
||||
) -> Dict:
|
||||
entry_dict = {
|
||||
UID: uid,
|
||||
EPOCH: 1596878400,
|
||||
PLAYLIST_TITLE: playlist_title,
|
||||
PLAYLIST_INDEX: playlist_index,
|
||||
PLAYLIST_COUNT: playlist_count,
|
||||
EXTRACTOR: "mock-entry-dict",
|
||||
|
|
@ -86,10 +90,16 @@ def mock_entry_dict_factory(mock_downloaded_file_path) -> Callable:
|
|||
|
||||
# Create mock video file
|
||||
if mock_download_to_working_dir:
|
||||
copy_file_fixture(
|
||||
fixture_name="sample_vid.mp4",
|
||||
output_file_path=mock_downloaded_file_path(f"{uid}.mp4"),
|
||||
)
|
||||
if is_extracted_audio:
|
||||
copy_file_fixture(
|
||||
fixture_name="sample_audio.mp3",
|
||||
output_file_path=mock_downloaded_file_path(f"{uid}.mp3"),
|
||||
)
|
||||
else:
|
||||
copy_file_fixture(
|
||||
fixture_name="sample_vid.mp4",
|
||||
output_file_path=mock_downloaded_file_path(f"{uid}.mp4"),
|
||||
)
|
||||
copy_file_fixture(
|
||||
fixture_name="thumb.jpg", output_file_path=mock_downloaded_file_path(f"{uid}.jpg")
|
||||
)
|
||||
|
|
@ -106,10 +116,14 @@ def mock_download_collection_thumbnail(mock_downloaded_file_path):
|
|||
_ = thumbnail_url
|
||||
output_name = os.path.basename(output_thumbnail_path)
|
||||
if "poster" in output_name or "show" in output_name:
|
||||
copy_file_fixture(fixture_name="poster.jpg", output_file_path=output_thumbnail_path)
|
||||
copy_file_fixture(
|
||||
fixture_name="poster.jpg", output_file_path=Path(output_thumbnail_path)
|
||||
)
|
||||
return True
|
||||
elif "fanart" in output_name:
|
||||
copy_file_fixture(fixture_name="fanart.jpeg", output_file_path=output_thumbnail_path)
|
||||
copy_file_fixture(
|
||||
fixture_name="fanart.jpeg", output_file_path=Path(output_thumbnail_path)
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
|
@ -125,37 +139,50 @@ def mock_download_collection_entries(
|
|||
mock_download_collection_thumbnail, mock_entry_dict_factory: Callable, working_directory: str
|
||||
):
|
||||
@contextlib.contextmanager
|
||||
def _mock_download_collection_entries_factory(is_youtube_channel: bool, num_urls: int = 1):
|
||||
def _mock_download_collection_entries_factory(
|
||||
is_youtube_channel: bool, num_urls: int = 1, is_extracted_audio: bool = False
|
||||
):
|
||||
def _write_entries_to_working_dir(*args, **kwargs) -> List[Dict]:
|
||||
if num_urls == 1 or ("2" in kwargs["url"] and num_urls > 1):
|
||||
# Second TV URL or second soundcloud URL, which downloads first
|
||||
is_second_url = "2" in kwargs["url"] or kwargs["url"].endswith("/albums")
|
||||
|
||||
if num_urls == 1 or (is_second_url and num_urls > 1):
|
||||
return [
|
||||
mock_entry_dict_factory(
|
||||
uid="21-1",
|
||||
upload_date="20210808",
|
||||
playlist_title="Download First",
|
||||
playlist_index=1,
|
||||
playlist_count=4,
|
||||
is_youtube_channel=is_youtube_channel,
|
||||
is_extracted_audio=is_extracted_audio,
|
||||
), # 1
|
||||
mock_entry_dict_factory(
|
||||
uid="20-1",
|
||||
upload_date="20200808",
|
||||
playlist_title="Download First",
|
||||
playlist_index=2,
|
||||
playlist_count=4,
|
||||
is_youtube_channel=is_youtube_channel,
|
||||
is_extracted_audio=is_extracted_audio,
|
||||
), # 2 98
|
||||
mock_entry_dict_factory(
|
||||
uid="20-2",
|
||||
upload_date="20200808",
|
||||
playlist_title="Download First",
|
||||
playlist_index=3,
|
||||
playlist_count=4,
|
||||
is_youtube_channel=is_youtube_channel,
|
||||
is_extracted_audio=is_extracted_audio,
|
||||
), # 1 99
|
||||
mock_entry_dict_factory(
|
||||
uid="20-3",
|
||||
upload_date="20200807",
|
||||
playlist_title="Download First",
|
||||
playlist_index=4,
|
||||
playlist_count=4,
|
||||
is_youtube_channel=is_youtube_channel,
|
||||
is_extracted_audio=is_extracted_audio,
|
||||
),
|
||||
]
|
||||
return [
|
||||
|
|
@ -163,38 +190,48 @@ def mock_download_collection_entries(
|
|||
mock_entry_dict_factory(
|
||||
uid="20-3",
|
||||
upload_date="20200807",
|
||||
playlist_title="Download Second",
|
||||
playlist_index=1,
|
||||
playlist_count=5,
|
||||
is_youtube_channel=is_youtube_channel,
|
||||
mock_download_to_working_dir=False,
|
||||
is_extracted_audio=is_extracted_audio,
|
||||
),
|
||||
mock_entry_dict_factory(
|
||||
uid="20-4",
|
||||
upload_date="20200806",
|
||||
playlist_title="Download Second",
|
||||
playlist_index=2,
|
||||
playlist_count=5,
|
||||
is_youtube_channel=is_youtube_channel,
|
||||
is_extracted_audio=is_extracted_audio,
|
||||
),
|
||||
mock_entry_dict_factory(
|
||||
uid="20-5",
|
||||
upload_date="20200706",
|
||||
playlist_title="Download Second",
|
||||
playlist_index=3,
|
||||
playlist_count=5,
|
||||
is_youtube_channel=is_youtube_channel,
|
||||
is_extracted_audio=is_extracted_audio,
|
||||
),
|
||||
mock_entry_dict_factory(
|
||||
uid="20-6",
|
||||
upload_date="20200706",
|
||||
playlist_title="Download Second",
|
||||
playlist_index=4,
|
||||
playlist_count=5,
|
||||
is_youtube_channel=is_youtube_channel,
|
||||
is_extracted_audio=is_extracted_audio,
|
||||
),
|
||||
mock_entry_dict_factory(
|
||||
uid="20-7",
|
||||
upload_date="20200606",
|
||||
playlist_title="Download Second",
|
||||
playlist_index=5,
|
||||
playlist_count=5,
|
||||
is_youtube_channel=is_youtube_channel,
|
||||
is_extracted_audio=is_extracted_audio,
|
||||
),
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -6,18 +6,19 @@ 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.music import MusicPresets
|
||||
from ytdl_sub.prebuilt_presets.tv_show import TvShowByDateEpisodeFormattingPresets
|
||||
from ytdl_sub.prebuilt_presets.tv_show import TvShowByDatePresets
|
||||
from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionEpisodeFormattingPresets
|
||||
from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionPresets
|
||||
from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionSeasonPresets
|
||||
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 +180,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 +209,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,
|
||||
|
|
@ -342,3 +343,70 @@ class TestPrebuiltTvShowCollectionPresets:
|
|||
dry_run=False,
|
||||
expected_download_summary_file_name=f"{reformatted_expected_summary_name}_migrated.json",
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("music_preset", MusicPresets.preset_names)
|
||||
class TestPrebuiltMusicPresets:
|
||||
def test_compilation(
|
||||
self,
|
||||
config,
|
||||
music_preset: str,
|
||||
):
|
||||
_ = Subscription.from_dict(
|
||||
config=config,
|
||||
preset_name="preset_test",
|
||||
preset_dict={
|
||||
"preset": [
|
||||
music_preset,
|
||||
],
|
||||
"overrides": {
|
||||
"subscription_value": "https://your.name.here",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
def test_presets_run(
|
||||
self,
|
||||
config,
|
||||
subscription_name,
|
||||
output_directory,
|
||||
mock_download_collection_entries,
|
||||
music_preset: str,
|
||||
):
|
||||
expected_summary_name = f"unit/music/{music_preset}"
|
||||
|
||||
preset_dict = {
|
||||
"preset": [
|
||||
music_preset,
|
||||
],
|
||||
"overrides": {
|
||||
"url": "https://your.name.here",
|
||||
"music_directory": output_directory,
|
||||
},
|
||||
}
|
||||
|
||||
subscription = Subscription.from_dict(
|
||||
config=config,
|
||||
preset_name=subscription_name,
|
||||
preset_dict=preset_dict,
|
||||
)
|
||||
|
||||
num_urls = 1
|
||||
if music_preset == "SoundCloud Discography":
|
||||
num_urls = 2 # simulate /albums and /tracks
|
||||
|
||||
with mock_download_collection_entries(
|
||||
is_youtube_channel=False, num_urls=num_urls, is_extracted_audio=True
|
||||
):
|
||||
transaction_log = subscription.download(dry_run=False)
|
||||
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name=f"{expected_summary_name}.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=False,
|
||||
expected_download_summary_file_name=f"{expected_summary_name}.json",
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue