From 38d1cb289e0726d73792c32c4ac3366c6c38a4d9 Mon Sep 17 00:00:00 2001 From: lemon-sh Date: Thu, 6 Jan 2022 00:23:00 +0100 Subject: [PATCH] Add a basic web service --- Cargo.toml | 2 +- sample_uberbot.toml | 3 +++ src/main.rs | 10 ++++++++-- src/web_service.rs | 23 +++++++++++++++++++++++ 4 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 src/web_service.rs diff --git a/Cargo.toml b/Cargo.toml index 588ef31..eef3f4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ async-circe = { git = "https://git.karx.xyz/circe/async-circe", default-features lazy_static = "1.4" sedregex = "0.2" rusqlite = { version = "0.26", features = ["bundled"] } -hyper = "0.14" +hyper = { version = "0.14", features = ["server"] } [features] tls = ["async-circe/tls"] diff --git a/sample_uberbot.toml b/sample_uberbot.toml index 0884b51..de3c2cd 100644 --- a/sample_uberbot.toml +++ b/sample_uberbot.toml @@ -11,3 +11,6 @@ spotify_client_secret = "" # Bot config prefix = "!" + +# Web service config +http_listen = "127.0.0.1:8080" diff --git a/src/main.rs b/src/main.rs index 380a94e..893540b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ mod bots; mod database; +mod web_service; use crate::database::{DbExecutor, ExecutorConnection}; use arrayvec::ArrayString; @@ -13,6 +14,7 @@ use std::fs::File; use std::io::Read; use std::thread; use std::{collections::HashMap, env}; +use std::net::SocketAddr; use tokio::select; use tracing_subscriber::EnvFilter; @@ -66,6 +68,7 @@ struct ClientConf { spotify_client_secret: String, prefix: String, db_path: Option, + http_listen: Option } #[tokio::main(flavor = "current_thread")] @@ -114,7 +117,8 @@ async fn main() -> anyhow::Result<()> { db: db_conn, }; - if let Err(e) = executor(state).await { + let http_listen = client_config.http_listen.unwrap_or_else(|| SocketAddr::from(([127, 0, 0, 1], 5000))); + if let Err(e) = executor(state, http_listen).await { tracing::error!("Error in message loop: {}", e); } @@ -126,8 +130,10 @@ async fn main() -> anyhow::Result<()> { Ok(()) } -async fn executor(mut state: AppState) -> anyhow::Result<()> { +async fn executor(mut state: AppState, http_listen: SocketAddr) -> anyhow::Result<()> { + let web_db = state.db.clone(); select! { + r = web_service::run(web_db, http_listen) => r?, r = message_loop(&mut state) => r?, _ = terminate_signal() => { tracing::info!("Sending QUIT message"); diff --git a/src/web_service.rs b/src/web_service.rs new file mode 100644 index 0000000..ce172ed --- /dev/null +++ b/src/web_service.rs @@ -0,0 +1,23 @@ +use std::net::SocketAddr; +use crate::ExecutorConnection; +use std::convert::Infallible; +use std::sync::Arc; +use hyper::{Body, Request, Response, Server}; +use hyper::service::{make_service_fn, service_fn}; + +pub async fn run(db: ExecutorConnection, listen: SocketAddr) -> anyhow::Result<()> { + let db = Arc::new(db); + + Server::bind(&listen).serve(make_service_fn(|_| { + let db = Arc::clone(&db); + async move { + Ok::<_, Infallible>(service_fn(move |r| handle(r, Arc::clone(&db)))) + } + })).await?; + + Ok(()) +} + +async fn handle(req: Request, db: Arc) -> Result, Infallible> { + Ok(Response::new(Body::from(format!("{:?}", db.get_quote(None).await)))) +}