Working on profile info
This commit is contained in:
parent
615431496b
commit
ccc4a3371b
91
src/sbot.rs
91
src/sbot.rs
|
@ -1,4 +1,5 @@
|
||||||
//! Sbot type and associated methods.
|
//! Sbot type and associated methods.
|
||||||
|
use std::collections::HashMap;
|
||||||
use async_std::{
|
use async_std::{
|
||||||
net::TcpStream,
|
net::TcpStream,
|
||||||
stream::{Stream, StreamExt},
|
stream::{Stream, StreamExt},
|
||||||
|
@ -281,33 +282,87 @@ impl Sbot {
|
||||||
// now we have a stream of about messages with most recent at the front of the vector
|
// now we have a stream of about messages with most recent at the front of the vector
|
||||||
pin_mut!(about_message_stream);
|
pin_mut!(about_message_stream);
|
||||||
// iterate through the vector looking for most recent about message with the given key
|
// iterate through the vector looking for most recent about message with the given key
|
||||||
let latest_about_message: Result<SsbMessageValue, GolgiError> = about_message_stream
|
let latest_about_message_res: Option<Result<SsbMessageValue, GolgiError>> = about_message_stream
|
||||||
// find the first msg that contains the field `key`
|
// find the first msg that contains the field `key`
|
||||||
.find(|res| match res {
|
.find(|res| match res {
|
||||||
Ok(msg) => msg.content.get(key).is_some(),
|
Ok(msg) => msg.content.get(key).is_some(),
|
||||||
Err(_) => false,
|
Err(_) => false,
|
||||||
})
|
})
|
||||||
.await
|
.await;
|
||||||
.ok_or_else(|| {
|
// Option<Result<SsbMessageValue, GolgiError>> -> Option<SsbMessageValue>
|
||||||
GolgiError::Sbot("error while looking for about message with given key".to_string())
|
let latest_about_message = latest_about_message_res.and_then(|msg| msg.ok());
|
||||||
})?;
|
// Option<SsbMessageValue> -> Option<String>
|
||||||
let latest_about_value = match latest_about_message {
|
let latest_about_value = latest_about_message.and_then(|msg| {
|
||||||
Ok(msg) => {
|
msg
|
||||||
msg
|
// SsbMessageValue -> Option<&Value>
|
||||||
// SsbMessageValue -> Option<&Value>
|
.content
|
||||||
.content
|
.get(key)
|
||||||
.get(key)
|
// Option<&Value> -> <Option<&str>
|
||||||
// Option<&Value> -> <Option<&str>
|
.and_then(|value| value.as_str())
|
||||||
.and_then(|value| value.as_str())
|
// Option<&str> -> Option<String>
|
||||||
// Option<&str> -> Option<String>
|
.map(|value| value.to_string())
|
||||||
.map(|value| value.to_string())
|
});
|
||||||
}
|
|
||||||
Err(_) => None,
|
|
||||||
};
|
|
||||||
// return value is either `Ok(Some(String))` or `Ok(None)`
|
// return value is either `Ok(Some(String))` or `Ok(None)`
|
||||||
Ok(latest_about_value)
|
Ok(latest_about_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get HashMap of profile info for given user
|
||||||
|
/// by iteratively searching through a stream of about messages,
|
||||||
|
/// in order of recency,
|
||||||
|
/// until we find all about messages for all needed info
|
||||||
|
/// or reach the end of the stream.
|
||||||
|
pub async fn get_profile_info(
|
||||||
|
&mut self,
|
||||||
|
ssb_id: &str
|
||||||
|
) -> Result<HashMap<String, String>, GolgiError> {
|
||||||
|
// get about_message_stream
|
||||||
|
let about_message_stream = self.get_about_message_stream(ssb_id).await?;
|
||||||
|
// now we have a stream of about messages with most recent at the front of the vector
|
||||||
|
pin_mut!(about_message_stream); // needed for iteration
|
||||||
|
let mut profile_info: HashMap<String, String> = HashMap::new();
|
||||||
|
// these are the about message keys we are looking for
|
||||||
|
// as we find values for each of these keys,
|
||||||
|
// we will remove them from this vector (as we are no longer searching for them)
|
||||||
|
let mut keys_to_search_for = vec!["name", "description", "profile"];
|
||||||
|
// iterate through the stream while it still has more values and
|
||||||
|
// we still have keys we are looking for
|
||||||
|
while let Some(res) = about_message_stream.next().await {
|
||||||
|
println!("res: {:?}", res);
|
||||||
|
// if there are no more keys we are looking for, then we are done
|
||||||
|
if keys_to_search_for.len() == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// if there are still keys we are looking for, then continue searching
|
||||||
|
match res {
|
||||||
|
Ok(msg) => {
|
||||||
|
// for each key we are searching for, check if this about
|
||||||
|
// message contains a value for that key
|
||||||
|
for key in &keys_to_search_for.clone() {
|
||||||
|
let option_val = msg.content.get(key)
|
||||||
|
.and_then(|val| val.as_str())
|
||||||
|
.map(|val| val.to_string());
|
||||||
|
match option_val {
|
||||||
|
Some(val) => {
|
||||||
|
// if a value is found, then insert it
|
||||||
|
profile_info.insert(key.to_string(), val);
|
||||||
|
// remove this key fom keys_to_search_for, since we are no longer searching for it
|
||||||
|
keys_to_search_for.retain(|val| val != key)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
// skip errors
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(profile_info)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get latest about name from given user
|
/// Get latest about name from given user
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
|
Loading…
Reference in New Issue