- 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`
This commit is contained in:
parent
ebc6fea762
commit
8aef6fb0b9
14
src/main.rs
14
src/main.rs
|
@ -110,7 +110,7 @@ mod utils;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
use async_std::channel;
|
use async_std::channel;
|
||||||
use log::info;
|
use log::{info, warn};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
fairing::AdHoc,
|
fairing::AdHoc,
|
||||||
fs::{relative, FileServer},
|
fs::{relative, FileServer},
|
||||||
|
@ -119,18 +119,17 @@ use rocket::{
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
use xdg::BaseDirectories;
|
use xdg::BaseDirectories;
|
||||||
|
|
||||||
use crate::{db::Database, routes::*, sbot::WhoAmI, task_loop::Task};
|
use crate::{db::Database, routes::*, task_loop::Task};
|
||||||
|
|
||||||
#[launch]
|
#[launch]
|
||||||
async fn rocket() -> _ {
|
async fn rocket() -> _ {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
// Retrieve and store the public key of the local sbot.
|
// Retrieve and store the public key of the local sbot.
|
||||||
let public_key: String = sbot::whoami()
|
match sbot::whoami().await {
|
||||||
.await
|
Ok(id) => info!("Public key of the local sbot instance: {}", id),
|
||||||
.expect("whoami rpc call failed. please ensure the sbot is running before trying again");
|
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)
|
||||||
info!("Public key of the local sbot instance: {}", public_key);
|
}
|
||||||
let whoami = WhoAmI(public_key);
|
|
||||||
|
|
||||||
// Create the key-value database.
|
// Create the key-value database.
|
||||||
let xdg_dirs = BaseDirectories::with_prefix("lykin").unwrap();
|
let xdg_dirs = BaseDirectories::with_prefix("lykin").unwrap();
|
||||||
|
@ -151,7 +150,6 @@ async fn rocket() -> _ {
|
||||||
info!("Launching web server");
|
info!("Launching web server");
|
||||||
rocket::build()
|
rocket::build()
|
||||||
.manage(db)
|
.manage(db)
|
||||||
.manage(whoami)
|
|
||||||
.manage(tx)
|
.manage(tx)
|
||||||
.mount(
|
.mount(
|
||||||
"/",
|
"/",
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
use async_std::channel::Sender;
|
use async_std::channel::Sender;
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use rocket::{form::Form, get, post, response::Redirect, uri, FromForm, State};
|
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::{
|
use crate::{
|
||||||
db::{Database, Peer},
|
db::{Database, Peer},
|
||||||
sbot,
|
sbot,
|
||||||
task_loop::Task,
|
task_loop::Task,
|
||||||
utils, WhoAmI,
|
utils,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(FromForm)]
|
#[derive(FromForm)]
|
||||||
|
@ -26,10 +26,7 @@ pub async fn home(db: &State<Database>) -> Template {
|
||||||
peers_unread.push((peer, unread_count.to_string()));
|
peers_unread.push((peer, unread_count.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut context = Context::new();
|
Template::render("base", context! { peers: &peers_unread })
|
||||||
context.insert("peers", &peers_unread);
|
|
||||||
|
|
||||||
Template::render("base", &context.into_json())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/posts/<public_key>/<msg_id>/delete")]
|
#[get("/posts/<public_key>/<msg_id>/delete")]
|
||||||
|
@ -61,12 +58,14 @@ pub async fn posts(db: &State<Database>, public_key: &str) -> Template {
|
||||||
|
|
||||||
let posts = db.get_posts(public_key).unwrap();
|
let posts = db.get_posts(public_key).unwrap();
|
||||||
|
|
||||||
let mut context = Context::new();
|
// Define context data to be rendered in the template.
|
||||||
context.insert("selected_peer", &public_key);
|
let context = context! {
|
||||||
context.insert("peers", &peers_unread);
|
selected_peer: &public_key,
|
||||||
context.insert("posts", &posts);
|
peers: &peers_unread,
|
||||||
|
posts: &posts
|
||||||
|
};
|
||||||
|
|
||||||
Template::render("base", &context.into_json())
|
Template::render("base", context)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/posts/<public_key>/<msg_id>")]
|
#[get("/posts/<public_key>/<msg_id>")]
|
||||||
|
@ -81,23 +80,18 @@ pub async fn post(db: &State<Database>, public_key: &str, msg_id: &str) -> Templ
|
||||||
let posts = db.get_posts(public_key).unwrap();
|
let posts = db.get_posts(public_key).unwrap();
|
||||||
let post = db.get_post(public_key, msg_id).unwrap();
|
let post = db.get_post(public_key, msg_id).unwrap();
|
||||||
|
|
||||||
let mut context = Context::new();
|
let context = context! {
|
||||||
context.insert("peers", &peers_unread);
|
peers: &peers_unread,
|
||||||
context.insert("selected_peer", &public_key);
|
selected_peer: &public_key,
|
||||||
context.insert(
|
selected_peer_encoded: &uri_encode::encode_uri_component(public_key),
|
||||||
"selected_peer_encoded",
|
selected_post: &msg_id,
|
||||||
&uri_encode::encode_uri_component(public_key),
|
selected_post_encoded: &uri_encode::encode_uri_component(msg_id),
|
||||||
);
|
posts: &posts,
|
||||||
context.insert("selected_post", &msg_id);
|
post: &post,
|
||||||
context.insert(
|
post_is_selected: &true
|
||||||
"selected_post_encoded",
|
};
|
||||||
&uri_encode::encode_uri_component(msg_id),
|
|
||||||
);
|
|
||||||
context.insert("posts", &posts);
|
|
||||||
context.insert("post", &post);
|
|
||||||
context.insert("post_is_selected", &true);
|
|
||||||
|
|
||||||
Template::render("base", &context.into_json())
|
Template::render("base", context)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/posts/<public_key>/<msg_id>/read")]
|
#[get("/posts/<public_key>/<msg_id>/read")]
|
||||||
|
@ -157,7 +151,6 @@ pub async fn download_latest_posts(db: &State<Database>, tx: &State<Sender<Task>
|
||||||
#[post("/subscribe", data = "<peer>")]
|
#[post("/subscribe", data = "<peer>")]
|
||||||
pub async fn subscribe_form(
|
pub async fn subscribe_form(
|
||||||
db: &State<Database>,
|
db: &State<Database>,
|
||||||
whoami: &State<WhoAmI>,
|
|
||||||
tx: &State<Sender<Task>>,
|
tx: &State<Sender<Task>>,
|
||||||
peer: Form<PeerForm>,
|
peer: Form<PeerForm>,
|
||||||
) -> Redirect {
|
) -> Redirect {
|
||||||
|
@ -182,21 +175,7 @@ pub async fn subscribe_form(
|
||||||
// Follow the peer if our local instance is not already following.
|
// Follow the peer if our local instance is not already following.
|
||||||
if db.add_peer(peer_info).is_ok() {
|
if db.add_peer(peer_info).is_ok() {
|
||||||
info!("Added {} to 'peers' database tree", &peer.public_key);
|
info!("Added {} to 'peers' database tree", &peer.public_key);
|
||||||
match sbot::is_following(&whoami.0, &peer.public_key).await {
|
sbot::follow_if_not_following(&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
|
|
||||||
)
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
let peer_id = peer.public_key.to_string();
|
let peer_id = peer.public_key.to_string();
|
||||||
// Fetch all root posts authored by the peer we're subscribing
|
// Fetch all root posts authored by the peer we're subscribing
|
||||||
|
@ -216,11 +195,7 @@ pub async fn subscribe_form(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/unsubscribe", data = "<peer>")]
|
#[post("/unsubscribe", data = "<peer>")]
|
||||||
pub async fn unsubscribe_form(
|
pub async fn unsubscribe_form(db: &State<Database>, peer: Form<PeerForm>) -> Redirect {
|
||||||
db: &State<Database>,
|
|
||||||
whoami: &State<WhoAmI>,
|
|
||||||
peer: Form<PeerForm>,
|
|
||||||
) -> Redirect {
|
|
||||||
info!("Unsubscribing from peer {}", &peer.public_key);
|
info!("Unsubscribing from peer {}", &peer.public_key);
|
||||||
|
|
||||||
if let Err(e) = utils::validate_public_key(&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",
|
"Removed peer {} from 'peers' database tree",
|
||||||
&peer.public_key
|
&peer.public_key
|
||||||
);
|
);
|
||||||
match sbot::is_following(&whoami.0, &peer.public_key).await {
|
sbot::unfollow_if_following(&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),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
warn!(
|
warn!(
|
||||||
"Failed to remove peer {} from 'peers' database tree",
|
"Failed to remove peer {} from 'peers' database tree",
|
||||||
|
|
48
src/sbot.rs
48
src/sbot.rs
|
@ -13,10 +13,52 @@ use golgi::{
|
||||||
use log::{debug, info, warn};
|
use log::{debug, info, warn};
|
||||||
use serde_json::value::Value;
|
use serde_json::value::Value;
|
||||||
|
|
||||||
use crate::db::Post;
|
use crate::{db::Post, sbot};
|
||||||
|
|
||||||
/// The public key of the local sbot instance.
|
/// Check the follow status of a remote peer and follow them if not already
|
||||||
pub struct WhoAmI(pub String);
|
/// 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.
|
/// Initialise a connection to a Scuttlebutt server.
|
||||||
async fn init_sbot() -> Result<Sbot, String> {
|
async fn init_sbot() -> Result<Sbot, String> {
|
||||||
|
|
Loading…
Reference in New Issue