1 use crate::apub::create_apub_response;
2 use crate::apub::fetcher::{fetch_remote_community, fetch_remote_user};
3 use crate::convert_datetime;
4 use crate::db::community::Community;
5 use crate::db::post::{Post, PostForm};
6 use crate::db::user::User_;
8 use activitystreams::{context, object::properties::ObjectProperties, object::Page};
9 use actix_web::body::Body;
10 use actix_web::web::Path;
11 use actix_web::{web, HttpResponse};
12 use diesel::r2d2::{ConnectionManager, Pool};
13 use diesel::PgConnection;
15 use serde::Deserialize;
18 #[derive(Deserialize)]
19 pub struct PostQuery {
23 pub async fn get_apub_post(
24 info: Path<PostQuery>,
25 db: web::Data<Pool<ConnectionManager<PgConnection>>>,
26 ) -> Result<HttpResponse<Body>, Error> {
27 let id = info.post_id.parse::<i32>()?;
28 let post = Post::read(&&db.get()?, id)?;
29 Ok(create_apub_response(&post.as_page(&db.get().unwrap())?))
33 pub fn as_page(&self, conn: &PgConnection) -> Result<Page, Error> {
34 let mut page = Page::default();
35 let oprops: &mut ObjectProperties = page.as_mut();
36 let creator = User_::read(conn, self.creator_id)?;
37 let community = Community::read(conn, self.community_id)?;
40 // Not needed when the Post is embedded in a collection (like for community outbox)
41 .set_context_xsd_any_uri(context())?
42 .set_id(self.ap_id.to_owned())?
43 // Use summary field to be consistent with mastodon content warning.
44 // https://mastodon.xyz/@Louisa/103987265222901387.json
45 .set_summary_xsd_string(self.name.to_owned())?
46 .set_published(convert_datetime(self.published))?
47 .set_to_xsd_any_uri(community.actor_id)?
48 .set_attributed_to_xsd_any_uri(creator.actor_id)?;
50 if let Some(body) = &self.body {
51 oprops.set_content_xsd_string(body.to_owned())?;
54 // TODO: hacky code because we get self.url == Some("")
55 // https://github.com/dessalines/lemmy/issues/602
56 let url = self.url.as_ref().filter(|u| !u.is_empty());
57 if let Some(u) = url {
58 oprops.set_url_xsd_any_uri(u.to_owned())?;
61 if let Some(u) = self.updated {
62 oprops.set_updated(convert_datetime(u))?;
70 pub fn from_page(page: &Page, conn: &PgConnection) -> Result<PostForm, Error> {
71 let oprops = &page.object_props;
72 let creator_id = Url::parse(&oprops.get_attributed_to_xsd_any_uri().unwrap().to_string())?;
73 let creator = fetch_remote_user(&creator_id, conn)?;
74 let community_id = Url::parse(&oprops.get_to_xsd_any_uri().unwrap().to_string())?;
75 let community = fetch_remote_community(&community_id, conn)?;
78 name: oprops.get_summary_xsd_string().unwrap().to_string(),
79 url: oprops.get_url_xsd_any_uri().map(|u| u.to_string()),
80 body: oprops.get_content_xsd_string().map(|c| c.to_string()),
81 creator_id: creator.id,
82 community_id: community.id,
83 removed: None, // -> Delete activity / tombstone
84 locked: None, // -> commentsEnabled
87 .map(|u| u.as_ref().to_owned().naive_local()),
90 .map(|u| u.as_ref().to_owned().naive_local()),
91 deleted: None, // -> Delete activity / tombstone
92 nsfw: false, // -> sensitive
93 stickied: None, // -> put it in "featured" collection of the community
94 embed_title: None, // -> attachment?
95 embed_description: None,
98 ap_id: oprops.get_id().unwrap().to_string(),