From cf249687251e11dbf2c861471065bc8a240d6c24 Mon Sep 17 00:00:00 2001 From: jake Date: Sun, 24 Mar 2024 12:08:47 -0400 Subject: [PATCH] GIT THIS --- .gitignore | 3 ++ Cargo.toml | 13 ++++++ asset | 1 + src/main.rs | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 120000 asset create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a1f3433 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +Cargo.lock +tmp/* diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..0366f55 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "hit-counter-rs" +version = "0.0.1" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +actix-web = "4" +actix-files = "0.6.5" +env_logger = "0.11.3" +log = "0.4" +async-stream = "0.3.5" diff --git a/asset b/asset new file mode 120000 index 0000000..9731baa --- /dev/null +++ b/asset @@ -0,0 +1 @@ +../../perl/hit-counter/asset/ \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..30963c5 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,117 @@ +// Due to the slowness of imagemagick (and calling system commands and w/e else) +// the image that the user will see on the page will be -1 behind the actual count +use actix_web::{ + get, + App, + HttpServer, + HttpResponse, + HttpRequest, +}; +use actix_files::NamedFile; +use std::{ + fs, + path::Path, + process::Command, +}; + +const MONTAGE_PATH: &str = "/bin/montage"; +// this kinda dates ImageMagick, oh well (6.9) +//const MONTAGE_ARGS: &str = "-tile 6x1 -geometry +0+0 -background none -scale 50"; +const ASSET_DIR: &str = "asset/"; +const TMP_OUTPUT: &str = "tmp/counter.png"; + + +const BIND_IP: &str = "127.0.0.1"; +const BIND_PORT: u16 = 8080; + +static mut COUNTER: u16 = 0; +const NUMBER_LENGTH: u8 = 6; +const COUNTER_FILE : &str = "counter.numb"; + +#[get("/")] +async fn counter_route(req: HttpRequest ) -> HttpResponse { + + let count: String; + unsafe { + COUNTER = &COUNTER + 1; + count = number_to_length(&COUNTER, NUMBER_LENGTH); + write_counter(); + } + + create_image(count); + + let file = NamedFile::open_async(TMP_OUTPUT).await.unwrap(); // streams the file + let res = file.into_response(&req); // NamedFile to HttpResponse + + res +} + +fn create_image (count: String) { + let mut command = Command::new(MONTAGE_PATH); + + for i in 0..NUMBER_LENGTH { + let mut file_name: String = String::new(); + + file_name.push_str( ASSET_DIR ); + file_name.push_str( &(count.as_str()[i as usize..i as usize + 1]) ); + file_name.push_str( ".png" ); + + command.arg(file_name); + } + command.arg("-tile").arg("6x1").arg("-geometry").arg("+0+0").arg("-background").arg("none").arg("-scale").arg("50"); + command.arg(TMP_OUTPUT); + // user will refresh the page faster than imagemagick does stuff + // possible dos I guess, idc + command.spawn().expect("`/bin/montage` has an error! (probably, idk)"); +} + +fn number_to_length(counter: &u16, length: u8) -> String { + let mut string : String = String::from(""); + + let mut counter_len = (counter.checked_ilog10().unwrap_or(0) + 1) as u8; // like length() in perl + while counter_len < length { + string.push('0'); + counter_len = counter_len + 1; + } + + string.push_str( counter.to_string().as_str() ); + + string +} + +unsafe fn read_counter() { + match fs::read_to_string(COUNTER_FILE) { + Ok(n) => COUNTER = n.as_str().parse().unwrap(), + Err(e) => log::info!("{e}"), + } +} + +unsafe fn write_counter() { + let count = COUNTER.to_string(); + fs::write(COUNTER_FILE, &count).expect("I can't write to file"); +} + + +#[actix_web::main] // or #[tokio::main] +async fn main() -> std::io::Result<()> { + env_logger::init_from_env(env_logger::Env::new().default_filter_or("info")); + + if ! Path::new(COUNTER_FILE).exists() { + unsafe { + write_counter(); + } + } + unsafe { + read_counter(); + } + + log::info!("starting HTTP server at http://{BIND_IP}:{BIND_PORT}"); + + HttpServer::new(|| { + App::new() + .service(counter_route) + }) + .bind((BIND_IP, BIND_PORT))? + .run() + .await +}