From fc2ea78876434418c1bc5d9fa6b051fd39839041 Mon Sep 17 00:00:00 2001 From: notplants Date: Sat, 8 Mar 2025 16:24:26 -0500 Subject: [PATCH] mostly working with tilde --- peach-lib/src/config_manager.rs | 1 + peach-lib/src/sbot.rs | 14 ++++++--- peach-web/src/error.rs | 10 ++++++ peach-web/src/utils/sbot.rs | 31 ++++++++++--------- tilde-client/src/lib.rs | 54 +++++++++++++++++++++------------ 5 files changed, 71 insertions(+), 39 deletions(-) diff --git a/peach-lib/src/config_manager.rs b/peach-lib/src/config_manager.rs index 52205f1..eb5baa2 100644 --- a/peach-lib/src/config_manager.rs +++ b/peach-lib/src/config_manager.rs @@ -61,6 +61,7 @@ pub fn get_peach_config_defaults() -> HashMap { ("TEMPORARY_PASSWORD_HASH", ""), ("TILDE_SBOT_DATADIR", "/home/notplants/.local/share/tildefriends/"), ("TILDE_SBOT_SERVICE", "tilde-sbot.service"), + ("TILDE_BINARY_PATH", "/home/notplants/computer/projects/peachpub/tilde/tildefriends/out/release/tildefriends.standalone"), ("PEACH_CONFIGDIR", "/var/lib/peachcloud"), ("PEACH_HOMEDIR", "/home/peach"), ("PEACH_WEBDIR", "/usr/share/peach-web"), diff --git a/peach-lib/src/sbot.rs b/peach-lib/src/sbot.rs index 07f41df..b4ca2e0 100644 --- a/peach-lib/src/sbot.rs +++ b/peach-lib/src/sbot.rs @@ -2,7 +2,7 @@ use std::{fs, fs::File, io, io::Write, path::PathBuf, process::Command, str}; use std::os::linux::raw::ino_t; -use tilde_client::{TildeClient, get_sbot_client}; +use tilde_client::{TildeClient}; use log::debug; use crate::config_manager; @@ -234,7 +234,7 @@ impl SbotConfig { // determine path of user's solar-sbot config.toml let config_path = format!( "{}/config.toml", - config_manager::get_config_value("SOLAR_SBOT_DATADIR")? + config_manager::get_config_value("TILDE_SBOT_DATADIR")? ); let config_contents = fs::read_to_string(config_path)?; @@ -254,7 +254,7 @@ impl SbotConfig { // determine path of user's solar-sbot config.toml let config_path = format!( "{}/config.toml", - config_manager::get_config_value("SOLAR_SBOT_DATADIR")? + config_manager::get_config_value("TILDE_SBOT_DATADIR")? ); // open config file for writing @@ -279,10 +279,14 @@ pub async fn init_sbot() -> Result { // initialise sbot connection with ip:port and shscap from config file let key_path = format!( "{}/secret", - config_manager::get_config_value("SOLAR_SBOT_DATADIR")? + config_manager::get_config_value("TILDE_SBOT_DATADIR")? ); // TODO: read this from config const SERVER_ADDR: &str = "http://127.0.0.1:3030"; - let sbot_client = get_sbot_client(); + let sbot_client = TildeClient { + name: "name".to_string(), + port: "8009".to_string(), + binary_path: config_manager::get_config_value("TILDE_BINARY_PATH")? + }; Ok(sbot_client) } diff --git a/peach-web/src/error.rs b/peach-web/src/error.rs index 2664364..dfe7ec6 100644 --- a/peach-web/src/error.rs +++ b/peach-web/src/error.rs @@ -6,6 +6,7 @@ use peach_lib::error::PeachError; use peach_lib::{serde_json, serde_yaml}; use serde_json::error::Error as JsonError; use serde_yaml::Error as YamlError; +use peach_lib::tilde_client::TildeError; /// Custom error type encapsulating all possible errors for the web application. #[derive(Debug)] @@ -17,6 +18,7 @@ pub enum PeachWebError { OsString, PeachLib { source: PeachError, msg: String }, Yaml(YamlError), + Tilde(TildeError), NotYetImplemented, } @@ -30,6 +32,7 @@ impl std::error::Error for PeachWebError { PeachWebError::OsString => None, PeachWebError::PeachLib { ref source, .. } => Some(source), PeachWebError::Yaml(ref source) => Some(source), + PeachWebError::Tilde(ref source) => Some(source), PeachWebError::NotYetImplemented => None } } @@ -53,6 +56,7 @@ impl std::fmt::Display for PeachWebError { ), PeachWebError::PeachLib { ref source, .. } => write!(f, "{}", source), PeachWebError::Yaml(ref source) => write!(f, "Serde YAML error: {}", source), + PeachWebError::Tilde(ref source) => write!(f, "Tilde error: {}", source), PeachWebError::NotYetImplemented => write!(f, "Not yet implemented"), } } @@ -84,3 +88,9 @@ impl From for PeachWebError { PeachWebError::Yaml(err) } } + +impl From for PeachWebError { + fn from(err: TildeError) -> PeachWebError { + PeachWebError::Tilde(err) + } +} \ No newline at end of file diff --git a/peach-web/src/utils/sbot.rs b/peach-web/src/utils/sbot.rs index c167489..e9dbdf6 100644 --- a/peach-web/src/utils/sbot.rs +++ b/peach-web/src/utils/sbot.rs @@ -151,16 +151,15 @@ pub fn create_invite(uses: u16) -> Result { let mut sbot_client = init_sbot_client().await?; debug!("Generating Scuttlebutt invite code"); - Err(PeachWebError::NotYetImplemented) - // let mut invite_code = sbot_client.invite_create(uses).await?; - // - // // insert domain into invite if one is configured + let mut invite_code = sbot_client.create_invite(uses as i32).await?; + + // // TODO: insert domain into invite if one is configured // let domain = config_manager::get_config_value("EXTERNAL_DOMAIN")?; // if !domain.is_empty() { // invite_code = domain + &invite_code[4..]; // } // - // Ok(invite_code) + Ok(invite_code) }) } @@ -445,19 +444,21 @@ pub fn get_blocks_list() -> Result>, Box> pub async fn get_peer_info(key: &str) -> Result, Box> { let mut sbot_client = init_sbot_client().await?; // key,value dict of info about this peer - let mut peer_info = HashMap::new(); - // retrieve the profile info for the given peer - // TODO: get all profile info not just latest_name - // TODO: latest_name throws an error - // TODO: just show as "error" isntead of aborting, if some field doesn't fetch - // let latest_name = sbot_client.latest_name(&key).await?; - let latest_name = "latest name".to_string(); - if let Some(latest_description) = sbot_client.latest_description(&key).await.ok() { - peer_info.insert("description".to_string(), latest_description); + let tilde_profile_info = sbot_client.get_profile_info(key).await.map_err(|err| { + println!("error getting profile info: {}", err); + err } + )?; + let mut peer_info = HashMap::new(); + tilde_profile_info.get("name").and_then(|val| val.as_str()).map(|val| { + peer_info.insert("name".to_string(), val.to_string()); + }); + tilde_profile_info.get("description").and_then(|val| val.as_str()).map(|val| { + peer_info.insert("description".to_string(), val.to_string()); + }); + // insert the public key of the peer into the info hashmap peer_info.insert("id".to_string(), key.to_string()); - peer_info.insert("name".to_string(), latest_name); // retrieve the profile image blob id for the given peer // TODO: blob support // if let Some(blob_id) = peer_info.get("image") { diff --git a/tilde-client/src/lib.rs b/tilde-client/src/lib.rs index 891ced0..b2205d9 100644 --- a/tilde-client/src/lib.rs +++ b/tilde-client/src/lib.rs @@ -1,6 +1,7 @@ // methods for interacting with tilde sbot -use crate::error::TildeError; +use std::collections::HashMap; +pub use crate::error::TildeError; use serde_json::Value; use std::process::{Command, exit}; @@ -8,44 +9,51 @@ use std::process::{Command, exit}; mod error; pub struct TildeClient { - name: String, - port: String + pub name: String, + pub port: String, + pub binary_path: String, } pub fn init_sbot() { println!("++ init sbot!"); } -pub fn get_sbot_client() -> TildeClient { - TildeClient { - name: "name".to_string(), - port: "8009".to_string() - } -} - - impl TildeClient { - pub fn run_tilde_command(&self, command: &str) -> Result { - let output = Command::new("out/release/tildefriends.standalone") - .arg(command) + pub fn run_tilde_command(&self, args: Vec<&str>) -> Result { + let mut command = Command::new(&self.binary_path); + command.args(args); + let output = command .output().map_err(|e| TildeError { message: format!("Command execution failed: {}", e), })?; if !output.status.success() { + println!("command: {:?}", command); + println!("stderr: {:?}", String::from_utf8_lossy(&output.stderr).to_string()); + println!("stdout: {:?}", String::from_utf8_lossy(&output.stdout).to_string()); return Err(TildeError { message: format!("Command failed with status: {}", output.status) }) } let result = String::from_utf8_lossy(&output.stdout).to_string(); println!("Command output: {}", result); + Ok(result) } - pub async fn latest_description(&self, key: &str) -> Result { - todo!(); + + pub async fn tilde_command_to_value(&self, args: Vec<&str>) -> Result { + let result = self.run_tilde_command(args)?; + let value = serde_json::from_str(&result).map_err(|e| TildeError { + message: format!("Failed to parse JSON: {}", e), + })?; + Ok(value) } pub async fn whoami(&self) -> Result { - self.run_tilde_command("get_identity") + self.run_tilde_command(vec!["get_identity"]).map(|val| val.trim_end().to_string()) + } + + pub async fn get_profile_info(&self, key: &str) -> Result { + self.tilde_command_to_value(vec!["get_profile", "-i", key]).await } pub async fn is_following(&self, from_id: &str, to_id: &str) -> Result { @@ -67,7 +75,15 @@ impl TildeClient { todo!(); } - pub async fn publish(&self, post: Value) -> Result, TildeError> { - todo!(); + pub async fn publish(&self, post: Value) -> Result { + let json_string = post.to_string(); + let key = self.whoami().await?; + self.run_tilde_command(vec!["publish", "-u", ":admin", "-i", &key, "-c", &json_string]) + } + + pub async fn create_invite(&self, num_uses: i32) -> Result { + // TODO: look up ip/domain from config + let key = self.whoami().await?; + self.run_tilde_command(vec!["create_invite", "-u", &num_uses.to_string(), "-i", &key, "-p", &self.port, "-a", "127.0.0.1", "-e", "-1"]) } }