feat: replace mentions with html hrefs

This commit is contained in:
əlemi 2024-05-23 16:28:18 +02:00
parent b700e06d10
commit 17f77c1769
Signed by: alemi
GPG key ID: A4895B84D311642C
2 changed files with 25 additions and 2 deletions

View file

@ -22,6 +22,7 @@ openssl = "0.10" # TODO handle pubkeys with a smaller crate
base64 = "0.22" base64 = "0.22"
chrono = { version = "0.4", features = ["serde"] } chrono = { version = "0.4", features = ["serde"] }
uuid = { version = "1.8", features = ["v4"] } uuid = { version = "1.8", features = ["v4"] }
regex = "1.10"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
serde_default = "0.1" serde_default = "0.1"
@ -50,7 +51,7 @@ time = { version = "0.3", features = ["serde"], optional = true }
async-recursion = "1.1" async-recursion = "1.1"
[features] [features]
default = ["migrations", "cli"] default = ["mastodon", "migrations", "cli"]
cli = [] cli = []
migrations = ["dep:sea-orm-migration"] migrations = ["dep:sea-orm-migration"]
mastodon = ["dep:mastodon-async-entities", "dep:time"] mastodon = ["dep:mastodon-async-entities", "dep:time"]

View file

@ -1,6 +1,6 @@
use apb::{target::Addressed, Activity, ActivityMut, ActorMut, BaseMut, Node, Object, ObjectMut, PublicKeyMut}; use apb::{target::Addressed, Activity, ActivityMut, ActorMut, BaseMut, Node, Object, ObjectMut, PublicKeyMut};
use reqwest::StatusCode; use reqwest::StatusCode;
use sea_orm::{sea_query::Expr, ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter, Set}; use sea_orm::{sea_query::Expr, ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter, QuerySelect, SelectColumns, Set};
use crate::{errors::UpubError, model, routes::activitypub::jsonld::LD}; use crate::{errors::UpubError, model, routes::activitypub::jsonld::LD};
@ -14,15 +14,37 @@ impl apb::server::Outbox for Context {
type Activity = serde_json::Value; type Activity = serde_json::Value;
async fn create_note(&self, uid: String, object: serde_json::Value) -> crate::Result<String> { async fn create_note(&self, uid: String, object: serde_json::Value) -> crate::Result<String> {
let re = regex::Regex::new(r"@(\w+)@(\w+)").expect("failed compiling regex pattern");
let raw_oid = uuid::Uuid::new_v4().to_string(); let raw_oid = uuid::Uuid::new_v4().to_string();
let oid = self.oid(&raw_oid); let oid = self.oid(&raw_oid);
let aid = self.aid(&uuid::Uuid::new_v4().to_string()); let aid = self.aid(&uuid::Uuid::new_v4().to_string());
let activity_targets = object.addressed(); let activity_targets = object.addressed();
let mut content = object.content().map(|x| x.to_string());
if let Some(c) = content {
let mut tmp = mdhtml::safe_markdown(&c);
for (full, [user, domain]) in re.captures_iter(&tmp.clone()).map(|x| x.extract()) {
if let Ok(Some(uid)) = model::user::Entity::find()
.filter(model::user::Column::PreferredUsername.eq(user))
.filter(model::user::Column::Domain.eq(domain))
.select_only()
.select_column(model::user::Column::Id)
.into_tuple::<String>()
.one(self.db())
.await
{
tmp = tmp.replacen(full, &format!("<a href=\"{uid}\" class=\"u-url mention\">@{user}</a>"), 1);
}
}
content = Some(tmp);
}
let object_model = self.insert_object( let object_model = self.insert_object(
object object
.set_id(Some(&oid)) .set_id(Some(&oid))
.set_attributed_to(Node::link(uid.clone())) .set_attributed_to(Node::link(uid.clone()))
.set_published(Some(chrono::Utc::now())) .set_published(Some(chrono::Utc::now()))
.set_content(content.as_deref())
.set_url(Node::maybe_link(self.cfg().instance.frontend.as_ref().map(|x| format!("{x}/objects/{raw_oid}")))), .set_url(Node::maybe_link(self.cfg().instance.frontend.as_ref().map(|x| format!("{x}/objects/{raw_oid}")))),
Some(self.domain().to_string()), Some(self.domain().to_string()),
).await?; ).await?;