Refactor ActorAddress type
This commit is contained in:
parent
cde324c07d
commit
429f530a71
5 changed files with 29 additions and 35 deletions
|
@ -114,18 +114,15 @@ pub struct Actor {
|
||||||
impl Actor {
|
impl Actor {
|
||||||
pub fn address(
|
pub fn address(
|
||||||
&self,
|
&self,
|
||||||
this_instance_host: &str,
|
|
||||||
) -> Result<ActorAddress, ValidationError> {
|
) -> Result<ActorAddress, ValidationError> {
|
||||||
let actor_host = url::Url::parse(&self.id)
|
let actor_host = url::Url::parse(&self.id)
|
||||||
.map_err(|_| ValidationError("invalid actor ID"))?
|
.map_err(|_| ValidationError("invalid actor ID"))?
|
||||||
.host_str()
|
.host_str()
|
||||||
.ok_or(ValidationError("invalid actor ID"))?
|
.ok_or(ValidationError("invalid actor ID"))?
|
||||||
.to_owned();
|
.to_owned();
|
||||||
let is_local = actor_host == this_instance_host;
|
|
||||||
let actor_address = ActorAddress {
|
let actor_address = ActorAddress {
|
||||||
username: self.preferred_username.clone(),
|
username: self.preferred_username.clone(),
|
||||||
instance: actor_host,
|
instance: actor_host,
|
||||||
is_local,
|
|
||||||
};
|
};
|
||||||
Ok(actor_address)
|
Ok(actor_address)
|
||||||
}
|
}
|
||||||
|
@ -179,7 +176,6 @@ impl Actor {
|
||||||
pub struct ActorAddress {
|
pub struct ActorAddress {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub instance: String,
|
pub instance: String,
|
||||||
pub is_local: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToString for ActorAddress {
|
impl ToString for ActorAddress {
|
||||||
|
@ -189,9 +185,13 @@ impl ToString for ActorAddress {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActorAddress {
|
impl ActorAddress {
|
||||||
|
pub fn is_local(&self, instance_host: &str) -> bool {
|
||||||
|
self.instance == instance_host
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns acct string, as used in Mastodon
|
/// Returns acct string, as used in Mastodon
|
||||||
pub fn acct(&self) -> String {
|
pub fn acct(&self, instance_host: &str) -> String {
|
||||||
if self.is_local {
|
if self.is_local(instance_host) {
|
||||||
self.username.clone()
|
self.username.clone()
|
||||||
} else {
|
} else {
|
||||||
self.to_string()
|
self.to_string()
|
||||||
|
@ -337,9 +337,9 @@ mod tests {
|
||||||
preferred_username: "test".to_string(),
|
preferred_username: "test".to_string(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let actor_address = actor.address(INSTANCE_HOST).unwrap();
|
let actor_address = actor.address().unwrap();
|
||||||
assert_eq!(actor_address.is_local, false);
|
assert_eq!(actor_address.is_local(INSTANCE_HOST), false);
|
||||||
assert_eq!(actor_address.acct(), "test@test.org");
|
assert_eq!(actor_address.acct(INSTANCE_HOST), "test@test.org");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -63,8 +63,8 @@ async fn create_remote_profile(
|
||||||
media_dir: &Path,
|
media_dir: &Path,
|
||||||
actor: Actor,
|
actor: Actor,
|
||||||
) -> Result<DbActorProfile, ImportError> {
|
) -> Result<DbActorProfile, ImportError> {
|
||||||
let actor_address = actor.address(&instance.host())?;
|
let actor_address = actor.address()?;
|
||||||
if actor_address.is_local {
|
if actor_address.is_local(&instance.host()) {
|
||||||
return Err(ImportError::LocalObject);
|
return Err(ImportError::LocalObject);
|
||||||
};
|
};
|
||||||
let avatar = fetch_actor_avatar(&actor, media_dir, None).await;
|
let avatar = fetch_actor_avatar(&actor, media_dir, None).await;
|
||||||
|
@ -74,7 +74,7 @@ async fn create_remote_profile(
|
||||||
let mut profile_data = ProfileCreateData {
|
let mut profile_data = ProfileCreateData {
|
||||||
username: actor.preferred_username.clone(),
|
username: actor.preferred_username.clone(),
|
||||||
display_name: actor.name.clone(),
|
display_name: actor.name.clone(),
|
||||||
acct: actor_address.acct(),
|
acct: actor_address.acct(&instance.host()),
|
||||||
bio: actor.summary.clone(),
|
bio: actor.summary.clone(),
|
||||||
avatar,
|
avatar,
|
||||||
banner,
|
banner,
|
||||||
|
@ -126,8 +126,9 @@ pub async fn get_or_import_profile_by_actor_id(
|
||||||
},
|
},
|
||||||
Err(DatabaseError::NotFound(_)) => {
|
Err(DatabaseError::NotFound(_)) => {
|
||||||
let actor = fetch_actor(instance, actor_id).await?;
|
let actor = fetch_actor(instance, actor_id).await?;
|
||||||
let actor_address = actor.address(&instance.host())?;
|
let actor_address = actor.address()?;
|
||||||
match get_profile_by_acct(db_client, &actor_address.acct()).await {
|
let acct = actor_address.acct(&instance.host());
|
||||||
|
match get_profile_by_acct(db_client, &acct).await {
|
||||||
Ok(profile) => {
|
Ok(profile) => {
|
||||||
// WARNING: Possible actor ID change
|
// WARNING: Possible actor ID change
|
||||||
log::info!("re-fetched profile {}", profile.acct);
|
log::info!("re-fetched profile {}", profile.acct);
|
||||||
|
@ -140,7 +141,7 @@ pub async fn get_or_import_profile_by_actor_id(
|
||||||
profile_updated
|
profile_updated
|
||||||
},
|
},
|
||||||
Err(DatabaseError::NotFound(_)) => {
|
Err(DatabaseError::NotFound(_)) => {
|
||||||
log::info!("fetched profile {}", actor_address.acct());
|
log::info!("fetched profile {}", acct);
|
||||||
let profile = create_remote_profile(
|
let profile = create_remote_profile(
|
||||||
db_client,
|
db_client,
|
||||||
instance,
|
instance,
|
||||||
|
@ -169,8 +170,8 @@ pub async fn import_profile_by_actor_address(
|
||||||
};
|
};
|
||||||
let actor_id = perform_webfinger_query(instance, actor_address).await?;
|
let actor_id = perform_webfinger_query(instance, actor_address).await?;
|
||||||
let actor = fetch_actor(instance, &actor_id).await?;
|
let actor = fetch_actor(instance, &actor_id).await?;
|
||||||
let profile_acct = actor.address(&instance.host())?.acct();
|
let profile_acct = actor.address()?.acct(&instance.host());
|
||||||
if profile_acct != actor_address.acct() {
|
if profile_acct != actor_address.acct(&instance.host()) {
|
||||||
// Redirected to different server
|
// Redirected to different server
|
||||||
match get_profile_by_acct(db_client, &profile_acct).await {
|
match get_profile_by_acct(db_client, &profile_acct).await {
|
||||||
Ok(profile) => return Ok(profile),
|
Ok(profile) => return Ok(profile),
|
||||||
|
|
|
@ -266,13 +266,11 @@ pub async fn handle_note(
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if let Ok(actor_address) = mention_to_address(
|
if let Ok(actor_address) = mention_to_address(&tag_name) {
|
||||||
&instance.host(),
|
let acct = actor_address.acct(&instance.host());
|
||||||
&tag_name,
|
|
||||||
) {
|
|
||||||
let profile = match get_profile_by_acct(
|
let profile = match get_profile_by_acct(
|
||||||
db_client,
|
db_client,
|
||||||
&actor_address.acct(),
|
&acct,
|
||||||
).await {
|
).await {
|
||||||
Ok(profile) => profile,
|
Ok(profile) => profile,
|
||||||
Err(DatabaseError::NotFound(_)) => {
|
Err(DatabaseError::NotFound(_)) => {
|
||||||
|
@ -287,7 +285,7 @@ pub async fn handle_note(
|
||||||
// Ignore mention if fetcher fails
|
// Ignore mention if fetcher fails
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"failed to find mentioned profile {}: {}",
|
"failed to find mentioned profile {}: {}",
|
||||||
actor_address.acct(),
|
acct,
|
||||||
error,
|
error,
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -111,7 +111,6 @@ async fn search_profiles_or_import(
|
||||||
let actor_address = ActorAddress {
|
let actor_address = ActorAddress {
|
||||||
username: username,
|
username: username,
|
||||||
instance: instance.unwrap(),
|
instance: instance.unwrap(),
|
||||||
is_local: false,
|
|
||||||
};
|
};
|
||||||
match import_profile_by_actor_address(
|
match import_profile_by_actor_address(
|
||||||
db_client,
|
db_client,
|
||||||
|
|
|
@ -26,9 +26,8 @@ fn find_mentions(
|
||||||
let actor_address = ActorAddress {
|
let actor_address = ActorAddress {
|
||||||
username: caps["user"].to_string(),
|
username: caps["user"].to_string(),
|
||||||
instance: secondary_caps["instance"].to_string(),
|
instance: secondary_caps["instance"].to_string(),
|
||||||
is_local: &secondary_caps["instance"] == instance_host,
|
|
||||||
};
|
};
|
||||||
let acct = actor_address.acct();
|
let acct = actor_address.acct(instance_host);
|
||||||
if !mentions.contains(&acct) {
|
if !mentions.contains(&acct) {
|
||||||
mentions.push(acct);
|
mentions.push(acct);
|
||||||
};
|
};
|
||||||
|
@ -64,9 +63,8 @@ pub fn replace_mentions(
|
||||||
let actor_address = ActorAddress {
|
let actor_address = ActorAddress {
|
||||||
username: caps["user"].to_string(),
|
username: caps["user"].to_string(),
|
||||||
instance: secondary_caps["instance"].to_string(),
|
instance: secondary_caps["instance"].to_string(),
|
||||||
is_local: &secondary_caps["instance"] == instance_host,
|
|
||||||
};
|
};
|
||||||
let acct = actor_address.acct();
|
let acct = actor_address.acct(instance_host);
|
||||||
if let Some(profile) = mention_map.get(&acct) {
|
if let Some(profile) = mention_map.get(&acct) {
|
||||||
// Replace with a link to profile.
|
// Replace with a link to profile.
|
||||||
// Actor URL may differ from actor ID.
|
// Actor URL may differ from actor ID.
|
||||||
|
@ -89,7 +87,6 @@ pub fn replace_mentions(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mention_to_address(
|
pub fn mention_to_address(
|
||||||
instance_host: &str,
|
|
||||||
mention: &str,
|
mention: &str,
|
||||||
) -> Result<ActorAddress, ValidationError> {
|
) -> Result<ActorAddress, ValidationError> {
|
||||||
let mention_re = Regex::new(MENTION_RE).unwrap();
|
let mention_re = Regex::new(MENTION_RE).unwrap();
|
||||||
|
@ -98,7 +95,6 @@ pub fn mention_to_address(
|
||||||
let actor_address = ActorAddress {
|
let actor_address = ActorAddress {
|
||||||
username: mention_caps["user"].to_string(),
|
username: mention_caps["user"].to_string(),
|
||||||
instance: mention_caps["instance"].to_string(),
|
instance: mention_caps["instance"].to_string(),
|
||||||
is_local: &mention_caps["instance"] == instance_host,
|
|
||||||
};
|
};
|
||||||
Ok(actor_address)
|
Ok(actor_address)
|
||||||
}
|
}
|
||||||
|
@ -182,14 +178,14 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mention_to_address() {
|
fn test_mention_to_address() {
|
||||||
let mention = "@user@example.com";
|
let mention = "@user@example.com";
|
||||||
let address_1 = mention_to_address("example.com", mention).unwrap();
|
let address_1 = mention_to_address(mention).unwrap();
|
||||||
assert_eq!(address_1.acct(), "user");
|
assert_eq!(address_1.acct("example.com"), "user");
|
||||||
|
|
||||||
let address_2 = mention_to_address("server.info", mention).unwrap();
|
let address_2 = mention_to_address(mention).unwrap();
|
||||||
assert_eq!(address_2.acct(), "user@example.com");
|
assert_eq!(address_2.acct("server.info"), "user@example.com");
|
||||||
|
|
||||||
let short_mention = "@user";
|
let short_mention = "@user";
|
||||||
let result = mention_to_address("example.com", short_mention);
|
let result = mention_to_address(short_mention);
|
||||||
assert_eq!(result.is_err(), true);
|
assert_eq!(result.is_err(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue