summaryrefslogtreecommitdiffstats
path: root/server/src/apub/post.rs
blob: 2db5d8ec0dcd4994b1b5f0e803523c27b481d464 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use crate::apub::puller::fetch_remote_user;
use crate::apub::{create_apub_response, make_apub_endpoint, EndpointType};
use crate::convert_datetime;
use crate::db::post::{Post, PostForm};
use crate::db::user::User_;
use crate::db::Crud;
use activitystreams::{context, object::properties::ObjectProperties, object::Page};
use actix_web::body::Body;
use actix_web::web::Path;
use actix_web::{web, HttpResponse};
use diesel::r2d2::{ConnectionManager, Pool};
use diesel::PgConnection;
use failure::Error;
use serde::Deserialize;

#[derive(Deserialize)]
pub struct PostQuery {
  post_id: String,
}

pub async fn get_apub_post(
  info: Path<PostQuery>,
  db: web::Data<Pool<ConnectionManager<PgConnection>>>,
) -> Result<HttpResponse<Body>, Error> {
  let id = info.post_id.parse::<i32>()?;
  let post = Post::read(&&db.get()?, id)?;
  Ok(create_apub_response(&post.as_page(&db.get().unwrap())?))
}

impl Post {
  pub fn as_page(&self, conn: &PgConnection) -> Result<Page, Error> {
    let base_url = make_apub_endpoint(EndpointType::Post, &self.id.to_string());
    let mut page = Page::default();
    let oprops: &mut ObjectProperties = page.as_mut();
    let creator = User_::read(conn, self.creator_id)?;

    oprops
      // Not needed when the Post is embedded in a collection (like for community outbox)
      .set_context_xsd_any_uri(context())?
      .set_id(base_url)?
      .set_name_xsd_string(self.name.to_owned())?
      .set_published(convert_datetime(self.published))?
      .set_attributed_to_xsd_any_uri(make_apub_endpoint(EndpointType::User, &creator.name))?;

    if let Some(body) = &self.body {
      oprops.set_content_xsd_string(body.to_owned())?;
    }

    // TODO: hacky code because we get self.url == Some("")
    // https://github.com/dessalines/lemmy/issues/602
    let url = self.url.as_ref().filter(|u| !u.is_empty());
    if let Some(u) = url {
      oprops.set_url_xsd_any_uri(u.to_owned())?;
    }

    if let Some(u) = self.updated {
      oprops.set_updated(convert_datetime(u))?;
    }

    Ok(page)
  }
}

impl PostForm {
  pub fn from_page(page: &Page, conn: &PgConnection) -> Result<PostForm, Error> {
    let oprops = &page.object_props;
    let creator = fetch_remote_user(
      &oprops.get_attributed_to_xsd_any_uri().unwrap().to_string(),
      conn,
    )?;
    Ok(PostForm {
      name: oprops.get_name_xsd_string().unwrap().to_string(),
      url: oprops.get_url_xsd_any_uri().map(|u| u.to_string()),
      body: oprops.get_content_xsd_string().map(|c| c.to_string()),
      creator_id: creator.id,
      community_id: -1,
      removed: None,
      locked: None,
      published: oprops
        .get_published()
        .map(|u| u.as_ref().to_owned().naive_local()),
      updated: oprops
        .get_updated()
        .map(|u| u.as_ref().to_owned().naive_local()),
      deleted: None,
      nsfw: false,
      stickied: None,
      embed_title: None,
      embed_description: None,
      embed_html: None,
      thumbnail_url: None,
      ap_id: oprops.get_id().unwrap().to_string(),
      local: false,
    })
  }
}