]> Untitled Git - lemmy.git/blob - crates/apub/src/fetcher/post_or_comment.rs
Make functions work with both connection and pool (#3420)
[lemmy.git] / crates / apub / src / fetcher / post_or_comment.rs
1 use crate::{
2   objects::{comment::ApubComment, community::ApubCommunity, post::ApubPost},
3   protocol::{
4     objects::{note::Note, page::Page},
5     InCommunity,
6   },
7 };
8 use activitypub_federation::{config::Data, traits::Object};
9 use chrono::NaiveDateTime;
10 use lemmy_api_common::context::LemmyContext;
11 use lemmy_db_schema::{
12   source::{community::Community, post::Post},
13   traits::Crud,
14 };
15 use lemmy_utils::error::LemmyError;
16 use serde::Deserialize;
17 use url::Url;
18
19 #[derive(Clone, Debug)]
20 pub enum PostOrComment {
21   Post(ApubPost),
22   Comment(ApubComment),
23 }
24
25 #[derive(Deserialize)]
26 #[serde(untagged)]
27 pub enum PageOrNote {
28   Page(Box<Page>),
29   Note(Note),
30 }
31
32 #[async_trait::async_trait]
33 impl Object for PostOrComment {
34   type DataType = LemmyContext;
35   type Kind = PageOrNote;
36   type Error = LemmyError;
37
38   fn last_refreshed_at(&self) -> Option<NaiveDateTime> {
39     None
40   }
41
42   #[tracing::instrument(skip_all)]
43   async fn read_from_id(
44     object_id: Url,
45     data: &Data<Self::DataType>,
46   ) -> Result<Option<Self>, LemmyError> {
47     let post = ApubPost::read_from_id(object_id.clone(), data).await?;
48     Ok(match post {
49       Some(o) => Some(PostOrComment::Post(o)),
50       None => ApubComment::read_from_id(object_id, data)
51         .await?
52         .map(PostOrComment::Comment),
53     })
54   }
55
56   #[tracing::instrument(skip_all)]
57   async fn delete(self, data: &Data<Self::DataType>) -> Result<(), LemmyError> {
58     match self {
59       PostOrComment::Post(p) => p.delete(data).await,
60       PostOrComment::Comment(c) => c.delete(data).await,
61     }
62   }
63
64   async fn into_json(self, _data: &Data<Self::DataType>) -> Result<Self::Kind, LemmyError> {
65     unimplemented!()
66   }
67
68   #[tracing::instrument(skip_all)]
69   async fn verify(
70     apub: &Self::Kind,
71     expected_domain: &Url,
72     data: &Data<Self::DataType>,
73   ) -> Result<(), LemmyError> {
74     match apub {
75       PageOrNote::Page(a) => ApubPost::verify(a, expected_domain, data).await,
76       PageOrNote::Note(a) => ApubComment::verify(a, expected_domain, data).await,
77     }
78   }
79
80   #[tracing::instrument(skip_all)]
81   async fn from_json(apub: PageOrNote, context: &Data<LemmyContext>) -> Result<Self, LemmyError> {
82     Ok(match apub {
83       PageOrNote::Page(p) => PostOrComment::Post(ApubPost::from_json(*p, context).await?),
84       PageOrNote::Note(n) => PostOrComment::Comment(ApubComment::from_json(n, context).await?),
85     })
86   }
87 }
88
89 #[async_trait::async_trait]
90 impl InCommunity for PostOrComment {
91   async fn community(&self, context: &Data<LemmyContext>) -> Result<ApubCommunity, LemmyError> {
92     let cid = match self {
93       PostOrComment::Post(p) => p.community_id,
94       PostOrComment::Comment(c) => {
95         Post::read(&mut context.pool(), c.post_id)
96           .await?
97           .community_id
98       }
99     };
100     Ok(Community::read(&mut context.pool(), cid).await?.into())
101   }
102 }