]> Untitled Git - lemmy.git/blob - lemmy_structs/src/lib.rs
remove timing files added by accident
[lemmy.git] / lemmy_structs / src / lib.rs
1 pub mod comment;
2 pub mod community;
3 pub mod post;
4 pub mod site;
5 pub mod user;
6 pub mod websocket;
7
8 use diesel::PgConnection;
9 use lemmy_db::{source::user::User, Crud, DbPool};
10 use lemmy_db_schema::source::{
11   comment::Comment,
12   post::Post,
13   user::User_,
14   user_mention::{UserMention, UserMentionForm},
15 };
16 use lemmy_utils::{email::send_email, settings::Settings, utils::MentionData, LemmyError};
17 use log::error;
18 use serde::{Deserialize, Serialize};
19
20 #[derive(Serialize, Deserialize, Debug)]
21 pub struct WebFingerLink {
22   pub rel: Option<String>,
23   #[serde(rename(serialize = "type", deserialize = "type"))]
24   pub type_: Option<String>,
25   pub href: Option<String>,
26   #[serde(skip_serializing_if = "Option::is_none")]
27   pub template: Option<String>,
28 }
29
30 #[derive(Serialize, Deserialize, Debug)]
31 pub struct WebFingerResponse {
32   pub subject: String,
33   pub aliases: Vec<String>,
34   pub links: Vec<WebFingerLink>,
35 }
36
37 pub async fn blocking<F, T>(pool: &DbPool, f: F) -> Result<T, LemmyError>
38 where
39   F: FnOnce(&diesel::PgConnection) -> T + Send + 'static,
40   T: Send + 'static,
41 {
42   let pool = pool.clone();
43   let res = actix_web::web::block(move || {
44     let conn = pool.get()?;
45     let res = (f)(&conn);
46     Ok(res) as Result<_, LemmyError>
47   })
48   .await?;
49
50   Ok(res)
51 }
52
53 pub async fn send_local_notifs(
54   mentions: Vec<MentionData>,
55   comment: Comment,
56   user: &User_,
57   post: Post,
58   pool: &DbPool,
59   do_send_email: bool,
60 ) -> Result<Vec<i32>, LemmyError> {
61   let user2 = user.clone();
62   let ids = blocking(pool, move |conn| {
63     do_send_local_notifs(conn, &mentions, &comment, &user2, &post, do_send_email)
64   })
65   .await?;
66
67   Ok(ids)
68 }
69
70 fn do_send_local_notifs(
71   conn: &PgConnection,
72   mentions: &[MentionData],
73   comment: &Comment,
74   user: &User_,
75   post: &Post,
76   do_send_email: bool,
77 ) -> Vec<i32> {
78   let mut recipient_ids = Vec::new();
79
80   // Send the local mentions
81   for mention in mentions
82     .iter()
83     .filter(|m| m.is_local() && m.name.ne(&user.name))
84     .collect::<Vec<&MentionData>>()
85   {
86     if let Ok(mention_user) = User_::read_from_name(&conn, &mention.name) {
87       // TODO
88       // At some point, make it so you can't tag the parent creator either
89       // This can cause two notifications, one for reply and the other for mention
90       recipient_ids.push(mention_user.id);
91
92       let user_mention_form = UserMentionForm {
93         recipient_id: mention_user.id,
94         comment_id: comment.id,
95         read: None,
96       };
97
98       // Allow this to fail softly, since comment edits might re-update or replace it
99       // Let the uniqueness handle this fail
100       let _ = UserMention::create(&conn, &user_mention_form);
101
102       // Send an email to those users that have notifications on
103       if do_send_email && mention_user.send_notifications_to_email {
104         send_email_to_user(
105           mention_user,
106           "Mentioned by",
107           "User Mention",
108           &comment.content,
109         )
110       }
111     }
112   }
113
114   // Send notifs to the parent commenter / poster
115   match comment.parent_id {
116     Some(parent_id) => {
117       if let Ok(parent_comment) = Comment::read(&conn, parent_id) {
118         if parent_comment.creator_id != user.id {
119           if let Ok(parent_user) = User_::read(&conn, parent_comment.creator_id) {
120             recipient_ids.push(parent_user.id);
121
122             if do_send_email && parent_user.send_notifications_to_email {
123               send_email_to_user(parent_user, "Reply from", "Comment Reply", &comment.content)
124             }
125           }
126         }
127       }
128     }
129     // Its a post
130     None => {
131       if post.creator_id != user.id {
132         if let Ok(parent_user) = User_::read(&conn, post.creator_id) {
133           recipient_ids.push(parent_user.id);
134
135           if do_send_email && parent_user.send_notifications_to_email {
136             send_email_to_user(parent_user, "Reply from", "Post Reply", &comment.content)
137           }
138         }
139       }
140     }
141   };
142   recipient_ids
143 }
144
145 pub fn send_email_to_user(user: User_, subject_text: &str, body_text: &str, comment_content: &str) {
146   if user.banned {
147     return;
148   }
149
150   if let Some(user_email) = user.email {
151     let subject = &format!(
152       "{} - {} {}",
153       subject_text,
154       Settings::get().hostname,
155       user.name,
156     );
157     let html = &format!(
158       "<h1>{}</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
159       body_text,
160       user.name,
161       comment_content,
162       Settings::get().get_protocol_and_hostname()
163     );
164     match send_email(subject, &user_email, &user.name, html) {
165       Ok(_o) => _o,
166       Err(e) => error!("{}", e),
167     };
168   }
169 }