diff --git a/Cargo.lock b/Cargo.lock index f5993c0..085e528 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -263,21 +263,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - [[package]] name = "futures-channel" version = "0.3.30" @@ -285,7 +270,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", - "futures-sink", ] [[package]] @@ -294,34 +278,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "futures-sink" version = "0.3.30" @@ -340,16 +296,10 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ - "futures-channel", "futures-core", - "futures-io", - "futures-macro", - "futures-sink", "futures-task", - "memchr", "pin-project-lite", "pin-utils", - "slab", ] [[package]] @@ -1334,7 +1284,6 @@ version = "0.1.0" dependencies = [ "axum", "color-eyre", - "futures", "reqwest", "serde", "tokio", diff --git a/Cargo.toml b/Cargo.toml index c54025a..199e83b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "uofgcal" +publish = false version = "0.1.0" edition = "2021" [dependencies] axum = "0.7.6" color-eyre = "0.6.3" -futures = "0.3.30" reqwest = "0.12.7" serde = { version = "1.0.210", features = ["derive"] } tokio = { version = "1.40.0", features = ["full"] } diff --git a/src/main.rs b/src/main.rs index 117645c..745cba9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ use axum::{ - body::Bytes, extract::{Query, State}, http::StatusCode, response::{AppendHeaders, IntoResponse}, @@ -13,51 +12,43 @@ use std::borrow::Cow; use tokio::net::TcpListener; const PORT: u16 = 8080; +const CALENDAR_URL: &str = "https://frontdoor.spa.gla.ac.uk/spacett/download/uogtimetable.ics"; #[derive(Deserialize)] -struct CalendarPayload { - calendar: Cow<'static, str>, - filename: Option>, - username: Cow<'static, str>, - password: Cow<'static, str>, +struct AuthPayload { + guid: Cow<'static, str>, + pass: Cow<'static, str>, } async fn get_calender( - Query(auth): Query, + Query(auth): Query, State(client): State, ) -> impl IntoResponse { if let Ok(resp) = client - .get(auth.calendar.as_ref()) - .basic_auth(auth.username.as_ref(), Some(auth.password.as_ref())) + .get(CALENDAR_URL) + .basic_auth(auth.guid.as_ref(), Some(auth.pass.as_ref())) .send() .await { - Ok(( - AppendHeaders([ - ( - header::CONTENT_TYPE, - "text/calendar; charset=utf-8".to_string(), - ), - ( - header::CONTENT_DISPOSITION, - format!( - r#"attachment; filename="{}""#, - auth.filename.unwrap_or_else(|| { - if auth.calendar.ends_with(".ics") { - Cow::Borrowed(&auth.calendar.split('/').last().unwrap()) - } else { - Cow::Borrowed("calendar.ics") - } - }) + match resp.status() { + StatusCode::UNAUTHORIZED => { + Err((StatusCode::UNAUTHORIZED, "Invalid username or password")) + } + _ => Ok(( + AppendHeaders([ + (header::CONTENT_TYPE, "text/calendar; charset=utf-8"), + ( + header::CONTENT_DISPOSITION, + r#"attachment; filename="calendar.ics""#, ), - ), - ]), - resp.bytes().await.ok().unwrap_or_default(), - )) + ]), + resp.bytes().await.ok().unwrap_or_default(), + )), + } } else { Err(( StatusCode::INTERNAL_SERVER_ERROR, - "Failed to fetch calendar".to_string(), + "Failed to fetch calendar", )) } } @@ -65,11 +56,16 @@ async fn get_calender( #[tokio::main] async fn main() -> Result<()> { color_eyre::install()?; - let tcp_listener = TcpListener::bind(format!("0.0.0.0:{PORT}")).await?; + + // setup the http client and tcp listener let client = Client::new(); + let tcp_listener = TcpListener::bind(format!("0.0.0.0:{PORT}")).await?; + + // start the server let router = Router::new() .route("/", get(get_calender)) .with_state(client); + axum::serve(tcp_listener, router).await?; Ok(()) }