From 8aef6fb0b9320049580e217d0c3c86485499a081 Mon Sep 17 00:00:00 2001 From: glyph Date: Tue, 16 Aug 2022 17:12:18 +0100 Subject: [PATCH] - Remove `whoami` from managed state and instead call it when required - Replace `Context::insert()` with `context!` macro - Simplify `src/routes.rs` by moving composite follow / unfollow functions into `src/sbot.rs` --- src/main.rs | 14 ++++----- src/routes.rs | 84 +++++++++++++++------------------------------------ src/sbot.rs | 48 +++++++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 71 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6c40ba4..07f1a1d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -110,7 +110,7 @@ mod utils; use std::env; use async_std::channel; -use log::info; +use log::{info, warn}; use rocket::{ fairing::AdHoc, fs::{relative, FileServer}, @@ -119,18 +119,17 @@ use rocket::{ use rocket_dyn_templates::Template; use xdg::BaseDirectories; -use crate::{db::Database, routes::*, sbot::WhoAmI, task_loop::Task}; +use crate::{db::Database, routes::*, task_loop::Task}; #[launch] async fn rocket() -> _ { env_logger::init(); // Retrieve and store the public key of the local sbot. - let public_key: String = sbot::whoami() - .await - .expect("whoami rpc call failed. please ensure the sbot is running before trying again"); - info!("Public key of the local sbot instance: {}", public_key); - let whoami = WhoAmI(public_key); + match sbot::whoami().await { + Ok(id) => info!("Public key of the local sbot instance: {}", id), + Err(e) => warn!("Failed to retrieve the public key of the local sbot instance (`whoami` RPC call failed). Please ensure the sbot is running before trying again. Error details: {}", e) + } // Create the key-value database. let xdg_dirs = BaseDirectories::with_prefix("lykin").unwrap(); @@ -151,7 +150,6 @@ async fn rocket() -> _ { info!("Launching web server"); rocket::build() .manage(db) - .manage(whoami) .manage(tx) .mount( "/", diff --git a/src/routes.rs b/src/routes.rs index 79db946..4d4af1e 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -3,13 +3,13 @@ use async_std::channel::Sender; use log::{info, warn}; use rocket::{form::Form, get, post, response::Redirect, uri, FromForm, State}; -use rocket_dyn_templates::{tera::Context, Template}; +use rocket_dyn_templates::{context, Template}; use crate::{ db::{Database, Peer}, sbot, task_loop::Task, - utils, WhoAmI, + utils, }; #[derive(FromForm)] @@ -26,10 +26,7 @@ pub async fn home(db: &State) -> Template { peers_unread.push((peer, unread_count.to_string())); } - let mut context = Context::new(); - context.insert("peers", &peers_unread); - - Template::render("base", &context.into_json()) + Template::render("base", context! { peers: &peers_unread }) } #[get("/posts///delete")] @@ -61,12 +58,14 @@ pub async fn posts(db: &State, public_key: &str) -> Template { let posts = db.get_posts(public_key).unwrap(); - let mut context = Context::new(); - context.insert("selected_peer", &public_key); - context.insert("peers", &peers_unread); - context.insert("posts", &posts); + // Define context data to be rendered in the template. + let context = context! { + selected_peer: &public_key, + peers: &peers_unread, + posts: &posts + }; - Template::render("base", &context.into_json()) + Template::render("base", context) } #[get("/posts//")] @@ -81,23 +80,18 @@ pub async fn post(db: &State, public_key: &str, msg_id: &str) -> Templ let posts = db.get_posts(public_key).unwrap(); let post = db.get_post(public_key, msg_id).unwrap(); - let mut context = Context::new(); - context.insert("peers", &peers_unread); - context.insert("selected_peer", &public_key); - context.insert( - "selected_peer_encoded", - &uri_encode::encode_uri_component(public_key), - ); - context.insert("selected_post", &msg_id); - context.insert( - "selected_post_encoded", - &uri_encode::encode_uri_component(msg_id), - ); - context.insert("posts", &posts); - context.insert("post", &post); - context.insert("post_is_selected", &true); + let context = context! { + peers: &peers_unread, + selected_peer: &public_key, + selected_peer_encoded: &uri_encode::encode_uri_component(public_key), + selected_post: &msg_id, + selected_post_encoded: &uri_encode::encode_uri_component(msg_id), + posts: &posts, + post: &post, + post_is_selected: &true + }; - Template::render("base", &context.into_json()) + Template::render("base", context) } #[get("/posts///read")] @@ -157,7 +151,6 @@ pub async fn download_latest_posts(db: &State, tx: &State #[post("/subscribe", data = "")] pub async fn subscribe_form( db: &State, - whoami: &State, tx: &State>, peer: Form, ) -> Redirect { @@ -182,21 +175,7 @@ pub async fn subscribe_form( // Follow the peer if our local instance is not already following. if db.add_peer(peer_info).is_ok() { info!("Added {} to 'peers' database tree", &peer.public_key); - match sbot::is_following(&whoami.0, &peer.public_key).await { - Ok(status) if status.as_str() == "false" => { - match sbot::follow_peer(&peer.public_key).await { - Ok(_) => info!("Followed peer {}", &peer.public_key), - Err(e) => warn!("Failed to follow peer {}: {}", &peer.public_key, e), - } - } - Ok(status) if status.as_str() == "true" => { - info!( - "Already following peer {}. No further action taken", - &peer.public_key - ) - } - _ => (), - } + sbot::follow_if_not_following(&peer.public_key).await; let peer_id = peer.public_key.to_string(); // Fetch all root posts authored by the peer we're subscribing @@ -216,11 +195,7 @@ pub async fn subscribe_form( } #[post("/unsubscribe", data = "")] -pub async fn unsubscribe_form( - db: &State, - whoami: &State, - peer: Form, -) -> Redirect { +pub async fn unsubscribe_form(db: &State, peer: Form) -> Redirect { info!("Unsubscribing from peer {}", &peer.public_key); if let Err(e) = utils::validate_public_key(&peer.public_key) { @@ -232,18 +207,7 @@ pub async fn unsubscribe_form( "Removed peer {} from 'peers' database tree", &peer.public_key ); - match sbot::is_following(&whoami.0, &peer.public_key).await { - Ok(status) if status.as_str() == "true" => { - info!("Unfollowing peer {}", &peer.public_key); - match sbot::unfollow_peer(&peer.public_key).await { - Ok(_) => { - info!("Unfollowed peer {}", &peer.public_key); - } - Err(e) => warn!("Failed to unfollow peer {}: {}", &peer.public_key, e), - } - } - _ => (), - } + sbot::unfollow_if_following(&peer.public_key).await; } else { warn!( "Failed to remove peer {} from 'peers' database tree", diff --git a/src/sbot.rs b/src/sbot.rs index aa253c8..3d89f36 100644 --- a/src/sbot.rs +++ b/src/sbot.rs @@ -13,10 +13,52 @@ use golgi::{ use log::{debug, info, warn}; use serde_json::value::Value; -use crate::db::Post; +use crate::{db::Post, sbot}; -/// The public key of the local sbot instance. -pub struct WhoAmI(pub String); +/// Check the follow status of a remote peer and follow them if not already +/// following. +pub async fn follow_if_not_following(remote_peer: &str) { + if let Ok(whoami) = sbot::whoami().await { + match sbot::is_following(&whoami, remote_peer).await { + Ok(status) if status.as_str() == "false" => { + match sbot::follow_peer(remote_peer).await { + Ok(_) => info!("Followed peer {}", &remote_peer), + Err(e) => warn!("Failed to follow peer {}: {}", &remote_peer, e), + } + } + Ok(status) if status.as_str() == "true" => { + info!( + "Already following peer {}. No further action taken", + &remote_peer + ) + } + _ => (), + } + } else { + warn!("Received an error during `whoami` RPC call. Please ensure the go-sbot is running and try again") + } +} + +/// Check the follow status of a remote peer and unfollow them if already +/// following. +pub async fn unfollow_if_following(remote_peer: &str) { + if let Ok(whoami) = sbot::whoami().await { + match sbot::is_following(&whoami, remote_peer).await { + Ok(status) if status.as_str() == "true" => { + info!("Unfollowing peer {}", &remote_peer); + match sbot::unfollow_peer(remote_peer).await { + Ok(_) => { + info!("Unfollowed peer {}", &remote_peer); + } + Err(e) => warn!("Failed to unfollow peer {}: {}", &remote_peer, e), + } + } + _ => (), + } + } else { + warn!("Received an error during `whoami` RPC call. Please ensure the go-sbot is running and try again") + } +} /// Initialise a connection to a Scuttlebutt server. async fn init_sbot() -> Result {