From 24469101bcba486e95169a022e88f411bce6e636 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 8 Jul 2020 17:14:55 +0200 Subject: [PATCH] Can create PDF posts --- Cargo.lock | 299 ++++++++++++++++++++++++---- Cargo.toml | 3 +- src/constants.rs | 5 +- src/controllers/posts_controller.rs | 12 +- src/data/http_request_handler.rs | 23 +++ src/utils/mod.rs | 3 +- src/utils/pdf_utils.rs | 22 ++ 7 files changed, 326 insertions(+), 41 deletions(-) create mode 100644 src/utils/pdf_utils.rs diff --git a/Cargo.lock b/Cargo.lock index 3ae89f5..e50f734 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -87,8 +87,8 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a60f9ba7c4e6df97f3aacb14bb5c0cd7d98a49dcbaed0d7f292912ad9a6a3ed2" dependencies = [ - "quote", - "syn", + "quote 1.0.6", + "syn 1.0.22", ] [[package]] @@ -274,8 +274,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f00371942083469785f7e28c540164af1913ee7c96a4534acb9cea92c39f057" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.6", + "syn 1.0.22", ] [[package]] @@ -302,6 +302,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" + [[package]] name = "arc-swap" version = "0.4.6" @@ -330,8 +336,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26c4f3195085c36ea8d24d32b2f828d23296a9370a28aa39d111f6f16bef9f3b" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.6", + "syn 1.0.22", ] [[package]] @@ -405,7 +411,7 @@ checksum = "1374191e2dd25f9ae02e3aa95041ed5d747fc77b3c102b49fe2dd9a8117a6244" dependencies = [ "num-bigint", "num-integer", - "num-traits", + "num-traits 0.2.11", "serde", ] @@ -514,7 +520,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" dependencies = [ "num-integer", - "num-traits", + "num-traits 0.2.11", "serde", "time", ] @@ -551,6 +557,7 @@ dependencies = [ "mailchecker", "mime_guess", "mysql", + "pdf", "percent-encoding", "rand", "serde", @@ -675,8 +682,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2127768764f1556535c01b5326ef94bd60ff08dcfbdc544d53e69ed155610f5d" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.6", + "syn 1.0.22", ] [[package]] @@ -686,8 +693,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "114aa287358087a616096186f3de19525d8083f83d437dc6b583f895316b02e6" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.6", + "syn 1.0.22", ] [[package]] @@ -711,6 +718,70 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" +[[package]] +name = "encoding" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" +dependencies = [ + "encoding-index-japanese", + "encoding-index-korean", + "encoding-index-simpchinese", + "encoding-index-singlebyte", + "encoding-index-tradchinese", +] + +[[package]] +name = "encoding-index-japanese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-korean" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-simpchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-singlebyte" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-tradchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding_index_tests" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" + [[package]] name = "encoding_rs" version = "0.8.23" @@ -728,8 +799,17 @@ checksum = "bc4bfcfacb61d231109d1d55202c1f33263319668b168843e02ad4652725ec9c" dependencies = [ "heck", "proc-macro2", - "quote", - "syn", + "quote 1.0.6", + "syn 1.0.22", +] + +[[package]] +name = "error-chain" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" +dependencies = [ + "backtrace", ] [[package]] @@ -749,8 +829,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.6", + "syn 1.0.22", "synstructure", ] @@ -803,6 +883,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi 0.3.8", +] + [[package]] name = "fuchsia-zircon" version = "0.3.3" @@ -875,8 +965,8 @@ checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" dependencies = [ "proc-macro-hack", "proc-macro2", - "quote", - "syn", + "quote 1.0.6", + "syn 1.0.22", ] [[package]] @@ -953,6 +1043,12 @@ dependencies = [ "lzw", ] +[[package]] +name = "glob" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" + [[package]] name = "h2" version = "0.2.5" @@ -1051,7 +1147,7 @@ dependencies = [ "jpeg-decoder", "num-iter", "num-rational", - "num-traits", + "num-traits 0.2.11", "png", "scoped_threadpool", "tiff", @@ -1066,6 +1162,12 @@ dependencies = [ "autocfg 1.0.0", ] +[[package]] +name = "inflate" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e0062d2dc2f17d2f13750d95316ae8a2ff909af0fda957084f5defd87c43bb" + [[package]] name = "io-enum" version = "0.2.2" @@ -1073,8 +1175,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "285762158c743ac75969bc8e9062ddcb013121d0c8aae32156740e621d2f3194" dependencies = [ "derive_utils", - "quote", - "syn", + "quote 1.0.6", + "syn 1.0.22", ] [[package]] @@ -1098,6 +1200,27 @@ dependencies = [ "winreg", ] +[[package]] +name = "isatty" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31a8281fc93ec9693494da65fbf28c0c2aa60a2eaec25dc58e2f31952e95edc" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi 0.3.8", +] + +[[package]] +name = "itertools" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.5" @@ -1269,6 +1392,18 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +[[package]] +name = "memmap" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f3c7359028b31999287dae4e5047ddfe90a23b7dca2282ce759b491080c99b" +dependencies = [ + "fs2", + "kernel32-sys", + "libc", + "winapi 0.2.8", +] + [[package]] name = "memoffset" version = "0.5.4" @@ -1391,7 +1526,7 @@ dependencies = [ "lazy_static", "lexical", "num-bigint", - "num-traits", + "num-traits 0.2.11", "rand", "regex", "rust_decimal", @@ -1469,7 +1604,7 @@ checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ "autocfg 1.0.0", "num-integer", - "num-traits", + "num-traits 0.2.11", ] [[package]] @@ -1479,7 +1614,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" dependencies = [ "autocfg 1.0.0", - "num-traits", + "num-traits 0.2.11", ] [[package]] @@ -1490,7 +1625,7 @@ checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f" dependencies = [ "autocfg 1.0.0", "num-integer", - "num-traits", + "num-traits 0.2.11", ] [[package]] @@ -1501,7 +1636,16 @@ checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" dependencies = [ "autocfg 1.0.0", "num-integer", - "num-traits", + "num-traits 0.2.11", +] + +[[package]] +name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +dependencies = [ + "num-traits 0.2.11", ] [[package]] @@ -1568,6 +1712,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ordermap" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b81cf3b8cb96aa0e73bbedfcdc9708d09fec2854ba8d474be4e6f666d7379e8b" + [[package]] name = "parking_lot" version = "0.10.2" @@ -1592,6 +1742,39 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "pdf" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7835739fa247acac9246181a184c60c7b5cf7a51315f6a1ab7a6dd10444a92d3" +dependencies = [ + "ansi_term", + "byteorder", + "chrono", + "encoding", + "error-chain", + "glob", + "inflate", + "isatty", + "itertools", + "lzw", + "memmap", + "num-traits 0.1.43", + "ordermap", + "pdf_derive", + "tuple", +] + +[[package]] +name = "pdf_derive" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e26454c6beff4d298c564bd3f115e1a92450cc91e0b5abcd1e0da2b03621e1d" +dependencies = [ + "quote 0.3.15", + "syn 0.11.11", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -1614,8 +1797,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e58db2081ba5b4c93bd6be09c40fd36cb9193a8336c384f3b40012e531aa7e40" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.6", + "syn 1.0.22", ] [[package]] @@ -1672,7 +1855,7 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53f5ffe53a6b28e37c9c1ce74893477864d64f74778a93a4beb43c8fa167f639" dependencies = [ - "unicode-xid", + "unicode-xid 0.2.0", ] [[package]] @@ -1681,6 +1864,12 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" + [[package]] name = "quote" version = "1.0.6" @@ -1807,7 +1996,7 @@ checksum = "ecffe00b665f0947e39e3b00302fce59303e99d25ea519cdd295616834255a0c" dependencies = [ "byteorder", "bytes", - "num-traits", + "num-traits 0.2.11", "serde", ] @@ -1908,8 +2097,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984" dependencies = [ "proc-macro2", - "quote", - "syn", + "quote 1.0.6", + "syn 1.0.22", ] [[package]] @@ -1993,6 +2182,17 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3" +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +dependencies = [ + "quote 0.3.15", + "synom", + "unicode-xid 0.0.4", +] + [[package]] name = "syn" version = "1.0.22" @@ -2000,8 +2200,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1425de3c33b0941002740a420b1a906a350b88d08b82b2c8a01035a3f9447bac" dependencies = [ "proc-macro2", - "quote", - "unicode-xid", + "quote 1.0.6", + "unicode-xid 0.2.0", +] + +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +dependencies = [ + "unicode-xid 0.0.4", ] [[package]] @@ -2011,9 +2220,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ "proc-macro2", - "quote", - "syn", - "unicode-xid", + "quote 1.0.6", + "syn 1.0.22", + "unicode-xid 0.2.0", ] [[package]] @@ -2156,6 +2365,16 @@ dependencies = [ "trust-dns-proto", ] +[[package]] +name = "tuple" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "014493a81b7f393503eb896ab5b268532baff9359a7f4efe347dca3359f317f2" +dependencies = [ + "num-traits 0.1.43", + "serde", +] + [[package]] name = "twoway" version = "0.2.1" @@ -2220,6 +2439,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" + [[package]] name = "unicode-xid" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index 948afcf..37af7c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,4 +25,5 @@ bytes = "0.5.4" image = "0.23.5" kamadak-exif = "0.5.1" lazy_static = "1.4.0" -mime_guess = "2.0.3" \ No newline at end of file +mime_guess = "2.0.3" +pdf = "0.6.3" \ No newline at end of file diff --git a/src/constants.rs b/src/constants.rs index 03a16c0..6fd99ef 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -67,7 +67,10 @@ pub const PATH_GROUPS_LOGOS: &str = "groups_logo"; 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"; +pub const PATH_POST_IMAGES: &str = "imgpost"; + +/// The path were PDF included with posts should be stored +pub const PATH_POST_PDF: &str = "post_pdf"; /// 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 4f75570..83d34d3 100644 --- a/src/controllers/posts_controller.rs +++ b/src/controllers/posts_controller.rs @@ -4,7 +4,7 @@ use crate::api_data::post_api::PostAPI; use crate::api_data::res_create_post::ResCreatePost; -use crate::constants::PATH_POST_IMAGES; +use crate::constants::{PATH_POST_IMAGES, PATH_POST_PDF}; use crate::controllers::routes::RequestResult; use crate::data::error::{ExecError, ResultBoxError}; use crate::data::group::GroupAccessLevel; @@ -174,6 +174,16 @@ pub fn create_post(r: &mut HttpRequestHandler) -> RequestResult { }) } + "pdf" => { + if !r.has_file("pdf") { + r.bad_request("Missing PDF in 'pdf'!".to_string())?; + } + + let file = r.save_post_pdf("pdf", PATH_POST_PDF)?; + + PostKind::POST_KIND_PDF(PostFile::new_from_created_file(&file)?) + } + // TODO : add support for next types _ => { diff --git a/src/data/http_request_handler.rs b/src/data/http_request_handler.rs index 53bfd2a..ca36e3d 100644 --- a/src/data/http_request_handler.rs +++ b/src/data/http_request_handler.rs @@ -20,6 +20,7 @@ use crate::data::post::{Post, PostAccessLevel}; use crate::data::user::UserID; use crate::helpers::{account_helper, api_helper, conversations_helper, friends_helper, groups_helper, movies_helper, posts_helper, user_helper, virtual_directory_helper}; use crate::helpers::virtual_directory_helper::VirtualDirType; +use crate::utils::pdf_utils::is_valid_pdf; use crate::utils::string_utils::{check_url, remove_html_nodes}; use crate::utils::user_data_utils::{generate_new_user_data_file_name, prepare_file_creation, user_data_path}; use crate::utils::virtual_directories_utils::check_virtual_directory; @@ -339,6 +340,28 @@ impl HttpRequestHandler { Ok(target_file_path.to_string_lossy().to_string()) } + /// Save a pdf included in the request + pub fn save_post_pdf(&mut self, name: &str, folder: &str) -> ResultBoxError { + let file = self.post_file(name)?; + + if !is_valid_pdf(&file.buff)? { + self.bad_request(format!("Invalid PDF specified in {} !", name))?; + unreachable!(); + } + + // Avoid memory warnings + let copied_buff = file.buff.clone(); + + // Determine pdf file destination + let target_user_data_folder = prepare_file_creation(self.user_id_ref()?, folder)?; + let target_file_path = generate_new_user_data_file_name(target_user_data_folder.as_path(), "pdf")?; + let target_sys_path = user_data_path(target_file_path.as_path()); + + std::fs::write(target_sys_path, &copied_buff.as_ref())?; + + Ok(target_file_path.to_string_lossy().to_string()) + } + /// Get an integer included in the POST request pub fn post_i64(&mut self, name: &str) -> ResultBoxError { Ok(self.post_string(name)?.parse::()?) diff --git a/src/utils/mod.rs b/src/utils/mod.rs index bda5ce1..a9559af 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -6,4 +6,5 @@ pub mod crypt_utils; pub mod user_data_utils; pub mod virtual_directories_utils; pub mod date_utils; -pub mod string_utils; \ No newline at end of file +pub mod string_utils; +pub mod pdf_utils; \ No newline at end of file diff --git a/src/utils/pdf_utils.rs b/src/utils/pdf_utils.rs new file mode 100644 index 0000000..9b46d46 --- /dev/null +++ b/src/utils/pdf_utils.rs @@ -0,0 +1,22 @@ +//! # PDF utilities +//! +//! @author Pierre Hubert + +use crate::data::error::{ExecError, ResultBoxError}; + +/// Check out whether a PDF is a valid PDF or not, by trying to open it +pub fn is_valid_pdf(file: &bytes::Bytes) -> ResultBoxError { + let pdf = pdf::file::File::new(Vec::from(file.as_ref())); + + match pdf.get_num_pages() { + Ok(num) if num < 1 => + Err(ExecError::boxed_string(format!("Detected a PDF with {} pages!", num))), + + Ok(_) => Ok(true), + + Err(e) => { + println!("Error while parsing PDF: {}", e); + Ok(false) + } + } +} \ No newline at end of file