use log::{info, warn}; use rocket::{form::Form, get, post, response::{Redirect, Flash}, uri, FromForm, request::FlashMessage, State}; use rocket_dyn_templates::{context, Template}; use crate::sbot; use crate::utils; use crate::db::{Database, Peer}; #[derive(FromForm)] pub struct PeerForm { pub public_key: String, } #[get("/")] pub async fn home(flash: Option>) -> Template { let whoami = match sbot::whoami().await { Ok(id) => id, Err(e) => format!("whoami call failed: {}", e), }; Template::render("base", context! { whoami, flash }) } #[get("/about")] pub async fn about_start() -> Template { Template::render("about", context! {}) } #[post("/about", data = "")] pub async fn about_form(peer: Form) -> Result> { info!("Showing follow information about peer {}", &peer.public_key); let whoami = match sbot::whoami().await { Ok(value) => value, Err(e) => return Err(Flash::error(Redirect::to(uri!(about_start)), e)), }; if let Err(e) = utils::validate_public_key(&peer.public_key) { let validation_err_msg = format!("Public key {} is invalid: {}", &peer.public_key, e); warn!("{}", validation_err_msg); return Err(Flash::error(Redirect::to(uri!(about_start)), validation_err_msg)); } info!("Public key {} is valid.", &peer.public_key); let follow_status = match sbot::is_following(&whoami, &peer.public_key).await { Ok(status) => status, Err(e) => { warn!("{}", e); return Err(Flash::error(Redirect::to(uri!(about_start)), e)); } }; let success_msg = format!("Follow status for {} : '{}'", &peer.public_key, follow_status); info!("{}", success_msg); Ok(Template::render("about", context! { whoami, peer_pubkey: &peer.public_key, status: follow_status })) } #[post("/subscribe", data = "")] pub async fn subscribe_form(db: &State, peer: Form) -> Result> { info!("Subscribing to peer {}", &peer.public_key); if let Err(e) = utils::validate_public_key(&peer.public_key) { let validation_err_msg = format!("Public key {} is invalid: {}", &peer.public_key, e); warn!("{}", validation_err_msg); return Err(Flash::error(Redirect::to(uri!(home)), validation_err_msg)); } else { info!("Public key {} is valid.", &peer.public_key); let peer_name = match sbot::get_name(&peer.public_key).await { Ok(name) => name, Err(e) => { warn!("Failed to fetch name for peer {}: {}", &peer.public_key, e); String::from("") } }; let peer_info = Peer::new(&peer.public_key).set_name(&peer_name); match sbot::follow_if_not_following(&peer.public_key).await { Ok(_) => { if db.add_peer(peer_info).is_ok() { info!("Added {} to 'peers' database tree", &peer.public_key); } else { let err_msg = format!("Failed to add peer {} to 'peers' database tree.", &peer.public_key ); warn!("{}", err_msg); return Err(Flash::error(Redirect::to(uri!(home)), err_msg)); } }, Err(e) => { warn!("{}", e); return Err(Flash::error(Redirect::to(uri!(home)), e)); } } } Ok(Redirect::to(uri!(home))) } #[post("/unsubscribe", data = "")] pub async fn unsubscribe_form(db: &State, peer: Form) -> Result> { info!("Unsubscribing to peer {}", &peer.public_key); if let Err(e) = utils::validate_public_key(&peer.public_key) { let validation_err_msg = format!("Public key {} is invalid: {}", &peer.public_key, e); warn!("{}", validation_err_msg); return Err(Flash::error(Redirect::to(uri!(home)), validation_err_msg)); } else { info!("Public key {} is valid.", &peer.public_key); match sbot::unfollow_if_not_following(&peer.public_key).await { Ok(_) => { if db.remove_peer(&peer.public_key).is_ok() { info!("Removed peer {} from 'peers' database tree.", &peer.public_key); } else { warn!("Failed to remove peer {} from 'peers' database tree", &peer.public_key); } }, Err(e) => { warn!("{}", e); return Err(Flash::error(Redirect::to(uri!(home)), e)); } } } Ok(Redirect::to(uri!(home))) }