2022-01-05 17:23:00 -06:00
|
|
|
use crate::ExecutorConnection;
|
2022-01-26 12:16:54 -06:00
|
|
|
use irc::client::Client;
|
|
|
|
use reqwest::StatusCode;
|
2022-01-26 05:58:49 -06:00
|
|
|
use serde_json::Value::Null;
|
2022-01-13 10:52:39 -06:00
|
|
|
use std::net::SocketAddr;
|
2022-01-26 12:16:54 -06:00
|
|
|
use std::sync::Arc;
|
2022-01-26 17:58:00 -06:00
|
|
|
use handlebars::Handlebars;
|
|
|
|
use lazy_static::lazy_static;
|
2022-01-26 12:16:54 -06:00
|
|
|
use tokio::sync::broadcast::Receiver;
|
|
|
|
use warp::{reply, Filter, Reply};
|
2022-01-26 17:58:00 -06:00
|
|
|
use serde::Serialize;
|
|
|
|
use crate::database::Quote;
|
|
|
|
|
|
|
|
lazy_static! {
|
|
|
|
static ref HANDLEBARS: Handlebars<'static> = {
|
|
|
|
let mut reg = Handlebars::new();
|
|
|
|
reg.register_template_string("quotes", include_str!("res/quote_tmpl.hbs")).unwrap();
|
|
|
|
reg
|
|
|
|
};
|
|
|
|
}
|
2022-01-05 17:23:00 -06:00
|
|
|
|
2022-01-15 10:09:46 -06:00
|
|
|
pub async fn run(
|
|
|
|
db: ExecutorConnection,
|
2022-01-26 12:16:54 -06:00
|
|
|
wh_irc: Arc<Client>,
|
|
|
|
wh_channel: String,
|
2022-01-15 10:09:46 -06:00
|
|
|
listen: SocketAddr,
|
2022-01-26 12:16:54 -06:00
|
|
|
mut cancel: Receiver<()>
|
|
|
|
) {
|
|
|
|
let quote_get = warp::path("quotes")
|
2022-01-26 10:00:27 -06:00
|
|
|
.and(warp::get())
|
|
|
|
.and(warp::any().map(move || db.clone()))
|
2022-01-26 12:34:54 -06:00
|
|
|
.map(handle_get_quote);
|
2022-01-05 17:23:00 -06:00
|
|
|
|
2022-01-26 10:00:27 -06:00
|
|
|
let webhook_post = warp::path("webhook")
|
2022-01-15 10:09:46 -06:00
|
|
|
.and(warp::post())
|
|
|
|
.and(warp::body::json())
|
2022-01-26 12:16:54 -06:00
|
|
|
.and(warp::any().map(move || wh_irc.clone()))
|
|
|
|
.and(warp::any().map(move || wh_channel.clone()))
|
2022-01-26 12:34:54 -06:00
|
|
|
.map(handle_webhook);
|
2022-01-05 17:23:00 -06:00
|
|
|
|
2022-01-26 10:00:27 -06:00
|
|
|
let filter = quote_get.or(webhook_post);
|
2022-01-26 12:16:54 -06:00
|
|
|
warp::serve(filter).bind_with_graceful_shutdown(listen, async move {
|
|
|
|
let _ = cancel.recv().await;
|
|
|
|
}).1.await;
|
2022-01-26 12:34:54 -06:00
|
|
|
tracing::info!("Web service finished");
|
2022-01-05 17:23:00 -06:00
|
|
|
}
|
|
|
|
|
2022-01-26 17:58:00 -06:00
|
|
|
#[derive(Serialize)]
|
|
|
|
struct QuotesTemplate {
|
|
|
|
quotes: Option<Vec<Quote>>
|
|
|
|
}
|
|
|
|
|
2022-01-26 12:34:54 -06:00
|
|
|
fn handle_get_quote(_: ExecutorConnection) -> impl Reply {
|
2022-01-26 17:58:00 -06:00
|
|
|
match HANDLEBARS.render("quotes", &QuotesTemplate{quotes: Some(vec![
|
|
|
|
Quote{quote:"something".into(),author:"by someone".into()},
|
|
|
|
Quote{quote:"something different".into(),author:"by someone else".into()},
|
|
|
|
Quote{quote:"something even more different".into(),author:"by nobody".into()}
|
|
|
|
])}) {
|
|
|
|
Ok(o) => reply::html(o).into_response(),
|
|
|
|
Err(e) => {
|
|
|
|
tracing::warn!("Error while rendering template: {}", e);
|
|
|
|
reply::with_status("Failed to render template", StatusCode::INTERNAL_SERVER_ERROR).into_response()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-05 17:23:00 -06:00
|
|
|
}
|
2022-01-26 05:58:49 -06:00
|
|
|
|
2022-01-26 12:34:54 -06:00
|
|
|
#[allow(clippy::needless_pass_by_value)]
|
|
|
|
fn handle_webhook(json: serde_json::Value, irc: Arc<Client>, channel: String) -> impl Reply {
|
2022-01-26 05:58:49 -06:00
|
|
|
if json["commits"] != Null {
|
|
|
|
let commits = json["commits"].as_array().unwrap();
|
|
|
|
let repo = &json["repository"]["full_name"].as_str().unwrap().trim();
|
2022-01-26 12:34:54 -06:00
|
|
|
if commits.len() == 1 {
|
|
|
|
let author = &json["commits"][0]["author"]["name"]
|
|
|
|
.as_str()
|
|
|
|
.unwrap()
|
|
|
|
.trim();
|
|
|
|
let message = &json["commits"][0]["message"].as_str().unwrap().trim();
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
} else {
|
2022-01-26 12:16:54 -06:00
|
|
|
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();
|
|
|
|
}
|
2022-01-26 05:58:49 -06:00
|
|
|
for commit in commits {
|
|
|
|
let author = &commit["author"]["name"].as_str().unwrap().trim();
|
|
|
|
let message = &commit["message"].as_str().unwrap().trim();
|
2022-01-26 12:16:54 -06:00
|
|
|
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();
|
|
|
|
}
|
2022-01-26 05:58:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-01-26 12:16:54 -06:00
|
|
|
StatusCode::CREATED.into_response()
|
2022-01-26 05:58:49 -06:00
|
|
|
}
|