add follow, unfollow, block and unblock routes and sbot helper functions

This commit is contained in:
glyph 2022-03-24 13:41:49 +02:00
parent 952951515b
commit 0bfad25d3d
9 changed files with 271 additions and 6 deletions

View File

@ -43,10 +43,18 @@ pub fn mount_peachpub_routes(
Response::html(routes::guide::build_template())
},
(POST) (/scuttlebutt/block) => {
routes::scuttlebutt::block::handle_form(request)
},
(GET) (/scuttlebutt/blocks) => {
Response::html(routes::scuttlebutt::blocks::build_template())
},
(POST) (/scuttlebutt/follow) => {
routes::scuttlebutt::follow::handle_form(request)
},
(GET) (/scuttlebutt/follows) => {
Response::html(routes::scuttlebutt::follows::build_template())
},
@ -111,6 +119,14 @@ pub fn mount_peachpub_routes(
routes::scuttlebutt::search::handle_form(request)
},
(POST) (/scuttlebutt/unblock) => {
routes::scuttlebutt::unblock::handle_form(request)
},
(POST) (/scuttlebutt/unfollow) => {
routes::scuttlebutt::unfollow::handle_form(request)
},
(GET) (/settings) => {
Response::html(routes::settings::menu::build_template())
},

View File

@ -0,0 +1,42 @@
use peach_lib::sbot::SbotStatus;
use rouille::{post_input, try_or_400, Request, Response};
use crate::utils::{flash::FlashResponse, sbot};
// ROUTE: /scuttlebutt/block
/// Block a Scuttlebutt profile specified by the given public key.
///
/// Parse the public key from the submitted form and publish a contact message.
/// Redirect to the appropriate profile page with a flash message describing
/// the outcome of the action (may be successful or unsuccessful).
pub fn handle_form(request: &Request) -> Response {
// query the request body for form data
// return a 400 error if the admin_id field is missing
let data = try_or_400!(post_input!(request, {
public_key: String,
}));
let (flash_name, flash_msg) = match SbotStatus::read() {
Ok(status) if status.state == Some("active".to_string()) => {
match sbot::block_peer(&data.public_key) {
Ok(success_msg) => (
"flash_name=success".to_string(),
format!("flash_msg={}", success_msg),
),
Err(error_msg) => (
"flash_name=error".to_string(),
format!("flash_msg={}", error_msg),
),
}
}
_ => (
"flash_name=warning".to_string(),
"Social interactions are unavailable.".to_string(),
),
};
let url = format!("/scuttlebutt/profile/{}", data.public_key);
Response::redirect_303(url).add_flash(flash_name, flash_msg)
}

View File

@ -0,0 +1,42 @@
use peach_lib::sbot::SbotStatus;
use rouille::{post_input, try_or_400, Request, Response};
use crate::utils::{flash::FlashResponse, sbot};
// ROUTE: /scuttlebutt/follow
/// Follow a Scuttlebutt profile specified by the given public key.
///
/// Parse the public key from the submitted form and publish a contact message.
/// Redirect to the appropriate profile page with a flash message describing
/// the outcome of the action (may be successful or unsuccessful).
pub fn handle_form(request: &Request) -> Response {
// query the request body for form data
// return a 400 error if the admin_id field is missing
let data = try_or_400!(post_input!(request, {
public_key: String,
}));
let (flash_name, flash_msg) = match SbotStatus::read() {
Ok(status) if status.state == Some("active".to_string()) => {
match sbot::follow_peer(&data.public_key) {
Ok(success_msg) => (
"flash_name=success".to_string(),
format!("flash_msg={}", success_msg),
),
Err(error_msg) => (
"flash_name=error".to_string(),
format!("flash_msg={}", error_msg),
),
}
}
_ => (
"flash_name=warning".to_string(),
"Social interactions are unavailable.".to_string(),
),
};
let url = format!("/scuttlebutt/profile/{}", data.public_key);
Response::redirect_303(url).add_flash(flash_name, flash_msg)
}

View File

@ -1,4 +1,6 @@
pub mod block;
pub mod blocks;
pub mod follow;
pub mod follows;
pub mod friends;
pub mod invites;
@ -8,3 +10,5 @@ pub mod profile;
pub mod profile_update;
pub mod publish;
pub mod search;
pub mod unblock;
pub mod unfollow;

View File

@ -57,7 +57,7 @@ pub fn handle_form(request: &Request) -> Response {
match sbot::validate_public_key(&data.public_key) {
Ok(_) => {
let url = format!("/scuttlebutt/profile?={}", &data.public_key);
let url = format!("/scuttlebutt/profile/{}", &data.public_key);
Response::redirect_303(url)
}
Err(err) => {

View File

@ -0,0 +1,42 @@
use peach_lib::sbot::SbotStatus;
use rouille::{post_input, try_or_400, Request, Response};
use crate::utils::{flash::FlashResponse, sbot};
// ROUTE: /scuttlebutt/unblock
/// Unblock a Scuttlebutt profile specified by the given public key.
///
/// Parse the public key from the submitted form and publish a contact message.
/// Redirect to the appropriate profile page with a flash message describing
/// the outcome of the action (may be successful or unsuccessful).
pub fn handle_form(request: &Request) -> Response {
// query the request body for form data
// return a 400 error if the admin_id field is missing
let data = try_or_400!(post_input!(request, {
public_key: String,
}));
let (flash_name, flash_msg) = match SbotStatus::read() {
Ok(status) if status.state == Some("active".to_string()) => {
match sbot::unblock_peer(&data.public_key) {
Ok(success_msg) => (
"flash_name=success".to_string(),
format!("flash_msg={}", success_msg),
),
Err(error_msg) => (
"flash_name=error".to_string(),
format!("flash_msg={}", error_msg),
),
}
}
_ => (
"flash_name=warning".to_string(),
"Social interactions are unavailable.".to_string(),
),
};
let url = format!("/scuttlebutt/profile/{}", data.public_key);
Response::redirect_303(url).add_flash(flash_name, flash_msg)
}

View File

@ -0,0 +1,42 @@
use peach_lib::sbot::SbotStatus;
use rouille::{post_input, try_or_400, Request, Response};
use crate::utils::{flash::FlashResponse, sbot};
// ROUTE: /scuttlebutt/unfollow
/// Unfollow a Scuttlebutt profile specified by the given public key.
///
/// Parse the public key from the submitted form and publish a contact message.
/// Redirect to the appropriate profile page with a flash message describing
/// the outcome of the action (may be successful or unsuccessful).
pub fn handle_form(request: &Request) -> Response {
// query the request body for form data
// return a 400 error if the admin_id field is missing
let data = try_or_400!(post_input!(request, {
public_key: String,
}));
let (flash_name, flash_msg) = match SbotStatus::read() {
Ok(status) if status.state == Some("active".to_string()) => {
match sbot::unfollow_peer(&data.public_key) {
Ok(success_msg) => (
"flash_name=success".to_string(),
format!("flash_msg={}", success_msg),
),
Err(error_msg) => (
"flash_name=error".to_string(),
format!("flash_msg={}", error_msg),
),
}
}
_ => (
"flash_name=warning".to_string(),
"Social interactions are unavailable.".to_string(),
),
};
let url = format!("/scuttlebutt/profile/{}", data.public_key);
Response::redirect_303(url).add_flash(flash_name, flash_msg)
}

View File

@ -75,7 +75,7 @@ fn memory_element(memory: Option<u32>) -> Markup {
memory_rounded.to_string(),
"icon icon-active",
"label-medium font-normal",
"label-small font-normal",
"label-small font-gray",
)
}
_ => (

View File

@ -130,11 +130,16 @@ pub fn latest_sequence_number() -> Result<u64, Box<dyn Error>> {
let history_stream = sbot_client.create_history_stream(id).await?;
let mut msgs: Vec<SsbMessageValue> = history_stream.try_collect().await?;
// reverse the list of messages so we can easily reference the latest one
msgs.reverse();
// there will be zero messages when the sbot is run for the first time
if msgs.is_empty() {
Ok(0)
} else {
// reverse the list of messages so we can easily reference the latest one
msgs.reverse();
// return the sequence number of the latest msg
Ok(msgs[0].sequence)
// return the sequence number of the latest msg
Ok(msgs[0].sequence)
}
})
}
@ -353,6 +358,78 @@ pub fn update_profile_info(
})
}
/// Follow a peer.
pub fn follow_peer(public_key: &str) -> Result<String, String> {
// retrieve latest go-sbot configuration parameters
let sbot_config = SbotConfig::read().ok();
task::block_on(async {
let mut sbot_client = init_sbot_with_config(&sbot_config)
.await
.map_err(|e| e.to_string())?;
debug!("Following a Scuttlebutt peer");
match sbot_client.follow(public_key).await {
Ok(_) => Ok("Followed peer".to_string()),
Err(e) => Err(format!("Failed to follow peer: {}", e)),
}
})
}
/// Unfollow a peer.
pub fn unfollow_peer(public_key: &str) -> Result<String, String> {
// retrieve latest go-sbot configuration parameters
let sbot_config = SbotConfig::read().ok();
task::block_on(async {
let mut sbot_client = init_sbot_with_config(&sbot_config)
.await
.map_err(|e| e.to_string())?;
debug!("Unfollowing a Scuttlebutt peer");
match sbot_client.unfollow(public_key).await {
Ok(_) => Ok("Unfollowed peer".to_string()),
Err(e) => Err(format!("Failed to unfollow peer: {}", e)),
}
})
}
/// Block a peer.
pub fn block_peer(public_key: &str) -> Result<String, String> {
// retrieve latest go-sbot configuration parameters
let sbot_config = SbotConfig::read().ok();
task::block_on(async {
let mut sbot_client = init_sbot_with_config(&sbot_config)
.await
.map_err(|e| e.to_string())?;
debug!("Blocking a Scuttlebutt peer");
match sbot_client.block(public_key).await {
Ok(_) => Ok("Blocked peer".to_string()),
Err(e) => Err(format!("Failed to block peer: {}", e)),
}
})
}
/// Unblock a peer.
pub fn unblock_peer(public_key: &str) -> Result<String, String> {
// retrieve latest go-sbot configuration parameters
let sbot_config = SbotConfig::read().ok();
task::block_on(async {
let mut sbot_client = init_sbot_with_config(&sbot_config)
.await
.map_err(|e| e.to_string())?;
debug!("Unblocking a Scuttlebutt peer");
match sbot_client.unblock(public_key).await {
Ok(_) => Ok("Unblocked peer".to_string()),
Err(e) => Err(format!("Failed to unblock peer: {}", e)),
}
})
}
/// Retrieve a list of peers blocked by the local public key.
pub fn get_blocks_list() -> Result<Vec<HashMap<String, String>>, Box<dyn Error>> {
// retrieve latest go-sbot configuration parameters