2025-05-06 14:03:06 -04:00

139 lines
4.7 KiB
Rust

// methods for interacting with tilde sbot
use std::collections::HashMap;
pub use crate::error::TildeError;
use serde_json::{json, Value};
use std::process::{Command, exit};
mod error;
pub struct TildeClient {
pub name: String,
pub port: String,
pub binary_path: String,
}
pub fn init_sbot() {
println!("++ init sbot!");
}
impl TildeClient {
pub fn run_tilde_command(&self, args: Vec<&str>) -> Result<String, TildeError> {
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 tilde_command_to_value(&self, args: Vec<&str>) -> Result<Value, TildeError> {
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<String, TildeError> {
self.run_tilde_command(vec!["get_identity"]).map(|val| val.trim_end().to_string())
}
pub async fn get_profile_info(&self, key: &str) -> Result<Value, TildeError> {
self.tilde_command_to_value(vec!["get_profile", "-i", key]).await
}
pub async fn latest_sequence_number(&self) -> Result<String, TildeError> {
let key = self.whoami().await?;
// let num = self.run_tilde_command(vec!["get_sequence", "-i", &key])?.parse::<u64>().map_err(|e| TildeError {
// message: format!("Failed to parse u64 from sequence number: {}", e),
// })?;
let num = self.run_tilde_command(vec!["get_sequence", "-i", &key])?;
println!("NUM: {}", num);
Ok(num)
}
pub async fn is_following(&self, from_id: &str, to_id: &str) -> Result<bool, TildeError> {
todo!();
}
pub async fn create_block(&self, key: &str) -> Result<bool, TildeError> {
todo!();
}
pub async fn get_blocks(&self, key: &str) -> Result<Vec<String>, TildeError> {
todo!();
}
pub async fn get_follows(&self, key: &str) -> Result<Vec<String>, TildeError> {
todo!();
}
pub async fn get_friends(&self, key: &str) -> Result<Vec<String>, TildeError> {
todo!();
}
pub async fn publish(&self, post: Value) -> Result<String, TildeError> {
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 publish_name(&self, name: &str) -> Result<String, TildeError> {
let key = self.whoami().await?;
let about_post = json!({
"type": "about",
"about": key,
"name": name
});
self.publish(about_post).await
}
pub async fn publish_description(&self, description: &str) -> Result<String, TildeError> {
let key = self.whoami().await?;
let about_post = json!({
"type": "about",
"about": key,
"description": description
});
self.publish(about_post).await
}
pub async fn publish_image(&self, image_blob_id: &str) -> Result<String, TildeError> {
let key = self.whoami().await?;
let about_post = json!({
"type": "about",
"about": key,
"image": image_blob_id
});
self.publish(about_post).await
}
pub async fn store_blob(&self, blob_file_path: &str) -> Result<String, TildeError> {
self.run_tilde_command(vec!["store_blob", "-f", blob_file_path])
}
pub async fn private_message(&self, recipient_key: &str, message: &str) -> Result<String, TildeError> {
let self_key = self.whoami().await?;
self.run_tilde_command(vec!["private", "-u", ":admin", "-i", &self_key, "-r", recipient_key, "-t", message])
}
pub async fn create_invite(&self, num_uses: i32) -> Result<String, TildeError> {
// 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"])
}
}