]> Untitled Git - lemmy.git/blob - crates/apub/src/fetcher/post_or_comment.rs
Rewrite fetcher (#1792)
[lemmy.git] / crates / apub / src / fetcher / post_or_comment.rs
1 use crate::objects::{comment::Note, post::Page, FromApub};
2 use activitystreams::chrono::NaiveDateTime;
3 use diesel::{result::Error, PgConnection};
4 use lemmy_db_queries::ApubObject;
5 use lemmy_db_schema::{
6   source::{
7     comment::{Comment, CommentForm},
8     post::{Post, PostForm},
9   },
10   DbUrl,
11 };
12 use lemmy_utils::LemmyError;
13 use lemmy_websocket::LemmyContext;
14 use serde::Deserialize;
15 use url::Url;
16
17 #[derive(Clone, Debug)]
18 pub enum PostOrComment {
19   Comment(Box<Comment>),
20   Post(Box<Post>),
21 }
22
23 pub enum PostOrCommentForm {
24   PostForm(PostForm),
25   CommentForm(CommentForm),
26 }
27
28 #[derive(Deserialize)]
29 pub enum PageOrNote {
30   Page(Page),
31   Note(Note),
32 }
33
34 #[async_trait::async_trait(?Send)]
35 impl ApubObject for PostOrComment {
36   fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
37     None
38   }
39
40   // TODO: this can probably be implemented using a single sql query
41   fn read_from_apub_id(conn: &PgConnection, object_id: &DbUrl) -> Result<Self, Error>
42   where
43     Self: Sized,
44   {
45     let post = Post::read_from_apub_id(conn, object_id);
46     Ok(match post {
47       Ok(o) => PostOrComment::Post(Box::new(o)),
48       Err(_) => PostOrComment::Comment(Box::new(Comment::read_from_apub_id(conn, object_id)?)),
49     })
50   }
51 }
52
53 #[async_trait::async_trait(?Send)]
54 impl FromApub for PostOrComment {
55   type ApubType = PageOrNote;
56
57   async fn from_apub(
58     apub: &PageOrNote,
59     context: &LemmyContext,
60     expected_domain: &Url,
61     request_counter: &mut i32,
62   ) -> Result<Self, LemmyError>
63   where
64     Self: Sized,
65   {
66     Ok(match apub {
67       PageOrNote::Page(p) => PostOrComment::Post(Box::new(
68         Post::from_apub(p, context, expected_domain, request_counter).await?,
69       )),
70       PageOrNote::Note(n) => PostOrComment::Comment(Box::new(
71         Comment::from_apub(n, context, expected_domain, request_counter).await?,
72       )),
73     })
74   }
75 }
76
77 impl PostOrComment {
78   pub(crate) fn ap_id(&self) -> Url {
79     match self {
80       PostOrComment::Post(p) => p.ap_id.clone(),
81       PostOrComment::Comment(c) => c.ap_id.clone(),
82     }
83     .into()
84   }
85 }