diff --git a/Cargo.lock b/Cargo.lock index b38ecb7..3ae89f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -549,6 +549,7 @@ dependencies = [ "kamadak-exif", "lazy_static", "mailchecker", + "mime_guess", "mysql", "percent-encoding", "rand", @@ -1283,6 +1284,16 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "mime_guess" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "miniz_oxide" version = "0.3.6" @@ -2176,6 +2187,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.4" @@ -2229,6 +2249,12 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" + [[package]] name = "void" version = "1.0.2" diff --git a/Cargo.toml b/Cargo.toml index f2d0f9b..948afcf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,4 +24,5 @@ chrono = "0.4.11" bytes = "0.5.4" image = "0.23.5" kamadak-exif = "0.5.1" -lazy_static = "1.4.0" \ No newline at end of file +lazy_static = "1.4.0" +mime_guess = "2.0.3" \ No newline at end of file diff --git a/src/constants.rs b/src/constants.rs index 155e900..03a16c0 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -66,5 +66,8 @@ pub const PATH_GROUPS_LOGOS: &str = "groups_logo"; /// The group logo to use when no custom logo have been uploaded pub const DEFAULT_GROUP_LOGO: &str = "groups_logo/default.png"; +/// The path where image associated with posts should be stored +pub const PATH_POST_IMAGES: &str ="imgpost"; + /// Maximum requests size (50 Mo) pub const MAX_REQUEST_SIZE: usize = 50000000; \ No newline at end of file diff --git a/src/controllers/posts_controller.rs b/src/controllers/posts_controller.rs index 6a237cc..14d931d 100644 --- a/src/controllers/posts_controller.rs +++ b/src/controllers/posts_controller.rs @@ -4,14 +4,30 @@ use crate::api_data::post_api::PostAPI; use crate::api_data::res_create_post::ResCreatePost; +use crate::constants::PATH_POST_IMAGES; use crate::controllers::routes::RequestResult; -use crate::data::error::ExecError; +use crate::data::error::{ExecError, ResultBoxError}; use crate::data::group::GroupAccessLevel; use crate::data::http_request_handler::HttpRequestHandler; -use crate::data::post::{Post, PostAccessLevel, PostKind, PostPageKind, PostVisibilityLevel}; +use crate::data::post::{Post, PostAccessLevel, PostFile, PostKind, PostPageKind, PostVisibilityLevel}; use crate::helpers::{groups_helper, posts_helper, user_helper}; use crate::utils::date_utils::time; use crate::utils::string_utils::check_string_before_insert; +use crate::utils::user_data_utils::user_data_path; + +impl PostFile { + /// Initialize a `PostFile` instance based on a file that have just been created + pub fn new_from_created_file(path: &str) -> ResultBoxError { + let data = std::fs::metadata(user_data_path(path.as_ref()))?; + Ok(PostFile { + path: path.to_string(), + size: data.len() as usize, + file_type: mime_guess::from_path(path) + .first() + .map(|m| format!("{}/{}", m.type_(), m.subtype())), + }) + } +} /// Get the list of posts of a user pub fn get_list_user(r: &mut HttpRequestHandler) -> RequestResult { @@ -113,6 +129,18 @@ pub fn create_post(r: &mut HttpRequestHandler) -> RequestResult { PostKind::POST_KIND_TEXT } + + // Image post + "image" => { + if !r.has_file("image") { + r.bad_request("An error occured while receiving the image!".to_string())?; + } + + let path = r.save_post_image("image", PATH_POST_IMAGES, 2000, 2000)?; + + PostKind::POST_KIND_IMAGE(PostFile::new_from_created_file(&path)?) + } + _ => { r.internal_error(ExecError::boxed_new("Unsupported kind of post!"))?; unreachable!(); diff --git a/src/helpers/database.rs b/src/helpers/database.rs index 26fbf2d..d3ecca5 100644 --- a/src/helpers/database.rs +++ b/src/helpers/database.rs @@ -555,6 +555,11 @@ impl InsertQuery { self } + pub fn add_usize(mut self, key: &str, value: usize) -> InsertQuery { + self.values.insert(key.to_string(), Value::from(value)); + self + } + pub fn add_u32(mut self, key: &str, value: u32) -> InsertQuery { self.values.insert(key.to_string(), Value::from(value)); self diff --git a/src/helpers/posts_helper.rs b/src/helpers/posts_helper.rs index 6743a09..3a74bdd 100644 --- a/src/helpers/posts_helper.rs +++ b/src/helpers/posts_helper.rs @@ -64,7 +64,7 @@ pub fn create(p: &Post) -> ResultBoxError { }; // Start insert query - let insert_query = database::InsertQuery::new(POSTS_TABLE) + let mut insert_query = database::InsertQuery::new(POSTS_TABLE) .add_user_id("ID_personne", user_id) .add_u64("ID_amis", friend_id.map(|f| f.id()).unwrap_or(0)) .add_u64("group_id", group_id.map(|f| f.id()).unwrap_or(0)) @@ -74,6 +74,26 @@ pub fn create(p: &Post) -> ResultBoxError { .add_str("type", &p.kind.to_db()) .add_opt_str("texte", p.content.as_ref()); + match &p.kind { + PostKind::POST_KIND_TEXT => {/* nothing to do */}, + + // Posts with associated file + POST_KIND_IMAGE(file) | POST_KIND_PDF(file) => { + insert_query = insert_query.add_str("path", &file.path) + .add_usize("size", file.size) + .add_opt_str("file_type", file.file_type.as_ref()); + } + + + _ => unimplemented!() + /* + POST_KIND_WEBLINK(_) => {}, + POST_KIND_MOVIE(_) => {}, + POST_KIND_COUNTDOWN(_) => {}, + POST_KIND_SURVEY => {}, + POST_KIND_YOUTUBE(_) => {},*/ + } + // Execute insertion let post_id = insert_query.insert()? .ok_or(ExecError::new("Insert post query did not return a result!"))?;