This commit is contained in:
Andy Killorin 2024-12-06 01:20:30 -05:00
parent 1b140607d7
commit 20fdd480dd
Signed by: ank
GPG key ID: 23F9463ECB67FE8C
4 changed files with 448 additions and 16 deletions

View file

@ -27,6 +27,8 @@ impl Authorized for Name {
Name::Andy => true, Name::Andy => true,
Name::Evan => true, Name::Evan => true,
Name::Michael => true, Name::Michael => true,
Name::Felix => true,
Name::Phil => true,
_ => false, _ => false,
} }
} }

307
server/Cargo.lock generated
View file

@ -23,6 +23,17 @@ version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" 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]] [[package]]
name = "atomic-polyfill" name = "atomic-polyfill"
version = "1.0.3" version = "1.0.3"
@ -38,6 +49,61 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 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]] [[package]]
name = "backtrace" name = "backtrace"
version = "0.3.74" version = "0.3.74"
@ -132,6 +198,54 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" 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]] [[package]]
name = "gimli" name = "gimli"
version = "0.31.1" version = "0.31.1"
@ -161,6 +275,87 @@ dependencies = [
"stable_deref_trait", "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]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.14" version = "1.0.14"
@ -195,12 +390,24 @@ version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "matchit"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.4" version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "mime"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.8.0" version = "0.8.0"
@ -281,12 +488,24 @@ dependencies = [
"windows-targets", "windows-targets",
] ]
[[package]]
name = "percent-encoding"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.15" version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]] [[package]]
name = "postcard" name = "postcard"
version = "1.1.1" version = "1.1.1"
@ -348,6 +567,18 @@ dependencies = [
"semver", "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]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
@ -380,11 +611,46 @@ dependencies = [
"syn", "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]] [[package]]
name = "server" name = "server"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"axum",
"common", "common",
"postcard", "postcard",
"serde", "serde",
@ -454,6 +720,18 @@ dependencies = [
"unicode-ident", "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]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.69" version = "1.0.69"
@ -544,12 +822,41 @@ dependencies = [
"syn", "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]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.41" version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [ dependencies = [
"log",
"pin-project-lite", "pin-project-lite",
"tracing-attributes", "tracing-attributes",
"tracing-core", "tracing-core",

View file

@ -5,6 +5,7 @@ edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.94" anyhow = "1.0.94"
axum = "0.7.9"
common = {path = "../common"} common = {path = "../common"}
postcard = {version = "1.0.0", features = ["alloc"]} postcard = {version = "1.0.0", features = ["alloc"]}
serde = "*" serde = "*"

View file

@ -1,7 +1,8 @@
use std::{sync::Arc, time::Duration}; 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 postcard::to_allocvec;
use tokio::{fs, io::{AsyncReadExt, AsyncWriteExt}, net::TcpStream, sync::{RwLock, Semaphore}, time::{self, sleep, Instant}}; use tokio::{fs, io::{AsyncReadExt, AsyncWriteExt}, net::TcpStream, sync::{RwLock, Semaphore}, time::{self, sleep, Instant}};
use anyhow::{Ok, Result}; 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"; const FISH: &'static str = "169.254.2.1:1234";
#[derive(Clone)]
struct AppState {
fish: Arc<Semaphore>,
last_badge: Arc<RwLock<(u64,Instant)>>,
}
#[tokio::main] #[tokio::main]
async fn main() -> Result<()>{ async fn main() -> Result<()>{
let log = fs::OpenOptions::new().append(true).create(true).open("john.log").await?; let log = fs::OpenOptions::new().append(true).create(true).open("john.log").await?;
@ -42,6 +49,24 @@ async fn main() -> Result<()>{
info!("starting"); 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(); let fish_ = fish.clone();
tokio::spawn(async move { tokio::spawn(async move {
loop { loop {
@ -57,6 +82,7 @@ async fn main() -> Result<()>{
} }
}); });
{
let _permit = fish.acquire().await?; let _permit = fish.acquire().await?;
let mut conn = TcpStream::connect(FISH).await?; let mut conn = TcpStream::connect(FISH).await?;
@ -73,10 +99,13 @@ async fn main() -> Result<()>{
conn.flush().await?; conn.flush().await?;
} }
let req = Request::SetVolume(23); let req = Request::SetVolume(30);
conn.write_all(&to_allocvec(&req)?).await?; conn.write_all(&to_allocvec(&req)?).await?;
}
Ok(()) loop {
sleep(Duration::from_secs(2)).await;
}
} }
async fn get_recent_badge(fish: Arc<Semaphore>) -> Result<u64> { async fn get_recent_badge(fish: Arc<Semaphore>) -> Result<u64> {
@ -96,3 +125,96 @@ async fn get_recent_badge(fish: Arc<Semaphore>) -> Result<u64> {
Err(anyhow::anyhow!("no badge present")) Err(anyhow::anyhow!("no badge present"))
} }
} }
async fn root(state: State<AppState>) -> Html<String> {
let (last_badge, time) = *state.last_badge.read().await;
let time = time.elapsed();
let mut page = format!(r#"
<p>
most recent badge {last_badge:#0x}<br>
{time:?} ago
</p>
<h1>set last badge</h1>
"#);
for name in [
"Tess",
"Amaia",
"Prueky",
"David",
"Nathaniel",
"Thia",
"Michael",
"Zoey",
] {
page.push_str(&format!(r#"
<form action="setLast" method="post" id="myForm">
<button style="font-size:40px;" type="submit" name="name", value="{name}">{name}</button>
</form>
"#));
}
Html::from(page)
}
#[derive(serde::Deserialize)]
struct NameForm {
name: String,
}
async fn set_last(
state: State<AppState>,
Form(input): Form<NameForm>) -> Html<String> {
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("<h1>failed, no badge scanned</h1>".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!("<p>{last_badge:#0x} is now {}</p></br><a href=\"/\">back</a>", input.name))
}
async fn recent_badge(state: State<AppState>) -> String {
let (last_badge, time) = *state.last_badge.read().await;
format!("id: {last_badge:#0x}, scanned {:?} ago", time.elapsed())
}
async fn phil(state: State<AppState>) -> 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"))
}