]> Untitled Git - lemmy.git/blob - lemmy_apub/src/objects/mod.rs
Merge pull request 'Add logging to find bug (ref #1283)' (#146) from debug-1283 into...
[lemmy.git] / lemmy_apub / src / objects / mod.rs
1 use crate::check_is_apub_id_valid;
2 use activitystreams::{
3   base::{AsBase, BaseExt, ExtendsExt},
4   markers::Base,
5   mime::{FromStrError, Mime},
6   object::{ApObjectExt, Object, ObjectExt, Tombstone, TombstoneExt},
7 };
8 use anyhow::{anyhow, Context};
9 use chrono::NaiveDateTime;
10 use lemmy_utils::{location_info, utils::convert_datetime, LemmyError};
11 use url::Url;
12
13 pub(crate) mod comment;
14 pub(crate) mod community;
15 pub(crate) mod post;
16 pub(crate) mod private_message;
17 pub(crate) mod user;
18
19 /// Updated is actually the deletion time
20 fn create_tombstone<T>(
21   deleted: bool,
22   object_id: &str,
23   updated: Option<NaiveDateTime>,
24   former_type: T,
25 ) -> Result<Tombstone, LemmyError>
26 where
27   T: ToString,
28 {
29   if deleted {
30     if let Some(updated) = updated {
31       let mut tombstone = Tombstone::new();
32       tombstone.set_id(object_id.parse()?);
33       tombstone.set_former_type(former_type.to_string());
34       tombstone.set_deleted(convert_datetime(updated));
35       Ok(tombstone)
36     } else {
37       Err(anyhow!("Cant convert to tombstone because updated time was None.").into())
38     }
39   } else {
40     Err(anyhow!("Cant convert object to tombstone if it wasnt deleted").into())
41   }
42 }
43
44 pub(in crate::objects) fn check_object_domain<T, Kind>(
45   apub: &T,
46   expected_domain: Option<Url>,
47 ) -> Result<String, LemmyError>
48 where
49   T: Base + AsBase<Kind>,
50 {
51   let object_id = if let Some(url) = expected_domain {
52     let domain = url.domain().context(location_info!())?;
53     apub.id(domain)?.context(location_info!())?
54   } else {
55     apub.id_unchecked().context(location_info!())?
56   };
57   check_is_apub_id_valid(&object_id)?;
58   Ok(object_id.to_string())
59 }
60
61 pub(in crate::objects) fn set_content_and_source<T, Kind1, Kind2>(
62   object: &mut T,
63   markdown_text: &str,
64 ) -> Result<(), LemmyError>
65 where
66   T: ApObjectExt<Kind1> + ObjectExt<Kind2> + AsBase<Kind2>,
67 {
68   let mut source = Object::<()>::new_none_type();
69   source
70     .set_content(markdown_text)
71     .set_media_type(mime_markdown()?);
72   object.set_source(source.into_any_base()?);
73
74   // set `content` to markdown for compatibility with older Lemmy versions
75   // TODO: change this to HTML in a while
76   object.set_content(markdown_text);
77   object.set_media_type(mime_markdown()?);
78   //object.set_content(markdown_to_html(markdown_text));
79   Ok(())
80 }
81
82 pub(in crate::objects) fn get_source_markdown_value<T, Kind1, Kind2>(
83   object: &T,
84 ) -> Result<Option<String>, LemmyError>
85 where
86   T: ApObjectExt<Kind1> + ObjectExt<Kind2> + AsBase<Kind2>,
87 {
88   let content = object
89     .content()
90     .map(|s| s.as_single_xsd_string())
91     .flatten()
92     .map(|s| s.to_string());
93   if content.is_some() {
94     let source = object.source();
95     // updated lemmy version, read markdown from `source.content`
96     if let Some(source) = source {
97       let source = Object::<()>::from_any_base(source.to_owned())?.context(location_info!())?;
98       check_is_markdown(source.media_type())?;
99       let source_content = source
100         .content()
101         .map(|s| s.as_single_xsd_string())
102         .flatten()
103         .context(location_info!())?
104         .to_string();
105       return Ok(Some(source_content));
106     }
107     // older lemmy version, read markdown from `content`
108     // TODO: remove this after a while
109     else {
110       return Ok(content);
111     }
112   }
113   Ok(None)
114 }
115
116 pub(in crate::objects) fn mime_markdown() -> Result<Mime, FromStrError> {
117   "text/markdown".parse()
118 }
119
120 pub(in crate::objects) fn check_is_markdown(mime: Option<&Mime>) -> Result<(), LemmyError> {
121   let mime = mime.context(location_info!())?;
122   if !mime.eq(&mime_markdown()?) {
123     Err(LemmyError::from(anyhow!(
124       "Lemmy only supports markdown content"
125     )))
126   } else {
127     Ok(())
128   }
129 }