From 20fdd480dd37bde59095fe2f0c9a0a26890f4fd6 Mon Sep 17 00:00:00 2001 From: Andy Killorin <37423245+Speedy6451@users.noreply.github.com> Date: Fri, 6 Dec 2024 01:20:30 -0500 Subject: [PATCH] frontend --- outside/src/auth.rs | 2 + server/Cargo.lock | 307 ++++++++++++++++++++++++++++++++++++++++++++ server/Cargo.toml | 1 + server/src/main.rs | 154 +++++++++++++++++++--- 4 files changed, 448 insertions(+), 16 deletions(-) diff --git a/outside/src/auth.rs b/outside/src/auth.rs index 1977417..d9259ac 100644 --- a/outside/src/auth.rs +++ b/outside/src/auth.rs @@ -27,6 +27,8 @@ impl Authorized for Name { Name::Andy => true, Name::Evan => true, Name::Michael => true, + Name::Felix => true, + Name::Phil => true, _ => false, } } diff --git a/server/Cargo.lock b/server/Cargo.lock index c3e2c19..f0ef608 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -23,6 +23,17 @@ version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "atomic-polyfill" version = "1.0.3" @@ -38,6 +49,61 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "axum" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 1.0.2", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -132,6 +198,54 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + [[package]] name = "gimli" version = "0.31.1" @@ -161,6 +275,87 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "http" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", +] + +[[package]] +name = "hyper-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "tokio", + "tower-service", +] + [[package]] name = "itoa" version = "1.0.14" @@ -195,12 +390,24 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "miniz_oxide" version = "0.8.0" @@ -281,12 +488,24 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + [[package]] name = "pin-project-lite" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "postcard" version = "1.1.1" @@ -348,6 +567,18 @@ dependencies = [ "semver", ] +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + [[package]] name = "scopeguard" version = "1.2.0" @@ -380,11 +611,46 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +dependencies = [ + "itoa", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "server" version = "0.1.0" dependencies = [ "anyhow", + "axum", "common", "postcard", "serde", @@ -454,6 +720,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + [[package]] name = "thiserror" version = "1.0.69" @@ -544,12 +822,41 @@ dependencies = [ "syn", ] +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + [[package]] name = "tracing" version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", diff --git a/server/Cargo.toml b/server/Cargo.toml index 022483e..acd12bd 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] anyhow = "1.0.94" +axum = "0.7.9" common = {path = "../common"} postcard = {version = "1.0.0", features = ["alloc"]} serde = "*" diff --git a/server/src/main.rs b/server/src/main.rs index 2e5270a..c827817 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,7 +1,8 @@ use std::{sync::Arc, time::Duration}; -use common::Request; +use axum::{extract::State, http::StatusCode, response::Html, routing::{get, post}, serve, Form, Router}; +use common::{Name, Request}; use postcard::to_allocvec; use tokio::{fs, io::{AsyncReadExt, AsyncWriteExt}, net::TcpStream, sync::{RwLock, Semaphore}, time::{self, sleep, Instant}}; use anyhow::{Ok, Result}; @@ -10,6 +11,12 @@ use tracing_subscriber::{filter, layer::{Filter, SubscriberExt}, util::Subscribe const FISH: &'static str = "169.254.2.1:1234"; +#[derive(Clone)] +struct AppState { + fish: Arc, + last_badge: Arc>, +} + #[tokio::main] async fn main() -> Result<()>{ let log = fs::OpenOptions::new().append(true).create(true).open("john.log").await?; @@ -42,6 +49,24 @@ async fn main() -> Result<()>{ info!("starting"); + + let app: Router = Router::new() + .route("/", get(root)) + .route("/phil", get(phil)) + .route("/recent", get(recent_badge)) + .route("/setLast", post(set_last)) + //.route("/map", post(set_badge)) + .with_state(AppState { + fish: fish.clone(), + last_badge: last_badge.clone() + }); + + let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap(); + + tokio::spawn(async {serve(listener, app).await.unwrap()}); + + + let fish_ = fish.clone(); tokio::spawn(async move { loop { @@ -57,26 +82,30 @@ async fn main() -> Result<()>{ } }); - let _permit = fish.acquire().await?; - let mut conn = TcpStream::connect(FISH).await?; + { + let _permit = fish.acquire().await?; + let mut conn = TcpStream::connect(FISH).await?; - let req = Request::RecentBadge; - conn.write_all(&to_allocvec(&req)?).await?; - conn.flush().await?; - - let badge = conn.read_u64().await?; - info!("read: {badge}"); - - if badge != 0 { - let req = Request::SetBadge(common::Name::Evan, badge); + let req = Request::RecentBadge; conn.write_all(&to_allocvec(&req)?).await?; conn.flush().await?; + + let badge = conn.read_u64().await?; + info!("read: {badge}"); + + if badge != 0 { + let req = Request::SetBadge(common::Name::Evan, badge); + conn.write_all(&to_allocvec(&req)?).await?; + conn.flush().await?; + } + + let req = Request::SetVolume(30); + conn.write_all(&to_allocvec(&req)?).await?; } - let req = Request::SetVolume(23); - conn.write_all(&to_allocvec(&req)?).await?; - - Ok(()) + loop { + sleep(Duration::from_secs(2)).await; + } } async fn get_recent_badge(fish: Arc) -> Result { @@ -96,3 +125,96 @@ async fn get_recent_badge(fish: Arc) -> Result { Err(anyhow::anyhow!("no badge present")) } } + +async fn root(state: State) -> Html { + let (last_badge, time) = *state.last_badge.read().await; + let time = time.elapsed(); + + let mut page = format!(r#" +

+ most recent badge {last_badge:#0x}
+ {time:?} ago +

+

set last badge

+ "#); + + for name in [ + "Tess", + "Amaia", + "Prueky", + "David", + "Nathaniel", + "Thia", + "Michael", + "Zoey", + ] { + page.push_str(&format!(r#" +
+ +
+ "#)); + } + Html::from(page) +} + +#[derive(serde::Deserialize)] +struct NameForm { + name: String, +} + +async fn set_last( + state: State, + Form(input): Form) -> Html { + + let name_e = match input.name.as_str() { + "Tess" => Name::Tess, + "Amaia" => Name::Amaia, + "Prueky" => Name::Prueky, + "David" => Name::David, + "Nathaniel" => Name::Nathaniel, + "Thia" => Name::Thia, + "Michael" => Name::Michael, + "Zoey" => Name::Zoey, + _ => Name::Unknown, + + }; + + let (last_badge, _) = *state.last_badge.read().await; + info!("setting {} ({name_e:?}) to {last_badge:#0x}", input.name); + let _fish = state.fish.acquire().await.unwrap(); + let mut conn = TcpStream::connect(FISH).await.unwrap(); + + if last_badge == 0 { + return Html::from("

failed, no badge scanned

".to_string()); + } + + let req = Request::SetBadge(name_e, last_badge); + conn.write_all(&to_allocvec(&req).unwrap()).await.unwrap(); + conn.flush().await.unwrap(); + + + Html::from(format!("

{last_badge:#0x} is now {}


back", input.name)) +} + +async fn recent_badge(state: State) -> String { + let (last_badge, time) = *state.last_badge.read().await; + format!("id: {last_badge:#0x}, scanned {:?} ago", time.elapsed()) +} + +async fn phil(state: State) -> String { + let _fish = state.fish.acquire().await.unwrap(); + let (last_badge, time) = *state.last_badge.read().await; + info!("id: {last_badge:#0x}, scanned {:?} ago", time.elapsed()); + let mut conn = TcpStream::connect(FISH).await.unwrap(); + + if last_badge != 0 { + let req = Request::SetBadge(common::Name::Phil, last_badge); + conn.write_all(&to_allocvec(&req).unwrap()).await.unwrap(); + conn.flush().await.unwrap(); + } + + + String::from(format!("{last_badge:#0x} is now phil")) + +} +