Refactor mention_to_acct to return detailed actor address
This commit is contained in:
parent
0fe8423031
commit
fae3f5bc2f
3 changed files with 43 additions and 19 deletions
|
@ -124,6 +124,23 @@ impl DbActorProfile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ActorAddress {
|
||||||
|
pub username: String,
|
||||||
|
pub instance: String,
|
||||||
|
pub is_local: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActorAddress {
|
||||||
|
/// Returns acct string, as used in Mastodon
|
||||||
|
pub fn acct(&self) -> String {
|
||||||
|
if self.is_local {
|
||||||
|
self.username.clone()
|
||||||
|
} else {
|
||||||
|
format!("{}@{}", self.username, self.instance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type ActorKeyError = rsa::pkcs8::Error;
|
pub type ActorKeyError = rsa::pkcs8::Error;
|
||||||
|
|
||||||
pub fn get_local_actor(
|
pub fn get_local_actor(
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::config::{Config, Instance};
|
||||||
use crate::database::{Pool, get_database_client};
|
use crate::database::{Pool, get_database_client};
|
||||||
use crate::errors::{DatabaseError, HttpError, ValidationError};
|
use crate::errors::{DatabaseError, HttpError, ValidationError};
|
||||||
use crate::models::attachments::queries::create_attachment;
|
use crate::models::attachments::queries::create_attachment;
|
||||||
use crate::models::posts::mentions::mention_to_acct;
|
use crate::models::posts::mentions::mention_to_address;
|
||||||
use crate::models::posts::queries::{
|
use crate::models::posts::queries::{
|
||||||
create_post,
|
create_post,
|
||||||
get_post_by_id,
|
get_post_by_id,
|
||||||
|
@ -243,8 +243,14 @@ pub async fn process_note(
|
||||||
};
|
};
|
||||||
} else if tag.tag_type == MENTION {
|
} else if tag.tag_type == MENTION {
|
||||||
// Ignore invalid mentions
|
// Ignore invalid mentions
|
||||||
if let Ok(acct) = mention_to_acct(&instance.host(), &tag.name) {
|
if let Ok(actor_address) = mention_to_address(
|
||||||
let profile = get_profile_by_acct(db_client, &acct).await?;
|
&instance.host(),
|
||||||
|
&tag.name,
|
||||||
|
) {
|
||||||
|
let profile = get_profile_by_acct(
|
||||||
|
db_client,
|
||||||
|
&actor_address.acct(),
|
||||||
|
).await?;
|
||||||
if !mentions.contains(&profile.id) {
|
if !mentions.contains(&profile.id) {
|
||||||
mentions.push(profile.id);
|
mentions.push(profile.id);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,6 +3,7 @@ use std::collections::HashMap;
|
||||||
use regex::{Captures, Regex};
|
use regex::{Captures, Regex};
|
||||||
use tokio_postgres::GenericClient;
|
use tokio_postgres::GenericClient;
|
||||||
|
|
||||||
|
use crate::activitypub::actor::ActorAddress;
|
||||||
use crate::errors::{DatabaseError, ValidationError};
|
use crate::errors::{DatabaseError, ValidationError};
|
||||||
use crate::models::profiles::queries::get_profiles_by_accts;
|
use crate::models::profiles::queries::get_profiles_by_accts;
|
||||||
use crate::models::profiles::types::DbActorProfile;
|
use crate::models::profiles::types::DbActorProfile;
|
||||||
|
@ -10,11 +11,11 @@ use crate::models::profiles::types::DbActorProfile;
|
||||||
const MENTION_RE: &str = r"@?(?P<user>\w+)@(?P<instance>.+)";
|
const MENTION_RE: &str = r"@?(?P<user>\w+)@(?P<instance>.+)";
|
||||||
const MENTION_SEARCH_RE: &str = r"(?m)(?P<space>^|\s)@(?P<user>\w+)@(?P<instance>\S+)";
|
const MENTION_SEARCH_RE: &str = r"(?m)(?P<space>^|\s)@(?P<user>\w+)@(?P<instance>\S+)";
|
||||||
|
|
||||||
fn pattern_to_acct(caps: &Captures, instance_host: &str) -> String {
|
fn pattern_to_address(caps: &Captures, instance_host: &str) -> ActorAddress {
|
||||||
if &caps["instance"] == instance_host {
|
ActorAddress {
|
||||||
caps["user"].to_string()
|
username: caps["user"].to_string(),
|
||||||
} else {
|
instance: caps["instance"].to_string(),
|
||||||
format!("{}@{}", &caps["user"], &caps["instance"])
|
is_local: &caps["instance"] == instance_host,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ fn find_mentions(
|
||||||
let mention_re = Regex::new(MENTION_SEARCH_RE).unwrap();
|
let mention_re = Regex::new(MENTION_SEARCH_RE).unwrap();
|
||||||
let mut mentions = vec![];
|
let mut mentions = vec![];
|
||||||
for caps in mention_re.captures_iter(text) {
|
for caps in mention_re.captures_iter(text) {
|
||||||
let acct = pattern_to_acct(&caps, instance_host);
|
let acct = pattern_to_address(&caps, instance_host).acct();
|
||||||
if !mentions.contains(&acct) {
|
if !mentions.contains(&acct) {
|
||||||
mentions.push(acct);
|
mentions.push(acct);
|
||||||
};
|
};
|
||||||
|
@ -56,7 +57,7 @@ pub fn replace_mentions(
|
||||||
) -> String {
|
) -> String {
|
||||||
let mention_re = Regex::new(MENTION_SEARCH_RE).unwrap();
|
let mention_re = Regex::new(MENTION_SEARCH_RE).unwrap();
|
||||||
let result = mention_re.replace_all(text, |caps: &Captures| {
|
let result = mention_re.replace_all(text, |caps: &Captures| {
|
||||||
let acct = pattern_to_acct(caps, instance_host);
|
let acct = pattern_to_address(caps, instance_host).acct();
|
||||||
match mention_map.get(&acct) {
|
match mention_map.get(&acct) {
|
||||||
Some(profile) => {
|
Some(profile) => {
|
||||||
// Replace with a link to profile.
|
// Replace with a link to profile.
|
||||||
|
@ -76,15 +77,15 @@ pub fn replace_mentions(
|
||||||
result.to_string()
|
result.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mention_to_acct(
|
pub fn mention_to_address(
|
||||||
instance_host: &str,
|
instance_host: &str,
|
||||||
mention: &str,
|
mention: &str,
|
||||||
) -> Result<String, ValidationError> {
|
) -> Result<ActorAddress, ValidationError> {
|
||||||
let mention_re = Regex::new(MENTION_RE).unwrap();
|
let mention_re = Regex::new(MENTION_RE).unwrap();
|
||||||
let mention_caps = mention_re.captures(mention)
|
let mention_caps = mention_re.captures(mention)
|
||||||
.ok_or(ValidationError("invalid mention tag"))?;
|
.ok_or(ValidationError("invalid mention tag"))?;
|
||||||
let acct = pattern_to_acct(&mention_caps, instance_host);
|
let actor_address = pattern_to_address(&mention_caps, instance_host);
|
||||||
Ok(acct)
|
Ok(actor_address)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -146,12 +147,12 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_mention_to_acct() {
|
fn test_mention_to_address() {
|
||||||
let mention = "@user@example.com";
|
let mention = "@user@example.com";
|
||||||
let acct_1 = mention_to_acct("example.com", mention).unwrap();
|
let address_1 = mention_to_address("example.com", mention).unwrap();
|
||||||
assert_eq!(acct_1, "user");
|
assert_eq!(address_1.acct(), "user");
|
||||||
|
|
||||||
let acct_2 = mention_to_acct("server.info", mention).unwrap();
|
let address_2 = mention_to_address("server.info", mention).unwrap();
|
||||||
assert_eq!(acct_2, "user@example.com");
|
assert_eq!(address_2.acct(), "user@example.com");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue