Get description

This commit is contained in:
notplants 2021-12-29 15:12:20 -05:00
parent 0aeed5578e
commit 696701e855
2 changed files with 96 additions and 21 deletions

View File

@ -29,16 +29,55 @@ pub struct SsbMessageValue {
pub signature: String,
}
// Enum representing the different possible message content types
#[derive(Debug)]
pub enum SsbMessageContentType {
About,
Vote,
Post,
Contact,
None
}
impl SsbMessageValue {
/// Gets the type field of the message content if found,
/// and if not returns "none"
pub fn get_message_type(&self) -> String {
let msg_type: String = self
.content
.get("type")
.map(|msg_type| msg_type.to_string())
.unwrap_or_else(|| "none".to_string());
msg_type
/// Gets the type field of the message content as an enum, if found.
/// if no type field is found, it returns a SsbMessageContentType::None
/// if a type field is found with an invalid format it returns a GolgiError::ContentTypeDecode
pub fn get_message_type(&self) -> Result<SsbMessageContentType, GolgiError> {
let msg_type = self
.content
.get("type");
let enum_type = match msg_type {
Some(mtype) => {
let mtype_str: &str = mtype.as_str().ok_or(GolgiError::ContentTypeDecode("type field with invalid format".to_string()))?;
match mtype_str {
"about" => SsbMessageContentType::About,
"post" => SsbMessageContentType::Post,
"vote" => SsbMessageContentType::Vote,
"contact" => SsbMessageContentType::Contact,
_ => return Err(GolgiError::ContentTypeDecode("type field with unknown value".to_string()))
}
},
None => {
SsbMessageContentType::None
}
};
Ok(enum_type)
}
/// Helper function which returns true if this message is of the given type,
/// and false if the type does not match or is not found
pub fn is_message_type(&self, message_type: SsbMessageContentType) -> bool {
let self_message_type = self.get_message_type();
match self_message_type {
Ok(mtype) => {
matches!(mtype, message_type)
}
Err(_err) => {
false
}
}
}
/// Converts the content json value into an SsbMessageContent enum,

View File

@ -5,7 +5,7 @@ use kuska_handshake::async_std::BoxStream;
use kuska_sodiumoxide::crypto::{auth, sign::ed25519};
use kuska_ssb::{
api::{
dto::{content::SubsetQuery, CreateHistoryStreamIn},
dto::{CreateHistoryStreamIn},
ApiCaller,
},
discovery, keystore,
@ -14,9 +14,12 @@ use kuska_ssb::{
};
use crate::error::GolgiError;
use crate::messages::{SsbKVT, SsbMessageContent, SsbMessageValue};
use crate::messages::{SsbKVT, SsbMessageContent, SsbMessageValue, SsbMessageContentType};
use crate::utils;
// re-export types from kuska
pub use kuska_ssb::api::dto::content::SubsetQuery;
/// The Scuttlebutt identity, keys and configuration parameters for connecting to a local sbot
/// instance, as well as handles for calling RPC methods and receiving responses.
pub struct Sbot {
@ -154,20 +157,53 @@ impl Sbot {
}
/// Get the about messages for a particular user.
pub async fn get_about_messages(&mut self, ssb_id: String) -> Result<String, GolgiError> {
let req_id = self.client.getsubset_req_send(query).await?;
utils::get_async_until_eof(&mut self.rpc_reader, req_id, utils::kvt_res_parse).await
/// Get the about messages for a particular user in order of recency.
pub async fn get_about_messages(&mut self, ssb_id: String) -> Result<Vec<SsbMessageValue>, GolgiError> {
let query = SubsetQuery::Author{
op: "author".to_string(),
feed: self.id.to_string(),
};
let kvts: Vec<SsbKVT> = self.get_subset(query).await?;
let messages: Vec<SsbMessageValue> = kvts.into_iter().map(|kvt| kvt.value).collect();
// TODO: after fixing sbot regression,
// change this subset query to filter by type about in addition to author
// and remove this filter section
// filter down to about messages
let mut about_messages: Vec<SsbMessageValue> = messages.into_iter().filter(|msg| {
msg.is_message_type(SsbMessageContentType::About)
}).collect();
// TODO: use subset query to order messages instead of doing it this way
about_messages.sort_by(|a, b| {
a.timestamp.partial_cmp(&b.timestamp).unwrap()
});
// return about messages
Ok(about_messages)
}
/// Get the latest description for a particular user from their about messages.
pub async fn get_description(&mut self, ssb_id: String) -> Result<String, GolgiError> {
let req_id = self.client.getsubset_req_send(query).await?;
utils::get_async_until_eof(&mut self.rpc_reader, req_id, utils::kvt_res_parse).await
// vector of about messages with most recent at the front of the vector
let about_messages = self.get_about_messages(ssb_id).await?;
// iterate through the vector looking for an about message with a description
// the first one we find is th emost recnet
for msg in about_messages {
let about_message = msg.into_ssb_message_content()?;
match about_message {
SsbMessageContent::About{description, ..} => {
match description {
Some(description_text) => {
return Ok(description_text)
},
None => {
continue
}
}
},
_ => {}
}
}
// if no about message with a description was found, then return the empty string
Ok("".to_string())
}
/// Call the `createHistoryStream` RPC method and return a vector