mirror of
https://gitlab.com/comunic/comunicapiv3
synced 2024-11-29 16:56:28 +00:00
Start to push notifications
This commit is contained in:
parent
0e80564f85
commit
4d6ff8fef3
@ -8,8 +8,9 @@ use crate::constants::PATH_COMMENTS_IMAGES;
|
|||||||
use crate::controllers::routes::RequestResult;
|
use crate::controllers::routes::RequestResult;
|
||||||
use crate::data::comment::Comment;
|
use crate::data::comment::Comment;
|
||||||
use crate::data::http_request_handler::HttpRequestHandler;
|
use crate::data::http_request_handler::HttpRequestHandler;
|
||||||
|
use crate::data::notification::NotifEventType;
|
||||||
use crate::data::post::PostAccessLevel;
|
use crate::data::post::PostAccessLevel;
|
||||||
use crate::helpers::{comments_helper, posts_helper};
|
use crate::helpers::{comments_helper, notifications_helper, posts_helper};
|
||||||
use crate::utils::date_utils::time;
|
use crate::utils::date_utils::time;
|
||||||
use crate::utils::string_utils::remove_html_nodes;
|
use crate::utils::string_utils::remove_html_nodes;
|
||||||
|
|
||||||
@ -45,7 +46,9 @@ pub fn create(r: &mut HttpRequestHandler) -> RequestResult {
|
|||||||
|
|
||||||
let comment_id = comments_helper::create(&comment)?;
|
let comment_id = comments_helper::create(&comment)?;
|
||||||
|
|
||||||
// TODO : Create notifications
|
// Create notifications
|
||||||
|
notifications_helper::create_post_notification(&r.user_id()?, post.id, NotifEventType::COMMENT_CREATED)?;
|
||||||
|
|
||||||
// TODO : Remove notifications targeting current user about the post
|
// TODO : Remove notifications targeting current user about the post
|
||||||
|
|
||||||
r.set_response(ResCreateComment::new(comment_id))
|
r.set_response(ResCreateComment::new(comment_id))
|
||||||
|
@ -211,6 +211,11 @@ impl PartialNotification {
|
|||||||
self.id.is_some()
|
self.id.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_time_create(mut self, time: u64) -> PartialNotification {
|
||||||
|
self.time_create = Some(time);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_dest_user_id(mut self, id: &UserID) -> PartialNotification {
|
pub fn set_dest_user_id(mut self, id: &UserID) -> PartialNotification {
|
||||||
self.dest_user_id = Some(id.clone());
|
self.dest_user_id = Some(id.clone());
|
||||||
self
|
self
|
||||||
@ -230,4 +235,9 @@ impl PartialNotification {
|
|||||||
self.on_elem_type = Some(t);
|
self.on_elem_type = Some(t);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_type(mut self, t: NotifEventType) -> PartialNotification {
|
||||||
|
self.kind = Some(t);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
@ -153,6 +153,11 @@ impl Post {
|
|||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check out whether a post is targeting a group page or not
|
||||||
|
pub fn is_on_group_page(&self) -> bool {
|
||||||
|
matches!(self.target_page, PostPageKind::PAGE_KIND_GROUP(_))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -552,6 +552,13 @@ impl InsertQuery {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add batch values
|
||||||
|
pub fn add_values(mut self, values: HashMap<String, mysql::Value>) -> Self {
|
||||||
|
self.values.extend(values.into_iter());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Add a string
|
/// Add a string
|
||||||
pub fn add_str(mut self, key: &str, value: &str) -> InsertQuery {
|
pub fn add_str(mut self, key: &str, value: &str) -> InsertQuery {
|
||||||
self.values.insert(key.to_string(), Value::from(value));
|
self.values.insert(key.to_string(), Value::from(value));
|
||||||
|
@ -16,8 +16,10 @@ use crate::helpers::database::QueryInfo;
|
|||||||
pub struct GetFriendsQuery {
|
pub struct GetFriendsQuery {
|
||||||
only_accepted: bool,
|
only_accepted: bool,
|
||||||
only_following: bool,
|
only_following: bool,
|
||||||
|
only_followers: bool,
|
||||||
target_user: UserID,
|
target_user: UserID,
|
||||||
friend_id: Option<UserID>,
|
friend_id: Option<UserID>,
|
||||||
|
common_with_user: Option<UserID>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetFriendsQuery {
|
impl GetFriendsQuery {
|
||||||
@ -26,8 +28,10 @@ impl GetFriendsQuery {
|
|||||||
GetFriendsQuery {
|
GetFriendsQuery {
|
||||||
only_accepted: false,
|
only_accepted: false,
|
||||||
only_following: false,
|
only_following: false,
|
||||||
|
only_followers: false,
|
||||||
target_user: target_user.clone(),
|
target_user: target_user.clone(),
|
||||||
friend_id: None,
|
friend_id: None,
|
||||||
|
common_with_user: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,11 +40,24 @@ impl GetFriendsQuery {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Specify whether only the friends followed by friend_id should be selected
|
||||||
pub fn set_only_following(mut self, following: bool) -> GetFriendsQuery {
|
pub fn set_only_following(mut self, following: bool) -> GetFriendsQuery {
|
||||||
self.only_following = following;
|
self.only_following = following;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Specify whether only the friends following friend_id should be selected
|
||||||
|
pub fn set_only_followers(mut self, following: bool) -> GetFriendsQuery {
|
||||||
|
self.only_followers = following;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Specify whether all the returned friends should be common with a specified user
|
||||||
|
pub fn set_only_common_with(mut self, user: &UserID) -> GetFriendsQuery {
|
||||||
|
self.common_with_user = Some(user.clone());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the list of friends
|
/// Get the list of friends
|
||||||
pub fn exec(self) -> ResultBoxError<Vec<Friend>> {
|
pub fn exec(self) -> ResultBoxError<Vec<Friend>> {
|
||||||
get_list(&self)
|
get_list(&self)
|
||||||
@ -80,6 +97,26 @@ fn get_list(friend_query: &GetFriendsQuery) -> ResultBoxError<Vec<Friend>> {
|
|||||||
query = query.cond_legacy_bool("f.abonnement", true);
|
query = query.cond_legacy_bool("f.abonnement", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut custom_where = String::new();
|
||||||
|
|
||||||
|
if friend_query.only_followers {
|
||||||
|
custom_where = " EXISTS (SELECT * FROM amis d WHERE d.ID_personne = f.ID_amis AND d.ID_amis = f.ID_personne AND abonnement = 1) ".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(user_id) = &friend_query.common_with_user {
|
||||||
|
if !custom_where.is_empty() {
|
||||||
|
custom_where.push_str(" AND ");
|
||||||
|
}
|
||||||
|
|
||||||
|
custom_where.push_str(" (f.ID_amis = ? OR EXISTS (SELECT * FROM amis d WHERE d.ID_personne = ? AND d.ID_amis = f.ID_amis AND actif = 1) ) ");
|
||||||
|
query = query.add_custom_where_argument_user_id(user_id);
|
||||||
|
query = query.add_custom_where_argument_user_id(user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !custom_where.is_empty() {
|
||||||
|
query = query.set_custom_where(&custom_where);
|
||||||
|
}
|
||||||
|
|
||||||
query.exec(db_to_friend)
|
query.exec(db_to_friend)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,6 +313,15 @@ pub fn get_access_level(group_id: &GroupID, user_id: Option<UserID>) -> ResultBo
|
|||||||
Ok(GroupAccessLevel::NO_ACCESS)
|
Ok(GroupAccessLevel::NO_ACCESS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the list of follower of a given group
|
||||||
|
pub fn get_list_followers(group_id: &GroupID) -> ResultBoxError<Vec<UserID>> {
|
||||||
|
database::QueryInfo::new(GROUPS_MEMBERS_TABLE)
|
||||||
|
.cond_group_id("groups_id", group_id)
|
||||||
|
.cond_legacy_bool("following", true)
|
||||||
|
.add_field("user_id")
|
||||||
|
.exec(|r| r.get_user_id("user_id"))
|
||||||
|
}
|
||||||
|
|
||||||
/// Count the number of members of a group
|
/// Count the number of members of a group
|
||||||
pub fn count_members(group_id: &GroupID) -> ResultBoxError<usize> {
|
pub fn count_members(group_id: &GroupID) -> ResultBoxError<usize> {
|
||||||
database::QueryInfo::new(GROUPS_MEMBERS_TABLE)
|
database::QueryInfo::new(GROUPS_MEMBERS_TABLE)
|
||||||
|
@ -8,8 +8,147 @@ use crate::constants::database_tables_names::NOTIFICATIONS_TABLE;
|
|||||||
use crate::data::error::ResultBoxError;
|
use crate::data::error::ResultBoxError;
|
||||||
use crate::data::group_id::GroupID;
|
use crate::data::group_id::GroupID;
|
||||||
use crate::data::notification::{NotifElemType, NotifEventType, NotifEventVisibility, Notification, PartialNotification};
|
use crate::data::notification::{NotifElemType, NotifEventType, NotifEventVisibility, Notification, PartialNotification};
|
||||||
|
use crate::data::post::{PostPageKind, PostVisibilityLevel};
|
||||||
use crate::data::user::UserID;
|
use crate::data::user::UserID;
|
||||||
use crate::helpers::database;
|
use crate::helpers::{database, groups_helper, posts_helper};
|
||||||
|
use crate::helpers::friends_helper::GetFriendsQuery;
|
||||||
|
use crate::utils::date_utils;
|
||||||
|
|
||||||
|
/// Create post notification
|
||||||
|
pub fn create_post_notification(from_user: &UserID, post_id: u64, action: NotifEventType) -> ResultBoxError {
|
||||||
|
let mut n = PartialNotification::new()
|
||||||
|
.set_time_create(date_utils::time())
|
||||||
|
.set_from_user_id(from_user)
|
||||||
|
.set_on_elem_id(post_id)
|
||||||
|
.set_on_elem_type(NotifElemType::POST)
|
||||||
|
.set_type(action);
|
||||||
|
|
||||||
|
push(&mut n)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Push a new notification
|
||||||
|
pub fn push(n: &mut PartialNotification) -> ResultBoxError
|
||||||
|
{
|
||||||
|
if n.time_create.is_none()
|
||||||
|
{
|
||||||
|
n.time_create = Some(date_utils::time());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the visibility level of the notification
|
||||||
|
if matches!(n.on_elem_type, Some(NotifElemType::POST)) {
|
||||||
|
let post = posts_helper::get_single(n.on_elem_id.unwrap())?;
|
||||||
|
|
||||||
|
// Determine post container
|
||||||
|
match &post.target_page {
|
||||||
|
PostPageKind::PAGE_KIND_USER(user_id) => {
|
||||||
|
n.container_type = Some(NotifElemType::USER_PAGE);
|
||||||
|
n.container_id = Some(user_id.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
PostPageKind::PAGE_KIND_GROUP(group_id) => {
|
||||||
|
n.container_type = Some(NotifElemType::GROUP_PAGE);
|
||||||
|
n.container_id = Some(group_id.id());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check the scope of the notification
|
||||||
|
// Private post (on user page)
|
||||||
|
if matches!(post.visibility, PostVisibilityLevel::VISIBILITY_USER) {
|
||||||
|
// Check if the post belongs to current user => no notification needed
|
||||||
|
if &post.user_id == post.user_page_id().unwrap() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the person who posted that is not the owner of the page
|
||||||
|
if post.user_page_id().unwrap() != n.from_user_id.as_ref().unwrap() {
|
||||||
|
n.dest_user_id = Some(post.user_page_id().unwrap().clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the user is the owner of the page, but the post does not belongs to him
|
||||||
|
else {
|
||||||
|
n.dest_user_id = Some(post.user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return push_private(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Posts on user page
|
||||||
|
else if post.is_on_user_page() {
|
||||||
|
let mut friend_req = GetFriendsQuery::new(n.from_user_id.as_ref().unwrap())
|
||||||
|
.set_only_followers(true);
|
||||||
|
|
||||||
|
// If the person who created the notification is not on his page
|
||||||
|
if n.from_user_id.as_ref().unwrap() != post.user_page_id().unwrap() {
|
||||||
|
friend_req = friend_req.set_only_common_with(post.user_page_id().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
let friends: Vec<UserID> = friend_req
|
||||||
|
.exec()?
|
||||||
|
.into_iter()
|
||||||
|
.map(|f| f.friend_id)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
return push_public(n, friends);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Posts on group pages
|
||||||
|
else if post.is_on_group_page() {
|
||||||
|
return push_group_members(n, post.group_id().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unsupported scenario
|
||||||
|
else {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Push a notification to group members
|
||||||
|
pub fn push_group_members(n: &mut PartialNotification, group_id: &GroupID) -> ResultBoxError {
|
||||||
|
let mut list = groups_helper::get_list_followers(group_id)?;
|
||||||
|
list = list.into_iter().filter(|f| f != n.from_user_id.as_ref().unwrap()).collect();
|
||||||
|
push_public(n, list)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Push a public notification
|
||||||
|
fn push_public(n: &mut PartialNotification, users: Vec<UserID>) -> ResultBoxError {
|
||||||
|
n.visibility = Some(NotifEventVisibility::EVENT_PUBLIC);
|
||||||
|
|
||||||
|
for user_id in users {
|
||||||
|
n.dest_user_id = Some(user_id);
|
||||||
|
|
||||||
|
if !similar_exists(n)? {
|
||||||
|
create(n)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Push a private notification (to 1 user)
|
||||||
|
fn push_private(n: &mut PartialNotification) -> ResultBoxError {
|
||||||
|
n.visibility = Some(NotifEventVisibility::EVENT_PRIVATE);
|
||||||
|
|
||||||
|
if !similar_exists(n)? {
|
||||||
|
create(n)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new notification
|
||||||
|
fn create(n: &PartialNotification) -> ResultBoxError {
|
||||||
|
database::InsertQuery::new(NOTIFICATIONS_TABLE)
|
||||||
|
.add_values(notif_to_db(n, true))
|
||||||
|
.insert_drop_result()?;
|
||||||
|
|
||||||
|
// TODO : WebSocket : trigger notify system
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Delete notifications
|
/// Delete notifications
|
||||||
pub fn delete(notification: &PartialNotification) -> ResultBoxError {
|
pub fn delete(notification: &PartialNotification) -> ResultBoxError {
|
||||||
|
Loading…
Reference in New Issue
Block a user