about summary refs log tree commit diff stats
path: root/src/storage/video_database/getters.rs
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-10-14 14:56:29 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-10-14 14:56:29 +0200
commit6c9286857ef8b314962b67f4a16a66e8c35531bc (patch)
tree9ced4485ec38b39f82cba258c06321a21c40000a /src/storage/video_database/getters.rs
parentbuild(Cargo.toml): Add further lints (diff)
downloadyt-6c9286857ef8b314962b67f4a16a66e8c35531bc.tar.gz
yt-6c9286857ef8b314962b67f4a16a66e8c35531bc.zip
refactor(treewide): Combine the separate crates in one workspace
Diffstat (limited to 'src/storage/video_database/getters.rs')
-rw-r--r--src/storage/video_database/getters.rs345
1 files changed, 0 insertions, 345 deletions
diff --git a/src/storage/video_database/getters.rs b/src/storage/video_database/getters.rs
deleted file mode 100644
index 29dd014..0000000
--- a/src/storage/video_database/getters.rs
+++ /dev/null
@@ -1,345 +0,0 @@
-// 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>.
-
-//! These functions interact with the storage db in a read-only way. They are added on-demaned (as
-//! you could theoretically just could do everything with the `get_videos` function), as
-//! performance or convince requires.
-use std::{fs::File, path::PathBuf};
-
-use anyhow::{bail, Context, Result};
-use blake3::Hash;
-use log::debug;
-use sqlx::{query, QueryBuilder, Row, Sqlite};
-use url::Url;
-use yt_dlp::wrapper::info_json::InfoJson;
-
-use crate::{
-    app::App,
-    storage::{
-        subscriptions::Subscription,
-        video_database::{extractor_hash::ExtractorHash, Video},
-    },
-};
-
-use super::{MpvOptions, VideoOptions, VideoStatus, YtDlpOptions};
-
-macro_rules! video_from_record {
-    ($record:expr) => {
-        let thumbnail_url = if let Some(url) = &$record.thumbnail_url {
-            Some(Url::parse(&url).expect("Parsing this as url should always work"))
-        } else {
-            None
-        };
-
-        Ok(Video {
-            cache_path: $record.cache_path.as_ref().map(|val| PathBuf::from(val)),
-            description: $record.description.clone(),
-            duration: $record.duration,
-            extractor_hash: ExtractorHash::from_hash(
-                $record
-                    .extractor_hash
-                    .parse()
-                    .expect("The db hash should be a valid blake3 hash"),
-            ),
-            last_status_change: $record.last_status_change,
-            parent_subscription_name: $record.parent_subscription_name.clone(),
-            publish_date: $record.publish_date,
-            status: VideoStatus::from_db_integer($record.status),
-            thumbnail_url,
-            title: $record.title.clone(),
-            url: Url::parse(&$record.url).expect("Parsing this as url should always work"),
-            priority: $record.priority,
-            status_change: if $record.status_change == 1 {
-                true
-            } else {
-                assert_eq!($record.status_change, 0);
-                false
-            },
-        })
-    };
-}
-
-/// Get the lines to display at the selection file
-/// [`changing` = true]: Means that we include *only* videos, that have the `status_changing` flag set
-/// [`changing` = None]: Means that we include *both* videos, that have the `status_changing` flag set and not set
-pub async fn get_videos(
-    app: &App,
-    allowed_states: &[VideoStatus],
-    changing: Option<bool>,
-) -> Result<Vec<Video>> {
-    let mut qb: QueryBuilder<Sqlite> = QueryBuilder::new(
-        "\
-    SELECT *
-    FROM videos
-    WHERE status IN ",
-    );
-
-    qb.push("(");
-    allowed_states
-        .iter()
-        .enumerate()
-        .for_each(|(index, state)| {
-            qb.push("'");
-            qb.push(state.as_db_integer());
-            qb.push("'");
-
-            if index != allowed_states.len() - 1 {
-                qb.push(",");
-            }
-        });
-    qb.push(")");
-
-    if let Some(val) = changing {
-        if val {
-            qb.push(" AND status_change = 1");
-        } else {
-            qb.push(" AND status_change = 0");
-        }
-    }
-
-    qb.push("\n    ORDER BY priority DESC, publish_date DESC;");
-
-    debug!("Will run: \"{}\"", qb.sql());
-
-    let videos = qb.build().fetch_all(&app.database).await.with_context(|| {
-        format!(
-            "Failed to query videos with states: '{}'",
-            allowed_states.iter().fold(String::new(), |mut acc, state| {
-                acc.push(' ');
-                acc.push_str(state.as_str());
-                acc
-            }),
-        )
-    })?;
-
-    let real_videos: Vec<Video> = videos
-        .iter()
-        .map(|base| -> Result<Video> {
-            Ok(Video {
-                cache_path: base
-                    .get::<Option<String>, &str>("cache_path")
-                    .as_ref()
-                    .map(PathBuf::from),
-                description: base.get::<Option<String>, &str>("description").clone(),
-                duration: base.get("duration"),
-                extractor_hash: ExtractorHash::from_hash(
-                    base.get::<String, &str>("extractor_hash")
-                        .parse()
-                        .expect("The db hash should be a valid blake3 hash"),
-                ),
-                last_status_change: base.get("last_status_change"),
-                parent_subscription_name: base
-                    .get::<Option<String>, &str>("parent_subscription_name")
-                    .clone(),
-                publish_date: base.get("publish_date"),
-                status: VideoStatus::from_db_integer(base.get("status")),
-                thumbnail_url: base
-                    .get::<Option<String>, &str>("thumbnail_url")
-                    .as_ref()
-                    .map(|url| Url::parse(url).expect("Parsing this as url should always work")),
-                title: base.get::<String, &str>("title").to_owned(),
-                url: Url::parse(base.get("url")).expect("Parsing this as url should always work"),
-                priority: base.get("priority"),
-                status_change: {
-                    let val = base.get::<i64, &str>("status_change");
-                    if val == 1 {
-                        true
-                    } else {
-                        assert_eq!(val, 0, "Can only be 1 or 0");
-                        false
-                    }
-                },
-            })
-        })
-        .collect::<Result<Vec<Video>>>()?;
-
-    Ok(real_videos)
-}
-
-pub async fn get_video_info_json(video: &Video) -> Result<Option<InfoJson>> {
-    if let Some(mut path) = video.cache_path.clone() {
-        if !path.set_extension("info.json") {
-            bail!(
-                "Failed to change path extension to 'info.json': {}",
-                path.display()
-            );
-        }
-        let info_json_string = File::open(path)?;
-        let info_json: InfoJson = serde_json::from_reader(&info_json_string)?;
-
-        Ok(Some(info_json))
-    } else {
-        Ok(None)
-    }
-}
-
-pub async fn get_video_by_hash(app: &App, hash: &ExtractorHash) -> Result<Video> {
-    let ehash = hash.hash().to_string();
-
-    let raw_video = query!(
-        "
-        SELECT * FROM videos WHERE extractor_hash = ?;
-        ",
-        ehash
-    )
-    .fetch_one(&app.database)
-    .await?;
-
-    video_from_record! {raw_video}
-}
-
-pub async fn get_currently_playing_video(app: &App) -> Result<Option<Video>> {
-    let mut videos: Vec<Video> = get_changing_videos(app, VideoStatus::Cached).await?;
-
-    if videos.is_empty() {
-        Ok(None)
-    } else {
-        assert_eq!(
-            videos.len(),
-            1,
-            "Only one video can change from cached to watched at once!"
-        );
-
-        Ok(Some(videos.remove(0)))
-    }
-}
-
-pub async fn get_changing_videos(app: &App, old_state: VideoStatus) -> Result<Vec<Video>> {
-    let status = old_state.as_db_integer();
-
-    let matching = query!(
-        r#"
-        SELECT *
-        FROM videos
-        WHERE status_change = 1 AND status = ?;
-    "#,
-        status
-    )
-    .fetch_all(&app.database)
-    .await?;
-
-    let real_videos: Vec<Video> = matching
-        .iter()
-        .map(|base| -> Result<Video> {
-            video_from_record! {base}
-        })
-        .collect::<Result<Vec<Video>>>()?;
-
-    Ok(real_videos)
-}
-
-pub async fn get_all_hashes(app: &App) -> Result<Vec<Hash>> {
-    let hashes_hex = query!(
-        r#"
-        SELECT extractor_hash
-        FROM videos;
-    "#
-    )
-    .fetch_all(&app.database)
-    .await?;
-
-    Ok(hashes_hex
-        .iter()
-        .map(|hash| {
-            Hash::from_hex(&hash.extractor_hash)
-                .expect("These values started as blake3 hashes, they should stay blake3 hashes")
-        })
-        .collect())
-}
-
-pub async fn get_video_hashes(app: &App, subs: &Subscription) -> Result<Vec<Hash>> {
-    let hashes_hex = query!(
-        r#"
-        SELECT extractor_hash
-        FROM videos
-        WHERE parent_subscription_name = ?;
-    "#,
-        subs.name
-    )
-    .fetch_all(&app.database)
-    .await?;
-
-    Ok(hashes_hex
-        .iter()
-        .map(|hash| {
-            Hash::from_hex(&hash.extractor_hash)
-                .expect("These values started as blake3 hashes, they should stay blake3 hashes")
-        })
-        .collect())
-}
-
-pub async fn get_video_yt_dlp_opts(app: &App, hash: &ExtractorHash) -> Result<YtDlpOptions> {
-    let ehash = hash.hash().to_string();
-
-    let yt_dlp_options = query!(
-        r#"
-        SELECT subtitle_langs
-        FROM video_options
-        WHERE extractor_hash = ?;
-    "#,
-        ehash
-    )
-    .fetch_one(&app.database)
-    .await
-    .with_context(|| {
-        format!(
-            "Failed to fetch the `yt_dlp_video_opts` for video: {}",
-            hash
-        )
-    })?;
-
-    Ok(YtDlpOptions {
-        subtitle_langs: yt_dlp_options.subtitle_langs,
-    })
-}
-pub async fn get_video_mpv_opts(app: &App, hash: &ExtractorHash) -> Result<MpvOptions> {
-    let ehash = hash.hash().to_string();
-
-    let mpv_options = query!(
-        r#"
-        SELECT playback_speed
-        FROM video_options
-        WHERE extractor_hash = ?;
-    "#,
-        ehash
-    )
-    .fetch_one(&app.database)
-    .await
-    .with_context(|| format!("Failed to fetch the `mpv_video_opts` for video: {}", hash))?;
-
-    Ok(MpvOptions {
-        playback_speed: mpv_options.playback_speed,
-    })
-}
-
-pub async fn get_video_opts(app: &App, hash: &ExtractorHash) -> Result<VideoOptions> {
-    let ehash = hash.hash().to_string();
-
-    let opts = query!(
-        r#"
-        SELECT playback_speed, subtitle_langs
-        FROM video_options
-        WHERE extractor_hash = ?;
-    "#,
-        ehash
-    )
-    .fetch_one(&app.database)
-    .await
-    .with_context(|| format!("Failed to fetch the `video_opts` for video: {}", hash))?;
-
-    let mpv = MpvOptions {
-        playback_speed: opts.playback_speed,
-    };
-    let yt_dlp = YtDlpOptions {
-        subtitle_langs: opts.subtitle_langs,
-    };
-
-    Ok(VideoOptions { mpv, yt_dlp })
-}