add server

This commit is contained in:
CoCo_Sol 2024-01-06 16:46:15 +01:00
commit 7ef80cf7af
6 changed files with 1651 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

1540
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

11
Cargo.toml Normal file
View file

@ -0,0 +1,11 @@
[package]
name = "ponguito-serv"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rocket = { version = "0.5.0", features = ["json"] }
serde = "1.0.195"
serde_json = "1.0.111"

10
Containerfile Normal file
View file

@ -0,0 +1,10 @@
FROM rust:alpine AS builder
RUN apk add musl-dev
WORKDIR /app
COPY . .
RUN cargo build --release
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/target/release/ponguito-serv .
CMD ["./ponguito-serv"]

1
data.json Normal file
View file

@ -0,0 +1 @@
{}

88
src/main.rs Normal file
View file

@ -0,0 +1,88 @@
use rocket::form::Form;
use rocket::serde::json::Json;
use rocket::{get, launch, Config, FromForm};
use rocket::{post, routes};
use serde::Deserialize;
use serde::Serialize;
use std::collections::HashMap;
use std::fs::File;
use std::io::Write;
use std::net::IpAddr;
#[derive(Deserialize, Serialize, FromForm, Clone, Debug)]
struct NewScore {
name: String,
score: u32,
}
#[post("/new_score", data = "<score>")]
fn new_score(score: Form<NewScore>) -> Option<()> {
let name = score.name.clone();
if name.to_lowercase().contains("yannis") {
return Some(());
}
let score = score.score.clone();
if load_data().contains_key(&name) {
if score < *load_data().get(&name).unwrap() {
return Some(());
}
save_data(name, score);
} else {
save_data(name, score);
}
Some(())
}
#[get("/data")]
fn data() -> Json<Vec<(u32, String)>> {
let mut best_scores: Vec<_> = load_data().into_iter().map(|(k, v)| (v, k)).collect();
let nb = 5.min(best_scores.len());
best_scores.sort_by(|a, b| b.0.cmp(&a.0)); // sort by score();
best_scores.truncate(nb);
Json(best_scores)
}
fn save_data(name: String, score: u32) {
let mut data = load_data();
data.insert(name, score);
let json = serde_json::to_string(&data).unwrap();
let mut file = File::create("data.json").unwrap();
file.write_all(json.as_bytes()).unwrap();
}
fn load_data() -> HashMap<String, u32> {
let file = File::open("data.json");
if let Ok(file) = file {
// read the file and put the data into ARTICLES if it didn't work then create an empty hashmap
let articles: HashMap<String, u32> =
serde_json::from_reader(file).unwrap_or_else(|_| HashMap::new());
return articles;
} else {
println!("Failed to open articles.json : {:?}", file);
panic!("Failed to open articles.json : {:?}", file);
}
}
// The main function of the website.
#[launch]
async fn rocket() -> _ {
// generate a secret key and figment the rocket server
let figment = Config::figment()
.merge(("port", 80))
.merge(("worker_count", 4))
.merge(("log_level", rocket::config::LogLevel::Critical))
.merge(("address", IpAddr::from([127, 0, 0, 1])));
// create a config
let config = Config::from(figment);
// launch the server with different routes
rocket::build()
// apply the config
.configure(config)
.mount("/", routes![new_score, data])
}