104 lines
3.3 KiB
Rust
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
|
|
}
|