From a54d2e9d712eae59b469d4f115f0d06d35cf55db Mon Sep 17 00:00:00 2001 From: Bat Date: Thu, 6 Sep 2018 09:21:08 +0100 Subject: [PATCH] Federate tags --- plume-common/src/activity_pub/mod.rs | 17 +++++++++++++++++ plume-common/src/lib.rs | 1 + plume-models/src/posts.rs | 12 +++++++++--- plume-models/src/tags.rs | 19 +++++++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/plume-common/src/activity_pub/mod.rs b/plume-common/src/activity_pub/mod.rs index 626bdc1..d308983 100644 --- a/plume-common/src/activity_pub/mod.rs +++ b/plume-common/src/activity_pub/mod.rs @@ -158,3 +158,20 @@ pub struct PublicKey { #[activitystreams(concrete(String), functional)] pub public_key_pem: Option } + +#[derive(Clone, Debug, Default, UnitString)] +#[activitystreams(Hashtag)] +pub struct HashtagType; + +#[derive(Clone, Debug, Default, Deserialize, Serialize, Properties)] +#[serde(rename_all = "camelCase")] +pub struct Hashtag { + #[serde(rename = "type")] + kind: HashtagType, + + #[activitystreams(concrete(String), functional)] + pub href: Option, + + #[activitystreams(concrete(String), functional)] + pub name: Option, +} diff --git a/plume-common/src/lib.rs b/plume-common/src/lib.rs index edf731a..6625b0a 100644 --- a/plume-common/src/lib.rs +++ b/plume-common/src/lib.rs @@ -19,6 +19,7 @@ extern crate openssl; extern crate pulldown_cmark; extern crate reqwest; extern crate rocket; +extern crate serde; #[macro_use] extern crate serde_derive; #[macro_use] diff --git a/plume-models/src/posts.rs b/plume-models/src/posts.rs index 2bb978f..af37f4d 100644 --- a/plume-models/src/posts.rs +++ b/plume-models/src/posts.rs @@ -9,6 +9,7 @@ use heck::KebabCase; use serde_json; use plume_common::activity_pub::{ + Hashtag, PUBLIC_VISIBILTY, Id, IntoId, inbox::{Deletable, FromActivity} }; @@ -206,7 +207,8 @@ impl Post { let mut to = self.get_receivers_urls(conn); to.push(PUBLIC_VISIBILTY.to_string()); - let mentions = Mention::list_for_post(conn, self.id).into_iter().map(|m| m.to_activity(conn)).collect::>(); + let mut mentions_json = Mention::list_for_post(conn, self.id).into_iter().map(|m| json!(m.to_activity(conn))).collect::>(); + let mut tags_json = Tag::for_post(conn, self.id).into_iter().map(|t| json!(t.into_activity(conn))).collect::>(); let mut article = Article::default(); article.object_props.set_name_string(self.title.clone()).expect("Article::into_activity: name error"); @@ -218,7 +220,7 @@ impl Post { article.object_props.set_content_string(self.content.get().clone()).expect("Article::into_activity: content error"); article.object_props.set_published_utctime(Utc.from_utc_datetime(&self.creation_date)).expect("Article::into_activity: published error"); article.object_props.set_summary_string(self.subtitle.clone()).expect("Article::into_activity: summary error"); - article.object_props.set_tag_link_vec(mentions).expect("Article::into_activity: tag error"); + article.object_props.tag = json!(mentions_json.append(&mut tags_json)); article.object_props.set_url_string(self.ap_url.clone()).expect("Article::into_activity: url error"); article.object_props.set_to_link_vec::(to.into_iter().map(Id::new).collect()).expect("Article::into_activity: to error"); article.object_props.set_cc_link_vec::(vec![]).expect("Article::into_activity: cc error"); @@ -295,12 +297,16 @@ impl FromActivity for Post { }); } - // save mentions + // save mentions and tags if let Some(serde_json::Value::Array(tags)) = article.object_props.tag.clone() { for tag in tags.into_iter() { serde_json::from_value::(tag) .map(|m| Mention::from_activity(conn, m, post.id, true)) .ok(); + + serde_json::from_value::(tag) + .map(|t| Tag::from_activity(conn, t, post.id)) + .ok(); } } post diff --git a/plume-models/src/tags.rs b/plume-models/src/tags.rs index e94a54d..23a0d78 100644 --- a/plume-models/src/tags.rs +++ b/plume-models/src/tags.rs @@ -1,4 +1,8 @@ use diesel::{self, PgConnection, ExpressionMethods, RunQueryDsl, QueryDsl}; + +use plume_common::activity_pub::Hashtag; +use ap_url; +use instance::Instance; use schema::tags; #[derive(Serialize, Queryable)] @@ -21,4 +25,19 @@ impl Tag { insert!(tags, NewTag); get!(tags); list_by!(tags, for_post, post_id as i32); + + pub fn into_activity(&self, conn: &PgConnection) -> Hashtag { + let ht = Hashtag::default(); + ht.set_href_string(ap_url(format!("{}/tag/{}", Instance::get_local(conn).unwrap().public_domain, self.tag))).expect("Tag::into_activity: href error"); + ht.set_name_string(self.tag).expect("Tag::into_activity: name error"); + ht + } + + pub fn from_activity(conn: &PgConnection, tag: Hashtag, post: i32) -> Tag { + Tag::insert(conn, NewTag { + tag: tag.name_string().expect("Tag::from_activity: name error"), + is_hastag: false, + post_id: post + }) + } }