Can delete member image

This commit is contained in:
2023-08-07 11:07:24 +02:00
parent c27ed56b8a
commit c6148f6562
14 changed files with 555 additions and 14 deletions

View File

@ -1,6 +1,7 @@
use crate::connections::db_connection;
use crate::models::{FamilyID, Member, MemberID, NewMember};
use crate::schema::members;
use crate::services::photos_service;
use crate::utils::time_utils::time;
use diesel::prelude::*;
use diesel::RunQueryDsl;
@ -85,10 +86,25 @@ pub async fn update(member: &mut Member) -> anyhow::Result<()> {
Ok(())
}
/// Delete a member photo
pub async fn remove_photo(member: &mut Member) -> anyhow::Result<()> {
match member.photo_id() {
None => {}
Some(photo) => {
photos_service::delete(photo).await?;
member.set_photo_id(None);
update(member).await?;
}
}
Ok(())
}
/// Delete a member
pub async fn delete(member: &Member) -> anyhow::Result<()> {
pub async fn delete(member: &mut Member) -> anyhow::Result<()> {
// TODO : remove associated couple
// TODO : remove user photo
remove_photo(member).await?;
// Remove the member
db_connection::execute(|conn| {
@ -101,8 +117,8 @@ pub async fn delete(member: &Member) -> anyhow::Result<()> {
/// Delete all the members of a family
pub async fn delete_all_family(family_id: FamilyID) -> anyhow::Result<()> {
for m in get_all_of_family(family_id).await? {
delete(&m).await?;
for mut m in get_all_of_family(family_id).await? {
delete(&mut m).await?;
}
Ok(())
}

View File

@ -5,5 +5,6 @@ pub mod login_token_service;
pub mod mail_service;
pub mod members_service;
pub mod openid_service;
pub mod photos_service;
pub mod rate_limiter_service;
pub mod users_service;

View File

@ -0,0 +1,92 @@
use crate::connections::{db_connection, s3_connection};
use crate::constants::{ALLOWED_PHOTOS_MIMETYPES, PHOTOS_MAX_SIZE, THUMB_HEIGHT, THUMB_WIDTH};
use crate::models::{NewPhoto, Photo, PhotoID};
use crate::schema::photos;
use crate::utils::crypt_utils::sha512;
use crate::utils::time_utils::time;
use actix_multipart::form::tempfile::TempFile;
use diesel::prelude::*;
use image::imageops::FilterType;
use image::ImageOutputFormat;
use std::io::{Cursor, Read};
use uuid::Uuid;
#[derive(thiserror::Error, Debug)]
enum PhotoServiceError {
#[error("Uploaded file is too large ({0} bytes)!")]
FileToLarge(usize),
#[error("Mime type not specified in request!")]
MissingMimeType,
#[error("Mimetype forbidden ({0})!")]
MimeTypeForbidden(String),
}
/// Finalize upload of a photo
pub async fn finalize_upload(mut file: TempFile) -> anyhow::Result<Photo> {
// Prerequisite checks
if file.size > PHOTOS_MAX_SIZE {
return Err(PhotoServiceError::FileToLarge(file.size).into());
}
let mime_type = file
.content_type
.ok_or(PhotoServiceError::MissingMimeType)?;
if !ALLOWED_PHOTOS_MIMETYPES.contains(&mime_type.as_ref()) {
return Err(PhotoServiceError::MimeTypeForbidden(mime_type.to_string()).into());
}
let mut photo_img = Vec::with_capacity(file.size);
file.file.read_to_end(&mut photo_img)?;
let thumbnail_image = image::load_from_memory(&photo_img)?.resize(
THUMB_WIDTH,
THUMB_HEIGHT,
FilterType::Triangle,
);
let mut thumb_cursor = Cursor::new(vec![]);
thumbnail_image.write_to(&mut thumb_cursor, ImageOutputFormat::Png)?;
let thumb_img = thumb_cursor.into_inner();
let photo = NewPhoto {
file_id: Uuid::new_v4().to_string(),
time_create: time() as i64,
mime_type: mime_type.to_string(),
sha512: sha512(&photo_img),
file_size: photo_img.len() as i32,
thumb_sha512: sha512(&thumb_img),
};
s3_connection::upload_file(&photo.photo_path(), &photo_img).await?;
s3_connection::upload_file(&photo.thumbnail_path(), &thumb_img).await?;
db_connection::execute(|conn| {
let res: Photo = diesel::insert_into(photos::table)
.values(&photo)
.get_result(conn)?;
Ok(res)
})
}
/// Get a photo by its ID
pub async fn get_by_id(id: PhotoID) -> anyhow::Result<Photo> {
db_connection::execute(|conn| photos::table.filter(photos::dsl::id.eq(id.0)).first(conn))
}
/// Delete a photo
pub async fn delete(id: PhotoID) -> anyhow::Result<()> {
let photo = get_by_id(id).await?;
s3_connection::delete_file_if_exists(&photo.photo_path()).await?;
s3_connection::delete_file_if_exists(&photo.thumbnail_path()).await?;
db_connection::execute(|conn| {
diesel::delete(photos::dsl::photos.filter(photos::dsl::id.eq(photo.id().0))).execute(conn)
})?;
Ok(())
}