diff options
Diffstat (limited to 'src/storage/video_database/mod.rs')
-rw-r--r-- | src/storage/video_database/mod.rs | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/src/storage/video_database/mod.rs b/src/storage/video_database/mod.rs new file mode 100644 index 0000000..28263ca --- /dev/null +++ b/src/storage/video_database/mod.rs @@ -0,0 +1,170 @@ +// yt - A fully featured command line YouTube client +// +// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This file is part of Yt. +// +// You should have received a copy of the License along with this program. +// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. + +use std::{fmt::Write, path::PathBuf}; + +use url::Url; + +use crate::{ + constants::{DEFAULT_MPV_PLAYBACK_SPEED, DEFAULT_SUBTITLE_LANGS}, + storage::video_database::extractor_hash::ExtractorHash, +}; + +pub mod downloader; +pub mod extractor_hash; +pub mod getters; +pub mod setters; + +#[derive(Debug)] +pub struct Video { + pub cache_path: Option<PathBuf>, + pub description: Option<String>, + pub duration: Option<f64>, + pub extractor_hash: ExtractorHash, + pub last_status_change: i64, + /// The associated subscription this video was fetched from (null, when the video was `add`ed) + pub parent_subscription_name: Option<String>, + pub priority: i64, + pub publish_date: Option<i64>, + pub status: VideoStatus, + /// The video is currently changing its state (for example from being `SELECT` to being `CACHE`) + pub status_change: bool, + pub thumbnail_url: Option<Url>, + pub title: String, + pub url: Url, +} + +#[derive(Debug)] +pub struct VideoOptions { + pub yt_dlp: YtDlpOptions, + pub mpv: MpvOptions, +} +impl VideoOptions { + pub(crate) fn new(subtitle_langs: String, playback_speed: f64) -> Self { + let yt_dlp = YtDlpOptions { subtitle_langs }; + let mpv = MpvOptions { playback_speed }; + Self { yt_dlp, mpv } + } + + /// This will write out the options that are different from the defaults. + /// Beware, that this does not set the priority. + pub fn to_cli_flags(self) -> String { + let mut f = String::new(); + + if self.mpv.playback_speed != DEFAULT_MPV_PLAYBACK_SPEED { + write!(f, " --speed '{}'", self.mpv.playback_speed).expect("Works"); + } + if self.yt_dlp.subtitle_langs != DEFAULT_SUBTITLE_LANGS { + write!(f, " --subtitle-langs '{}'", self.yt_dlp.subtitle_langs).expect("Works"); + } + + f.trim().to_owned() + } +} + +#[derive(Debug)] +/// Additionally settings passed to mpv on watch +pub struct MpvOptions { + /// The playback speed. (1 is 100%, 2.7 is 270%, and so on) + pub playback_speed: f64, +} + +#[derive(Debug)] +/// Additionally configuration options, passed to yt-dlp on download +pub struct YtDlpOptions { + /// In the form of `lang1,lang2,lang3` (e.g. `en,de,sv`) + pub subtitle_langs: String, +} + +/// # Video Lifetime (words in <brackets> are commands): +/// <Pick> +/// / \ +/// <Watch> <Drop> -> Dropped // yt select +/// | +/// Cache // yt cache +/// | +/// Watched // yt watch +#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum VideoStatus { + #[default] + Pick, + + /// The video has been select to be watched + Watch, + /// The video has been cached and is ready to be watched + Cached, + /// The video has been watched + Watched, + + /// The video has been select to be dropped + Drop, + /// The video has been dropped + Dropped, +} + +impl VideoStatus { + pub fn as_command(&self) -> &str { + // NOTE: Keep the serialize able variants synced with the main `select` function <2024-06-14> + match self { + VideoStatus::Pick => "pick", + + VideoStatus::Watch => "watch", + VideoStatus::Cached => "watch", + VideoStatus::Watched => "watch", + + VideoStatus::Drop => "drop", + VideoStatus::Dropped => "drop", + } + } + + pub fn as_db_integer(&self) -> i64 { + // These numbers should not change their mapping! + // Oh, and keep them in sync with the SQLite check constraint. + match self { + VideoStatus::Pick => 0, + + VideoStatus::Watch => 1, + VideoStatus::Cached => 2, + VideoStatus::Watched => 3, + + VideoStatus::Drop => 4, + VideoStatus::Dropped => 5, + } + } + pub fn from_db_integer(num: i64) -> Self { + match num { + 0 => Self::Pick, + + 1 => Self::Watch, + 2 => Self::Cached, + 3 => Self::Watched, + + 4 => Self::Drop, + 5 => Self::Dropped, + other => unreachable!( + "The database returned a enum discriminator, unknown to us: '{}'", + other + ), + } + } + + pub fn as_str(&self) -> &'static str { + match self { + VideoStatus::Pick => "Pick", + + VideoStatus::Watch => "Watch", + VideoStatus::Cached => "Cache", + VideoStatus::Watched => "Watched", + + VideoStatus::Drop => "Drop", + VideoStatus::Dropped => "Dropped", + } + } +} |