From b449a900fe85830b85e127f570552d3b20424df6 Mon Sep 17 00:00:00 2001 From: Patrick Cleavelin Date: Tue, 1 Aug 2023 15:44:07 -0500 Subject: [PATCH] add youtube-dl upload widget --- src/main.rs | 1 + src/page.rs | 30 ++++++++++++++++++++++++++ src/routes.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) diff --git a/src/main.rs b/src/main.rs index cab4cee..cb038ca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -148,6 +148,7 @@ fn spawn_api(settings: Arc>) { "/v2/intros/remove/:guild_id/:channel", post(routes::v2_remove_intro_from_user), ) + .route("/v2/intros/:guild/add", get(routes::v2_add_guild_intro)) .route( "/v2/intros/:guild/upload", post(routes::v2_upload_guild_intro), diff --git a/src/page.rs b/src/page.rs index 6b3928d..db574f9 100644 --- a/src/page.rs +++ b/src/page.rs @@ -145,6 +145,13 @@ pub(crate) async fn guild_dashboard( .push_builder(upload_form(&state.origin, guild_id)) }) }) + .builder(Tag::Div, |b| { + b.attribute("class", "container") + .builder(Tag::Article, |b| { + b.builder_text(Tag::Header, "Upload New Intro from Url") + .push_builder(ytdl_form(&state.origin, guild_id)) + }) + }) } else { b }; @@ -231,6 +238,29 @@ fn upload_form(origin: &str, guild_id: u64) -> HtmxBuilder { }) } +fn ytdl_form(origin: &str, guild_id: u64) -> HtmxBuilder { + HtmxBuilder::new(Tag::Empty).form(|b| { + b.attribute("class", "container") + .hx_get(&format!("{}/v2/intros/{}/add", origin, guild_id)) + .builder(Tag::FieldSet, |b| { + b.attribute("class", "container") + .label(|b| { + b.text("Video Url").input(|b| { + b.attribute("placeholder", "enter video url") + .attribute("name", "url") + }) + }) + .label(|b| { + b.text("Intro Title").input(|b| { + b.attribute("placeholder", "enter intro title") + .attribute("name", "name") + }) + }) + }) + .button(|b| b.attribute("type", "submit").text("Upload")) + }) +} + fn moderator_dashboard(state: &ApiState) -> HtmxBuilder { HtmxBuilder::new(Tag::Empty).link("Go back to old UI", &format!("{}/old", state.origin)) } diff --git a/src/routes.rs b/src/routes.rs index 96cdd5b..b6e927e 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -747,6 +747,65 @@ pub(crate) async fn add_guild_intro( Ok(()) } +pub(crate) async fn v2_add_guild_intro( + State(state): State, + Path(guild): Path, + Query(mut params): Query>, + user: User, +) -> Result { + let mut settings = state.settings.lock().await; + let Some(url) = params.remove("url") else { + return Err(Error::InvalidRequest); + }; + let Some(friendly_name) = params.remove("name") else { + return Err(Error::InvalidRequest); + }; + + { + let Some(guild) = settings.guilds.get(&guild) else { + return Err(Error::NoGuildFound); + }; + let Some(guild_user) = guild.users.get(&user.name) else { + return Err(Error::NoUserFound); + }; + + if !guild_user.permissions.can(auth::Permission::UploadSounds) { + return Err(Error::InvalidPermission); + } + } + + let Some(guild) = settings.guilds.get_mut(&guild) else { + return Err(Error::NoGuildFound); + }; + + let uuid = Uuid::new_v4().to_string(); + let child = tokio::process::Command::new("yt-dlp") + .arg(&url) + .args(["-o", &format!("sounds/{uuid}")]) + .args(["-x", "--audio-format", "mp3"]) + .spawn() + .map_err(Error::Ytdl)? + .wait() + .await + .map_err(Error::Ytdl)?; + + if !child.success() { + return Err(Error::YtdlTerminated); + } + + guild.intros.insert( + uuid.clone(), + Intro::File(FileIntro { + filename: format!("{uuid}.mp3"), + friendly_name, + }), + ); + + let mut headers = HeaderMap::new(); + headers.insert("HX-Refresh", HeaderValue::from_static("true")); + Ok(headers) +} + pub(crate) async fn delete_guild_intro( State(state): State, Path(guild): Path,