use crate::core::{
download_mode::{DownloadSource, DownloadType, Quality},
flags::{all_flags, Flag},
};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Preset {
pub id: &'static str,
pub label: &'static str,
pub description: &'static str,
pub icon: &'static str,
pub download_type: DownloadType,
pub download_source: DownloadSource,
pub quality: Quality,
pub flag_keys: Vec<&'static str>,
}
const VIDEO_BASE: &[&str] = &[
"--embed-thumbnail",
"--add-metadata",
"--embed-chapters",
"--embed-info-json",
"--embed-subs",
"--merge-output-format mp4",
"--no-overwrites",
"--continue",
];
const AUDIO_BASE: &[&str] = &[
"--extract-audio",
"--audio-format mp3",
"--audio-quality 0",
"--embed-thumbnail",
"--add-metadata",
"--embed-chapters",
"--embed-info-json",
"--no-overwrites",
"--continue",
];
pub fn all_presets() -> Vec<Preset> {
let single_video_flags = VIDEO_BASE.to_vec();
let single_video = Preset {
id: "single_video",
label: "Single Video",
description: "One video at 1080p with metadata, chapters & thumbnail",
icon: "🎬",
download_type: DownloadType::Video,
download_source: DownloadSource::Single,
quality: Quality::HD1080,
flag_keys: { single_video_flags.clone() },
};
let batch_video = Preset {
id: "batch_video",
label: "Batch Videos",
description: "Videos from a .txt file — one URL per line",
icon: "📄",
download_type: DownloadType::Video,
download_source: DownloadSource::Batch,
quality: Quality::HD1080,
flag_keys: VIDEO_BASE.to_vec(),
};
let mut playlist_video_flags = VIDEO_BASE.to_vec();
playlist_video_flags.insert(0, "--yes-playlist");
let video_playlist = Preset {
id: "video_playlist",
label: "Video Playlist",
description: "Full playlist sorted into Playlists/@uploader/title/",
icon: "📋",
download_type: DownloadType::Video,
download_source: DownloadSource::Playlist,
quality: Quality::HD1080,
flag_keys: playlist_video_flags,
};
let channel_video = Preset {
id: "channel_video",
label: "Channel Videos",
description: "Archive entire channel sorted into Channels/@uploader/",
icon: "📺",
download_type: DownloadType::Video,
download_source: DownloadSource::Channel,
quality: Quality::HD1080,
flag_keys: VIDEO_BASE.to_vec(),
};
let single_audio = Preset {
id: "single_audio",
label: "Single Audio",
description: "Extract audio as MP3 with metadata, chapters & thumbnail",
icon: "🎵",
download_type: DownloadType::Audio,
download_source: DownloadSource::Single,
quality: Quality::HD1080,
flag_keys: AUDIO_BASE.to_vec(),
};
let batch_audio = Preset {
id: "batch_audio",
label: "Batch Audio",
description: "Extract audio from each URL in a .txt batch file",
icon: "📄",
download_type: DownloadType::Audio,
download_source: DownloadSource::Batch,
quality: Quality::HD1080,
flag_keys: AUDIO_BASE.to_vec(),
};
let mut playlist_audio_flags = AUDIO_BASE.to_vec();
playlist_audio_flags.insert(0, "--yes-playlist");
let audio_playlist = Preset {
id: "audio_playlist",
label: "Audio Playlist",
description: "Extract all audio from a playlist into Playlists/@uploader/",
icon: "🎧",
download_type: DownloadType::Audio,
download_source: DownloadSource::Playlist,
quality: Quality::HD1080,
flag_keys: playlist_audio_flags,
};
let channel_audio = Preset {
id: "channel_audio",
label: "Channel Audio",
description: "Extract all audio from a channel into Channels/@uploader/",
icon: "📻",
download_type: DownloadType::Audio,
download_source: DownloadSource::Channel,
quality: Quality::HD1080,
flag_keys: AUDIO_BASE.to_vec(),
};
vec![
single_video,
batch_video,
video_playlist,
channel_video,
single_audio,
batch_audio,
audio_playlist,
channel_audio,
]
}
pub fn default_preset() -> Preset {
all_presets().into_iter().next().unwrap()
}
pub fn resolve_preset_flags(preset: &Preset) -> Vec<Flag> {
let all = all_flags();
preset
.flag_keys
.iter()
.filter_map(|key| all.iter().find(|f| f.flag == *key).cloned())
.collect()
}