From 81002c75d22bf013e80c0940f6e01c3081246d0c Mon Sep 17 00:00:00 2001 From: Paul <paulmakles@gmail.com> Date: Wed, 28 Apr 2021 17:12:14 +0100 Subject: [PATCH] Only push out status; mark attachments as deleted. --- src/database/entities/autumn.rs | 3 ++ src/database/entities/channel.rs | 54 ++++++++++++++++++++++++++++++-- src/database/entities/message.rs | 20 ++++++++++++ src/routes/users/edit_user.rs | 16 ++++++---- 4 files changed, 85 insertions(+), 8 deletions(-) diff --git a/src/database/entities/autumn.rs b/src/database/entities/autumn.rs index a0ae82f..10eb7c1 100644 --- a/src/database/entities/autumn.rs +++ b/src/database/entities/autumn.rs @@ -19,6 +19,9 @@ pub struct File { metadata: Metadata, content_type: String, size: isize, + + #[serde(skip_serializing_if = "Option::is_none")] + deleted: Option<bool>, #[serde(skip_serializing_if = "Option::is_none")] message_id: Option<String>, diff --git a/src/database/entities/channel.rs b/src/database/entities/channel.rs index 1334616..dce0672 100644 --- a/src/database/entities/channel.rs +++ b/src/database/entities/channel.rs @@ -1,9 +1,10 @@ use crate::database::*; use crate::notifications::events::ClientboundNotification; use crate::util::result::{Error, Result}; -use mongodb::bson::{doc, from_document, to_document}; +use mongodb::{bson::{Document, doc, from_document, to_document}, options::FindOptions}; use rocket_contrib::json::JsonValue; use serde::{Deserialize, Serialize}; +use futures::StreamExt; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct LastMessage { @@ -107,7 +108,56 @@ impl Channel { pub async fn delete(&self) -> Result<()> { let id = self.id(); - get_collection("messages") + let messages = get_collection("messages"); + + // Check if there are any attachments we need to delete. + let message_ids = messages + .find( + doc! { + "channel": id, + "attachment": { + "$exists": 1 + } + }, + FindOptions::builder().projection(doc! { "_id": 1 }).build(), + ) + .await + .map_err(|_| Error::DatabaseError { + operation: "fetch_many", + with: "messages", + })? + .filter_map(async move |s| s.ok()) + .collect::<Vec<Document>>() + .await + .into_iter() + .filter_map(|x| x.get_str("_id").ok().map(|x| x.to_string())) + .collect::<Vec<String>>(); + + // If we found any, mark them as deleted. + if message_ids.len() > 0 { + get_collection("attachments") + .update_many( + doc! { + "message_id": { + "$in": message_ids + } + }, + doc! { + "$set": { + "deleted": true + } + }, + None + ) + .await + .map_err(|_| Error::DatabaseError { + operation: "update_many", + with: "attachments", + })?; + } + + // And then delete said messages. + messages .delete_many( doc! { "channel": id diff --git a/src/database/entities/message.rs b/src/database/entities/message.rs index b506ccc..0ef9f01 100644 --- a/src/database/entities/message.rs +++ b/src/database/entities/message.rs @@ -276,6 +276,26 @@ impl Message { .await .ok(); + if let Some(attachment) = &self.attachment { + get_collection("attachments") + .update_one( + doc! { + "_id": &attachment.id + }, + doc! { + "$set": { + "deleted": true + } + }, + None + ) + .await + .map_err(|_| Error::DatabaseError { + operation: "update_one", + with: "attachment", + })?; + } + Ok(()) } } diff --git a/src/routes/users/edit_user.rs b/src/routes/users/edit_user.rs index b1c1ef9..ab5e1f6 100644 --- a/src/routes/users/edit_user.rs +++ b/src/routes/users/edit_user.rs @@ -10,8 +10,10 @@ use validator::Validate; #[derive(Validate, Serialize, Deserialize)] pub struct Data { #[serde(skip_serializing_if = "Option::is_none")] + #[validate] status: Option<UserStatus>, #[serde(skip_serializing_if = "Option::is_none")] + #[validate] profile: Option<UserProfile>, } @@ -29,13 +31,15 @@ pub async fn req(user: User, data: Json<Data>, _ignore_id: String) -> Result<()> .await .map_err(|_| Error::DatabaseError { operation: "update_one", with: "user" })?; - ClientboundNotification::UserUpdate { - id: user.id.clone(), - data: json!(data.0), + if let Some(status) = data.0.status { + ClientboundNotification::UserUpdate { + id: user.id.clone(), + data: json!({ "status": status }), + } + .publish(user.id.clone()) + .await + .ok(); } - .publish(user.id.clone()) - .await - .ok(); Ok(()) } -- GitLab