diff --git a/src/client.rs b/src/client.rs index 2c05ed7..cba4ee4 100644 --- a/src/client.rs +++ b/src/client.rs @@ -3,7 +3,7 @@ use crate::twitch::TwitchClient; use std::path::Path; use twba_local_db::prelude::*; use twba_local_db::re_exports::sea_orm::ActiveValue::Set; -use twba_local_db::re_exports::sea_orm::{ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel, QueryFilter, QuerySelect}; +use twba_local_db::re_exports::sea_orm::{ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel, QueryFilter, QueryOrder, QuerySelect}; #[derive(Debug)] pub struct DownloaderClient { @@ -22,6 +22,7 @@ impl DownloaderClient { Path::new(self.twitch_client.config.download_folder_path.as_str()); let videos = Videos::find() .filter(VideosColumn::Status.eq(Status::NotStarted)) + .order_by_asc(VideosColumn::CreatedAt) .limit(self.twitch_client.config.max_items_to_process) .all(&self.db) .await?; diff --git a/src/main.rs b/src/main.rs index 98c621a..300695f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,9 @@ -pub mod prelude; - -use twba_backup_config::get_default_builder; use prelude::*; +use twba_backup_config::get_default_builder; +use twba_local_db::prelude::{Status, Videos, VideosColumn}; pub mod client; mod errors; +pub mod prelude; pub mod twitch; #[tokio::main] @@ -26,18 +26,36 @@ async fn main() -> Result<()> { #[tracing::instrument] async fn run() -> Result<()> { - let conf = get_default_builder() - .load() - .map_err(|e| { - error!("Failed to load config: {:?}", e); - DownloaderError::LoadConfig(e.into()) - })?; + let conf = get_default_builder().load().map_err(|e| { + error!("Failed to load config: {:?}", e); + DownloaderError::LoadConfig(e.into()) + })?; let db = twba_local_db::open_database(Some(&conf.db_url)).await?; twba_local_db::migrate_db(&db).await?; // local_db::print_db(&db).await?; dbg!(&conf); + let amount_of_downloaded_but_not_uploaded_videos = + get_amount_of_downloaded_but_not_uploaded_videos(&db).await?; + //TODO: make configurable + if amount_of_downloaded_but_not_uploaded_videos >= 3 { + info!( + "There are {} videos that are downloaded but not uploaded. Not downloading anything to prevent taking up all the space.", + amount_of_downloaded_but_not_uploaded_videos + ); + return Ok(()); + } else { + info!( + "There are {} videos that are downloaded but not uploaded. Downloading more videos.", + amount_of_downloaded_but_not_uploaded_videos + ); + } + // let continue_ = wait_for_user().unwrap_or(true); + // if !continue_ { + // info!("Quitting because user requested it."); + // return Ok(()); + // } let twitch_client = twitch::TwitchClient::new(conf); let client = client::DownloaderClient::new(twitch_client, db); @@ -45,3 +63,38 @@ async fn run() -> Result<()> { Ok(()) } + +async fn get_amount_of_downloaded_but_not_uploaded_videos(db: &C) -> Result +where + C: twba_local_db::re_exports::sea_orm::ConnectionTrait, +{ + use twba_local_db::re_exports::sea_orm::*; + Ok(Videos::find() + .filter(VideosColumn::Status.between(Status::Downloading, Status::Uploading)) + .order_by_asc(VideosColumn::CreatedAt) + .count(db) + .await?) +} + +pub fn wait_for_user() -> StdResult> { + use std::io::{self, Write}; + loop { + print!("Press Enter to continue or 'q' to quit: "); + io::stdout().flush()?; // Make sure the prompt is immediately displayed + + let mut input = String::new(); + io::stdin().read_line(&mut input)?; + + match input.trim() { + "" => return Ok(true), // User pressed Enter + "q" => { + println!("Quitting..."); + return Ok(false); + } + _ => { + println!("Invalid input. Please try again."); + continue; + } // Any other input, repeat the loop + } + } +} diff --git a/src/prelude.rs b/src/prelude.rs index 8f71c3d..1f0ba0b 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -4,9 +4,10 @@ use std::fmt::Debug; pub(crate) use tracing::{debug, error, info, trace, warn}; pub(crate) use twba_backup_config::prelude::*; +pub(crate) use std::error::Error as StdError; pub(crate) use std::result::Result as StdResult; -/// Just a wrapper around Into that implements Debug. +/// Just a wrapper around Into\ that implements Debug. /// /// This is just for convenience so we dont need to write /// '`impl Into + Debug`' everywhere. diff --git a/src/twitch/mod.rs b/src/twitch/mod.rs index 05fde8d..2637ead 100644 --- a/src/twitch/mod.rs +++ b/src/twitch/mod.rs @@ -43,7 +43,7 @@ impl TwitchClient { ) -> Result { let video_id = video_id.into(); let folder_path = output_folder.join(id.to_string()); - let final_path = output_folder.join(format!("{}.mp4", video_id)); + let final_path = output_folder.join(format!("{}.mp4", id)); if final_path.exists() { return Err(DownloadFileError::TargetAlreadyExists(final_path).into()); }