about summary refs log tree commit diff stats
path: root/src/main.rs
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-08-21 10:49:23 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-08-21 11:28:43 +0200
commit1debeb77f7986de1b659dcfdc442de6415e1d9f5 (patch)
tree4df3e7c3f6a2d1ec116e4088c5ace7f143a8b05f /src/main.rs
downloadyt-1debeb77f7986de1b659dcfdc442de6415e1d9f5.tar.gz
yt-1debeb77f7986de1b659dcfdc442de6415e1d9f5.zip
chore: Initial Commit
This repository was migrated out of my nixos-config.
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..cfd6adc
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,163 @@
+// 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::{collections::HashMap, fs};
+
+use anyhow::{bail, Context, Result};
+use app::App;
+use cache::invalidate;
+use clap::Parser;
+use cli::{CacheCommand, CheckCommand, SelectCommand, SubscriptionCommand};
+use select::cmds::handle_select_cmd;
+use tokio::{
+    fs::File,
+    io::{stdin, BufReader},
+};
+use url::Url;
+use yt_dlp::wrapper::info_json::InfoJson;
+
+use crate::{cli::Command, storage::subscriptions::get_subscriptions};
+
+pub mod app;
+pub mod cli;
+
+pub mod cache;
+pub mod comments;
+pub mod constants;
+pub mod download;
+pub mod select;
+pub mod status;
+pub mod storage;
+pub mod subscribe;
+pub mod update;
+pub mod watch;
+
+#[tokio::main]
+async fn main() -> Result<()> {
+    let args = cli::CliArgs::parse();
+    stderrlog::new()
+        .module(module_path!())
+        .modules(&["yt_dlp".to_owned(), "libmpv2".to_owned()])
+        .quiet(args.quiet)
+        .show_module_names(false)
+        .color(stderrlog::ColorChoice::Auto)
+        .verbosity(args.verbosity as usize)
+        .timestamp(stderrlog::Timestamp::Off)
+        .init()
+        .expect("Let's just hope that this does not panic");
+
+    let app = App::new().await?;
+
+    match args.command.unwrap_or(Command::default()) {
+        Command::Download { force } => {
+            if force {
+                invalidate(&app, true).await?;
+            }
+
+            download::Downloader::new().consume(&app).await?;
+        }
+        Command::Select { cmd } => {
+            let cmd = cmd.unwrap_or(SelectCommand::default());
+
+            match cmd {
+                SelectCommand::File { done } => select::select(&app, done).await?,
+                _ => handle_select_cmd(&app, cmd, None).await?,
+            }
+        }
+        Command::Update {
+            max_backlog,
+            subscriptions,
+            concurrent_processes,
+        } => {
+            let all_subs = get_subscriptions(&app).await?;
+
+            for sub in &subscriptions {
+                if let None = all_subs.0.get(sub) {
+                    bail!(
+                        "Your specified subscription to update '{}' is not a subscription!",
+                        sub
+                    )
+                }
+            }
+
+            update::update(&app, max_backlog, subscriptions, concurrent_processes).await?;
+        }
+
+        Command::Subscriptions { cmd } => match cmd {
+            SubscriptionCommand::Add { name, url } => {
+                subscribe::subscribe(&app, name, url)
+                    .await
+                    .context("Failed to add a subscription")?;
+            }
+            SubscriptionCommand::Remove { name } => {
+                subscribe::unsubscribe(&app, name)
+                    .await
+                    .context("Failed to remove a subscription")?;
+            }
+            SubscriptionCommand::List { url } => {
+                let all_subs = get_subscriptions(&app).await?;
+
+                if url {
+                    for val in all_subs.0.values() {
+                        println!("{}", val.url);
+                    }
+                } else {
+                    for (key, val) in all_subs.0 {
+                        println!("{}: '{}'", key, val.url);
+                    }
+                }
+            }
+            SubscriptionCommand::Import { file, force } => {
+                if let Some(file) = file {
+                    let f = File::open(file).await?;
+
+                    subscribe::import(&app, BufReader::new(f), force).await?
+                } else {
+                    subscribe::import(&app, BufReader::new(stdin()), force).await?
+                };
+            }
+        },
+
+        Command::Watch {} => watch::watch(&app).await?,
+
+        Command::Status {} => status::show(&app).await?,
+
+        Command::Database { command } => match command {
+            CacheCommand::Invalidate { hard } => cache::invalidate(&app, hard).await?,
+            CacheCommand::Maintain { all } => cache::maintain(&app, all).await?,
+        },
+
+        Command::Check { command } => match command {
+            CheckCommand::InfoJson { path } => {
+                let string = fs::read_to_string(&path)
+                    .with_context(|| format!("Failed to read '{}' to string!", path.display()))?;
+
+                let _: InfoJson =
+                    serde_json::from_str(&string).context("Failed to deserialize value")?;
+            }
+            CheckCommand::UpdateInfoJson { path } => {
+                let string = fs::read_to_string(&path)
+                    .with_context(|| format!("Failed to read '{}' to string!", path.display()))?;
+
+                let _: HashMap<Url, InfoJson> =
+                    serde_json::from_str(&string).context("Failed to deserialize value")?;
+            }
+        },
+        Command::Comments {} => {
+            comments::comments(&app).await?;
+        }
+        Command::Description {} => {
+            todo!()
+            // description::description(&app).await?;
+        }
+    }
+
+    Ok(())
+}