diff --git a/src/web_service.rs b/src/web_service.rs index f827507..d557335 100644 --- a/src/web_service.rs +++ b/src/web_service.rs @@ -1,15 +1,20 @@ use crate::ExecutorConnection; +use irc::client::Client; +use reqwest::StatusCode; use serde_json::Value::Null; use std::net::SocketAddr; -use tokio::sync::mpsc::Sender; -use warp::{Filter, Reply, reply}; +use std::sync::Arc; +use tokio::sync::broadcast::Receiver; +use warp::{reply, Filter, Reply}; pub async fn run( db: ExecutorConnection, - webhook_tx: Sender, + wh_irc: Arc, + wh_channel: String, listen: SocketAddr, -) -> anyhow::Result<()> { - let quote_get = warp::get() + mut cancel: Receiver<()> +) { + let quote_get = warp::path("quotes") .and(warp::get()) .and(warp::any().map(move || db.clone())) .then(handle_get_quote); @@ -17,35 +22,48 @@ pub async fn run( let webhook_post = warp::path("webhook") .and(warp::post()) .and(warp::body::json()) - .and(warp::any().map(move || webhook_tx.clone())) + .and(warp::any().map(move || wh_irc.clone())) + .and(warp::any().map(move || wh_channel.clone())) .then(handle_webhook); let filter = quote_get.or(webhook_post); - warp::serve(filter).run(listen).await; - Ok(()) + warp::serve(filter).bind_with_graceful_shutdown(listen, async move { + let _ = cancel.recv().await; + }).1.await; + tracing::info!("Web service finished") } async fn handle_get_quote(_: ExecutorConnection) -> impl Reply { reply::html(include_str!("res/quote_tmpl.html")) } -async fn handle_webhook( - json: serde_json::Value, - tx: Sender, -) -> impl Reply { +async fn handle_webhook(json: serde_json::Value, irc: Arc, channel: String) -> impl Reply { if json["commits"] != Null { let commits = json["commits"].as_array().unwrap(); let repo = &json["repository"]["full_name"].as_str().unwrap().trim(); if commits.len() != 1 { - tx.send(format!("{} new commits on {}:", commits.len(), repo)) - .await - .expect("Failed to send string to main thread"); + if let Err(e) = irc.send_privmsg( + channel.clone(), + format!("{} new commits on {}:", commits.len(), repo), + ) { + return reply::with_status( + format!("An error has occurred: {}", e), + StatusCode::INTERNAL_SERVER_ERROR, + ) + .into_response(); + } for commit in commits { let author = &commit["author"]["name"].as_str().unwrap().trim(); let message = &commit["message"].as_str().unwrap().trim(); - tx.send(format!("{} - {}", author, message)) - .await - .expect("Failed to send string to main thread"); + if let Err(e) = + irc.send_privmsg(channel.clone(), format!("{} - {}", author, message)) + { + return reply::with_status( + format!("An error has occurred: {}", e), + StatusCode::INTERNAL_SERVER_ERROR, + ) + .into_response(); + } } } else { let author = &json["commits"][0]["author"]["name"] @@ -53,10 +71,17 @@ async fn handle_webhook( .unwrap() .trim(); let message = &json["commits"][0]["message"].as_str().unwrap().trim(); - tx.send(format!("New commit on {}: {} - {}", repo, message, author)) - .await - .expect("Failed to send string to main thread"); + if let Err(e) = irc.send_privmsg( + channel, + format!("New commit on {}: {} - {}", repo, message, author), + ) { + return reply::with_status( + format!("An error has occurred: {}", e), + StatusCode::INTERNAL_SERVER_ERROR, + ) + .into_response(); + } } } - warp::reply::with_status("Ok", warp::http::StatusCode::OK) + StatusCode::CREATED.into_response() }