lykin/src/sbot.rs

104 lines
3.3 KiB
Rust

// Scuttlebutt functionality.
use async_std::stream::StreamExt;
use chrono::{NaiveDate, NaiveDateTime, TimeZone, Utc};
use golgi::{
api::friends::RelationshipQuery,
messages::{SsbMessageContentType, SsbMessageKVT},
sbot::Keystore,
GolgiError, Sbot,
};
use log::warn;
use serde_json::value::Value;
use crate::db::Post;
pub async fn whoami() -> Result<String, String> {
let mut sbot = Sbot::init(Keystore::Patchwork, None, None)
.await
.map_err(|e| e.to_string())?;
sbot.whoami().await.map_err(|e| e.to_string())
}
/// Follow a peer.
pub async fn follow_peer(public_key: &str) -> Result<String, String> {
let mut sbot = Sbot::init(Keystore::Patchwork, None, None)
.await
.map_err(|e| e.to_string())?;
sbot.follow(public_key).await.map_err(|e| e.to_string())
}
/// Check follow status.
///
/// Is peer A (`public_key_a`) following peer B (`public_key_b`)?
pub async fn is_following(public_key_a: &str, public_key_b: &str) -> Result<String, String> {
let mut sbot = Sbot::init(Keystore::Patchwork, None, None)
.await
.map_err(|e| e.to_string())?;
let query = RelationshipQuery {
source: public_key_a.to_string(),
dest: public_key_b.to_string(),
};
sbot.friends_is_following(query)
.await
.map_err(|e| e.to_string())
}
pub async fn get_message_stream(
public_key: &str,
) -> impl futures::Stream<Item = Result<SsbMessageKVT, GolgiError>> {
let mut sbot = Sbot::init(Keystore::Patchwork, None, None)
.await
.map_err(|e| e.to_string())
.unwrap();
sbot.create_history_stream(public_key.to_string())
.await
.unwrap()
}
pub async fn get_root_posts(
history_stream: impl futures::Stream<Item = Result<SsbMessageKVT, GolgiError>>,
) -> Vec<Post> {
let mut posts = Vec::new();
futures::pin_mut!(history_stream);
while let Some(res) = history_stream.next().await {
match res {
Ok(msg) => {
if msg.value.is_message_type(SsbMessageContentType::Post) {
let content = msg.value.content.to_owned();
if let Value::Object(map) = content {
if !map.contains_key("root") {
let text = map.get_key_value("text").unwrap();
let timestamp_int = msg.value.timestamp.round() as i64 / 1000;
//let timestamp = Utc.timestamp(timestamp_int, 0);
let datetime = NaiveDateTime::from_timestamp(timestamp_int, 0);
//let datetime = timestamp.to_rfc2822();
let date = datetime.format("%d %b %Y").to_string();
posts.push(Post {
key: msg.key.to_owned(),
text: text.1.to_string(),
date,
sequence: msg.value.sequence,
read: false,
})
}
}
}
}
Err(err) => {
// Print the `GolgiError` of this element to `stderr`.
warn!("err: {:?}", err);
}
}
}
posts
}