add routes and helpers for starting, stopping and restarting the sbot

This commit is contained in:
glyph 2022-03-20 16:38:32 +02:00
parent 60539adf41
commit 6db5e7c169
8 changed files with 190 additions and 17 deletions

View File

@ -170,7 +170,20 @@ fn main() {
},
(GET) (/settings/scuttlebutt) => {
Response::html(routes::settings::scuttlebutt::menu::build_template())
Response::html(routes::settings::scuttlebutt::menu::build_template(request))
.reset_flash()
},
(GET) (/settings/scuttlebutt/restart) => {
routes::settings::scuttlebutt::restart::restart_sbot()
},
(GET) (/settings/scuttlebutt/start) => {
routes::settings::scuttlebutt::start::start_sbot()
},
(GET) (/settings/scuttlebutt/stop) => {
routes::settings::scuttlebutt::stop::stop_sbot()
},
(GET) (/settings/scuttlebutt/configure) => {

View File

@ -2,8 +2,8 @@ use maud::{html, PreEscaped};
use crate::{templates, CONFIG};
// TODO: flash message implementation for rouille
//
// ROUTE: /settings
/// Settings menu template builder.
pub fn build_template() -> PreEscaped<String> {
let menu_template = html! {

View File

@ -1,10 +1,8 @@
use maud::{html, PreEscaped};
use peach_lib::sbot::SbotStatus;
use rouille::Request;
use crate::templates;
// TODO: flash message implementation for rouille
//
use crate::{templates, utils::flash::FlashRequest};
/// Read the status of the go-sbot service and render buttons accordingly.
fn render_process_buttons() -> PreEscaped<String> {
@ -28,8 +26,13 @@ fn render_process_buttons() -> PreEscaped<String> {
}
}
// ROUTE: /settings/scuttlebutt
/// Scuttlebutt settings menu template builder.
pub fn build_template() -> PreEscaped<String> {
pub fn build_template(request: &Request) -> PreEscaped<String> {
// check for flash cookies; will be (None, None) if no flash cookies are found
let (flash_name, flash_msg) = request.retrieve_flash();
let menu_template = html! {
(PreEscaped("<!-- SCUTTLEBUTT SETTINGS MENU -->"))
div class="card center" {
@ -39,6 +42,11 @@ pub fn build_template() -> PreEscaped<String> {
// conditionally render the start / stop / restart buttons
(render_process_buttons())
}
// render flash message if cookies were found in the request
@if let (Some(name), Some(msg)) = (flash_name, flash_msg) {
(PreEscaped("<!-- FLASH MESSAGE -->"))
(templates::flash::build_template(name, &msg))
}
}
};

View File

@ -1,2 +1,5 @@
pub mod configure;
pub mod menu;
pub mod restart;
pub mod start;
pub mod stop;

View File

@ -0,0 +1,33 @@
use log::info;
use rouille::Response;
use crate::utils::{flash::FlashResponse, sbot::systemctl_sbot_cmd};
// ROUTE: /settings/scuttlebutt/restart
/// Attempt to restart the go-sbot.service process.
/// Redirect to the Scuttlebutt settings menu and communicate the outcome of
/// the attempt via a flash message.
pub fn restart_sbot() -> Response {
info!("Restarting go-sbot.service");
let (flash_name, flash_msg) = match systemctl_sbot_cmd("stop") {
// if stop was successful, try to start the process
Ok(_) => match systemctl_sbot_cmd("start") {
Ok(_) => (
"flash_name=success".to_string(),
"flash_msg=Sbot process has been restarted".to_string(),
),
Err(e) => (
"flash_name=error".to_string(),
format!("flash_msg=Failed to start the sbot process: {}", e),
),
},
Err(e) => (
"flash_name=error".to_string(),
format!("flash_msg=Failed to stop the sbot process: {}", e),
),
};
// redirect to the scuttlebutt settings menu
Response::redirect_303("/settings/scuttlebutt").add_flash(flash_name, flash_msg)
}

View File

@ -0,0 +1,26 @@
use log::info;
use rouille::Response;
use crate::utils::{flash::FlashResponse, sbot::systemctl_sbot_cmd};
// ROUTE: /settings/scuttlebutt/start
/// Attempt to start the go-sbot.service process.
/// Redirect to the Scuttlebutt settings menu and communicate the outcome of
/// the attempt via a flash message.
pub fn start_sbot() -> Response {
info!("Starting go-sbot.service");
let (flash_name, flash_msg) = match systemctl_sbot_cmd("start") {
Ok(_) => (
"flash_name=success".to_string(),
"flash_msg=Sbot process has been started".to_string(),
),
Err(_) => (
"flash_name=error".to_string(),
"flash_msg=Failed to start the sbot process".to_string(),
),
};
// redirect to the scuttlebutt settings menu
Response::redirect_303("/settings/scuttlebutt").add_flash(flash_name, flash_msg)
}

View File

@ -0,0 +1,26 @@
use log::info;
use rouille::Response;
use crate::utils::{flash::FlashResponse, sbot::systemctl_sbot_cmd};
// ROUTE: /settings/scuttlebutt/stop
/// Attempt to stop the go-sbot.service process.
/// Redirect to the Scuttlebutt settings menu and communicate the outcome of
/// the attempt via a flash message.
pub fn stop_sbot() -> Response {
info!("Stopping go-sbot.service");
let (flash_name, flash_msg) = match systemctl_sbot_cmd("stop") {
Ok(_) => (
"flash_name=success".to_string(),
"flash_msg=Sbot process has been stopped".to_string(),
),
Err(_) => (
"flash_name=error".to_string(),
"flash_msg=Failed to stop the sbot process".to_string(),
),
};
// redirect to the scuttlebutt settings menu
Response::redirect_303("/settings/scuttlebutt").add_flash(flash_name, flash_msg)
}

View File

@ -1,19 +1,35 @@
use std::io::prelude::*;
use std::{collections::HashMap, error::Error};
use std::{fs, fs::File, path::Path};
use std::{
collections::HashMap,
error::Error,
fs,
fs::File,
io,
path::Path,
process::{Command, Output},
};
use async_std::task;
use dirs;
use futures::stream::TryStreamExt;
use golgi::{blobs, messages::SsbMessageValue, Sbot};
use golgi::{api::friends::RelationshipQuery, blobs, messages::SsbMessageValue, Sbot};
use log::info;
use peach_lib::sbot::SbotConfig;
use temporary::Directory;
use crate::error::PeachWebError;
use crate::{error::PeachWebError, utils::sbot};
// SBOT HELPER FUNCTIONS
/// Executes a systemctl command for the go-sbot.service process.
pub fn systemctl_sbot_cmd(cmd: &str) -> io::Result<Output> {
Command::new("systemctl")
.arg("--user")
.arg(cmd)
.arg("go-sbot.service")
.output()
}
/// Initialise an sbot client with the given configuration parameters.
pub async fn init_sbot_with_config(
sbot_config: &Option<SbotConfig>,
) -> Result<Sbot, PeachWebError> {
@ -191,16 +207,64 @@ pub fn get_follows_list() -> Result<Vec<HashMap<String, String>>, Box<dyn Error>
})
}
pub fn get_friends_list() -> Result<Vec<String>, Box<dyn Error>> {
pub fn get_friends_list() -> Result<Vec<HashMap<String, String>>, Box<dyn Error>> {
// 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?;
// return the sequence number of the latest msg
//Ok(msgs[0].sequence)
let local_id = sbot_client.whoami().await?;
Ok(vec!["temp".to_string()])
let follows = sbot_client.get_follows().await?;
// we'll use this to store the profile info for each friend
let mut peer_list = Vec::new();
if !follows.is_empty() {
for peer in follows.iter() {
// trim whitespace (including newline characters) and
// remove the inverted-commas around the id
let peer_id = peer.trim().replace('"', "");
// retrieve the profile info for the given peer
let mut peer_info = sbot_client.get_profile_info(&peer_id).await?;
// insert the public key of the peer into the info hashmap
peer_info.insert("id".to_string(), peer_id.to_string());
// retrieve the profile image blob id for the given peer
if let Some(blob_id) = peer_info.get("image") {
// look-up the path for the image blob
if let Ok(blob_path) = blobs::get_blob_path(&blob_id) {
// insert the image blob path of the peer into the info hashmap
peer_info.insert("blob_path".to_string(), blob_path.to_string());
// check if the blob is in the blobstore
// set a flag in the info hashmap
match sbot::blob_is_stored_locally(&blob_path).await {
Ok(exists) if exists == true => {
peer_info.insert("blob_exists".to_string(), "true".to_string())
}
_ => peer_info.insert("blob_exists".to_string(), "false".to_string()),
};
}
}
// check if the peer follows us (making us friends)
let follow_query = RelationshipQuery {
source: peer_id.to_string(),
dest: local_id.clone(),
};
// query follow state
match sbot_client.friends_is_following(follow_query).await {
Ok(following) if following == "true" => {
// only push profile info to peer_list vec if they follow us
peer_list.push(peer_info)
}
_ => (),
};
}
}
// return the list of peers
Ok(peer_list)
})
}