Use mention tag name instead of href when parsing incoming notes
This commit is contained in:
parent
2df7f7ced7
commit
d31d315517
3 changed files with 36 additions and 16 deletions
|
@ -9,7 +9,7 @@ use crate::config::{Config, Instance};
|
|||
use crate::database::{Pool, get_database_client};
|
||||
use crate::errors::{DatabaseError, HttpError, ValidationError};
|
||||
use crate::models::attachments::queries::create_attachment;
|
||||
use crate::models::posts::types::{Post, PostCreateData, Visibility};
|
||||
use crate::models::posts::mentions::mention_to_acct;
|
||||
use crate::models::posts::queries::{
|
||||
create_post,
|
||||
get_post_by_id,
|
||||
|
@ -17,6 +17,7 @@ use crate::models::posts::queries::{
|
|||
delete_post,
|
||||
};
|
||||
use crate::models::posts::tags::normalize_tag;
|
||||
use crate::models::posts::types::{Post, PostCreateData, Visibility};
|
||||
use crate::models::profiles::queries::{
|
||||
get_profile_by_actor_id,
|
||||
get_profile_by_acct,
|
||||
|
@ -241,13 +242,9 @@ pub async fn process_note(
|
|||
tags.push(tag_name);
|
||||
};
|
||||
} else if tag.tag_type == MENTION {
|
||||
if let Some(href) = tag.href {
|
||||
let profile = get_or_fetch_profile_by_actor_id(
|
||||
db_client,
|
||||
&instance,
|
||||
&href,
|
||||
&config.media_dir(),
|
||||
).await?;
|
||||
// Ignore invalid mentions
|
||||
if let Ok(acct) = mention_to_acct(&instance.host(), &tag.name) {
|
||||
let profile = get_profile_by_acct(db_client, &acct).await?;
|
||||
if !mentions.contains(&profile.id) {
|
||||
mentions.push(profile.id);
|
||||
};
|
||||
|
|
|
@ -3,11 +3,12 @@ use std::collections::HashMap;
|
|||
use regex::{Captures, Regex};
|
||||
use tokio_postgres::GenericClient;
|
||||
|
||||
use crate::errors::DatabaseError;
|
||||
use crate::errors::{DatabaseError, ValidationError};
|
||||
use crate::models::profiles::queries::get_profiles_by_accts;
|
||||
use crate::models::profiles::types::DbActorProfile;
|
||||
|
||||
const MENTION_RE: &str = r"(?m)(?P<space>^|\s)@(?P<user>\w+)@(?P<instance>\S+)";
|
||||
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+)";
|
||||
|
||||
fn pattern_to_acct(caps: &Captures, instance_host: &str) -> String {
|
||||
if &caps["instance"] == instance_host {
|
||||
|
@ -22,7 +23,7 @@ fn find_mentions(
|
|||
instance_host: &str,
|
||||
text: &str,
|
||||
) -> Vec<String> {
|
||||
let mention_re = Regex::new(MENTION_RE).unwrap();
|
||||
let mention_re = Regex::new(MENTION_SEARCH_RE).unwrap();
|
||||
let mut mentions = vec![];
|
||||
for caps in mention_re.captures_iter(text) {
|
||||
let acct = pattern_to_acct(&caps, instance_host);
|
||||
|
@ -53,12 +54,13 @@ pub fn replace_mentions(
|
|||
instance_url: &str,
|
||||
text: &str,
|
||||
) -> String {
|
||||
let mention_re = Regex::new(MENTION_RE).unwrap();
|
||||
let mention_re = Regex::new(MENTION_SEARCH_RE).unwrap();
|
||||
let result = mention_re.replace_all(text, |caps: &Captures| {
|
||||
let acct = pattern_to_acct(caps, instance_host);
|
||||
match mention_map.get(&acct) {
|
||||
Some(profile) => {
|
||||
// Replace with a link
|
||||
// Replace with a link to profile.
|
||||
// Actor URL may differ from actor ID.
|
||||
let url = profile.actor_url(instance_url).unwrap();
|
||||
format!(
|
||||
// https://microformats.org/wiki/h-card
|
||||
|
@ -74,6 +76,17 @@ pub fn replace_mentions(
|
|||
result.to_string()
|
||||
}
|
||||
|
||||
pub fn mention_to_acct(
|
||||
instance_host: &str,
|
||||
mention: &str,
|
||||
) -> Result<String, ValidationError> {
|
||||
let mention_re = Regex::new(MENTION_RE).unwrap();
|
||||
let mention_caps = mention_re.captures(mention)
|
||||
.ok_or(ValidationError("invalid mention tag"))?;
|
||||
let acct = pattern_to_acct(&mention_caps, instance_host);
|
||||
Ok(acct)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json::json;
|
||||
|
@ -131,4 +144,14 @@ mod tests {
|
|||
);
|
||||
assert_eq!(result, expected_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mention_to_acct() {
|
||||
let mention = "@user@example.com";
|
||||
let acct_1 = mention_to_acct("example.com", mention).unwrap();
|
||||
assert_eq!(acct_1, "user");
|
||||
|
||||
let acct_2 = mention_to_acct("server.info", mention).unwrap();
|
||||
assert_eq!(acct_2, "user@example.com");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use regex::{Captures, Regex};
|
||||
|
||||
use crate::errors::ConversionError;
|
||||
use crate::errors::ValidationError;
|
||||
use crate::frontend::get_tag_page_url;
|
||||
|
||||
const HASHTAG_RE: &str = r"(?m)(?P<before>^|\s)#(?P<tag>\S+)";
|
||||
|
@ -52,11 +52,11 @@ pub fn replace_tags(instance_url: &str, text: &str, tags: &[String]) -> String {
|
|||
result.to_string()
|
||||
}
|
||||
|
||||
pub fn normalize_tag(tag: &str) -> Result<String, ConversionError> {
|
||||
pub fn normalize_tag(tag: &str) -> Result<String, ValidationError> {
|
||||
let hashtag_name_re = Regex::new(HASHTAG_NAME_RE).unwrap();
|
||||
let tag_name = tag.trim_start_matches('#');
|
||||
if !hashtag_name_re.is_match(tag_name) {
|
||||
return Err(ConversionError);
|
||||
return Err(ValidationError("invalid tag name"));
|
||||
};
|
||||
Ok(tag_name.to_lowercase())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue