Get description
This commit is contained in:
parent
0aeed5578e
commit
696701e855
|
@ -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,
|
||||
|
|
60
src/sbot.rs
60
src/sbot.rs
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue