Can export data as ZIP file
This commit is contained in:
parent
1b3ce1a98d
commit
f335b9d0c0
210
moneymgr_backend/Cargo.lock
generated
210
moneymgr_backend/Cargo.lock
generated
@ -34,6 +34,29 @@ dependencies = [
|
|||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "actix-files"
|
||||||
|
version = "0.6.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0773d59061dedb49a8aed04c67291b9d8cf2fe0b60130a381aab53c6dd86e9be"
|
||||||
|
dependencies = [
|
||||||
|
"actix-http",
|
||||||
|
"actix-service",
|
||||||
|
"actix-utils",
|
||||||
|
"actix-web",
|
||||||
|
"bitflags",
|
||||||
|
"bytes",
|
||||||
|
"derive_more 0.99.19",
|
||||||
|
"futures-core",
|
||||||
|
"http-range",
|
||||||
|
"log",
|
||||||
|
"mime",
|
||||||
|
"mime_guess",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project-lite",
|
||||||
|
"v_htmlescape",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "actix-http"
|
name = "actix-http"
|
||||||
version = "3.10.0"
|
version = "3.10.0"
|
||||||
@ -412,6 +435,15 @@ version = "1.0.97"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
|
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arbitrary"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
|
||||||
|
dependencies = [
|
||||||
|
"derive_arbitrary",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arc-swap"
|
name = "arc-swap"
|
||||||
version = "1.7.1"
|
version = "1.7.1"
|
||||||
@ -612,6 +644,25 @@ dependencies = [
|
|||||||
"bytes",
|
"bytes",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bzip2"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47"
|
||||||
|
dependencies = [
|
||||||
|
"bzip2-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bzip2-sys"
|
||||||
|
version = "0.1.13+1.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "castaway"
|
name = "castaway"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
@ -827,6 +878,21 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc"
|
||||||
|
version = "3.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"
|
||||||
|
dependencies = [
|
||||||
|
"crc-catalog",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc-catalog"
|
||||||
|
version = "2.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.4.2"
|
version = "1.4.2"
|
||||||
@ -836,6 +902,12 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.8.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crunchy"
|
name = "crunchy"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
@ -915,6 +987,12 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deflate64"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "der"
|
name = "der"
|
||||||
version = "0.7.9"
|
version = "0.7.9"
|
||||||
@ -936,6 +1014,17 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derive_arbitrary"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_more"
|
name = "derive_more"
|
||||||
version = "0.99.19"
|
version = "0.99.19"
|
||||||
@ -1365,8 +1454,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
|
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.13.3+wasi-0.2.2",
|
"wasi 0.13.3+wasi-0.2.2",
|
||||||
|
"wasm-bindgen",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1555,6 +1646,12 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http-range"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httparse"
|
name = "httparse"
|
||||||
version = "1.10.1"
|
version = "1.10.1"
|
||||||
@ -2046,6 +2143,27 @@ version = "0.4.27"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lzma-rs"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"crc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lzma-sys"
|
||||||
|
version = "0.1.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "maybe-async"
|
name = "maybe-async"
|
||||||
version = "0.2.10"
|
version = "0.2.10"
|
||||||
@ -2141,6 +2259,7 @@ name = "moneymgr_backend"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-cors",
|
"actix-cors",
|
||||||
|
"actix-files",
|
||||||
"actix-multipart",
|
"actix-multipart",
|
||||||
"actix-remote-ip",
|
"actix-remote-ip",
|
||||||
"actix-session",
|
"actix-session",
|
||||||
@ -2166,8 +2285,10 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
"tempfile",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"zip",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2378,6 +2499,16 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "487f2ccd1e17ce8c1bfab3a65c89525af41cfad4c8659021a1e9a2aacd73b89b"
|
checksum = "487f2ccd1e17ce8c1bfab3a65c89525af41cfad4c8659021a1e9a2aacd73b89b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pbkdf2"
|
||||||
|
version = "0.12.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
|
||||||
|
dependencies = [
|
||||||
|
"digest",
|
||||||
|
"hmac",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pem-rfc7468"
|
name = "pem-rfc7468"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -3142,6 +3273,12 @@ dependencies = [
|
|||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simd-adler32"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
@ -3274,9 +3411,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.19.0"
|
version = "3.19.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600"
|
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"getrandom 0.3.1",
|
"getrandom 0.3.1",
|
||||||
@ -3627,6 +3764,12 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "v_htmlescape"
|
||||||
|
version = "0.15.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4e8257fbc510f0a46eb602c10215901938b5c2a7d5e70fc11483b1d3c9b5b18c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
@ -4031,6 +4174,15 @@ version = "0.5.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xz2"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2"
|
||||||
|
dependencies = [
|
||||||
|
"lzma-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yoke"
|
||||||
version = "0.7.5"
|
version = "0.7.5"
|
||||||
@ -4101,6 +4253,20 @@ name = "zeroize"
|
|||||||
version = "1.8.1"
|
version = "1.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
|
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
|
||||||
|
dependencies = [
|
||||||
|
"zeroize_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zeroize_derive"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerovec"
|
name = "zerovec"
|
||||||
@ -4124,6 +4290,46 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zip"
|
||||||
|
version = "2.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1dcb24d0152526ae49b9b96c1dcf71850ca1e0b882e4e28ed898a93c41334744"
|
||||||
|
dependencies = [
|
||||||
|
"aes",
|
||||||
|
"arbitrary",
|
||||||
|
"bzip2",
|
||||||
|
"constant_time_eq",
|
||||||
|
"crc32fast",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"deflate64",
|
||||||
|
"flate2",
|
||||||
|
"getrandom 0.3.1",
|
||||||
|
"hmac",
|
||||||
|
"indexmap",
|
||||||
|
"lzma-rs",
|
||||||
|
"memchr",
|
||||||
|
"pbkdf2",
|
||||||
|
"sha1",
|
||||||
|
"time",
|
||||||
|
"xz2",
|
||||||
|
"zeroize",
|
||||||
|
"zopfli",
|
||||||
|
"zstd",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zopfli"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "edfc5ee405f504cd4984ecc6f14d02d55cfda60fa4b689434ef4102aae150cd7"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"crc32fast",
|
||||||
|
"log",
|
||||||
|
"simd-adler32",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zstd"
|
name = "zstd"
|
||||||
version = "0.13.3"
|
version = "0.13.3"
|
||||||
|
@ -14,6 +14,7 @@ actix-cors = "0.7.0"
|
|||||||
actix-multipart = "0.7.0"
|
actix-multipart = "0.7.0"
|
||||||
actix-remote-ip = "0.1.0"
|
actix-remote-ip = "0.1.0"
|
||||||
actix-session = { version = "0.10.0", features = ["redis-session"] }
|
actix-session = { version = "0.10.0", features = ["redis-session"] }
|
||||||
|
actix-files = "0.6.6"
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
anyhow = "1.0.97"
|
anyhow = "1.0.97"
|
||||||
serde = { version = "1.0.219", features = ["derive"] }
|
serde = { version = "1.0.219", features = ["derive"] }
|
||||||
@ -32,3 +33,5 @@ rust-embed = { version = "8.6.0" }
|
|||||||
sha2 = "0.10.8"
|
sha2 = "0.10.8"
|
||||||
httpdate = "1.0.3"
|
httpdate = "1.0.3"
|
||||||
chrono = "0.4.41"
|
chrono = "0.4.41"
|
||||||
|
tempfile = "3.19.1"
|
||||||
|
zip = "2.6.1"
|
@ -53,3 +53,21 @@ pub const ACCOUNT_TYPES: [AccountTypeDesc; 3] = [
|
|||||||
icon: include_str!("../assets/saving.svg"),
|
icon: include_str!("../assets/saving.svg"),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/// ZIP export paths
|
||||||
|
pub mod zip_export {
|
||||||
|
/// Accounts file path inside archive
|
||||||
|
pub const ACCOUNTS_FILE: &str = "accounts.json";
|
||||||
|
|
||||||
|
/// Movements file path inside archive
|
||||||
|
pub const MOVEMENTS_FILE: &str = "movements.json";
|
||||||
|
|
||||||
|
/// Files list file path inside archive
|
||||||
|
pub const FILES_FILE: &str = "files.json";
|
||||||
|
|
||||||
|
/// Files directory inside archive
|
||||||
|
pub const FILES_DIR: &str = "files/";
|
||||||
|
|
||||||
|
/// Inbox file path inside archive
|
||||||
|
pub const INBOX_FILE: &str = "inbox.json";
|
||||||
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use crate::app_config::AppConfig;
|
||||||
|
use crate::constants;
|
||||||
use crate::controllers::HttpResult;
|
use crate::controllers::HttpResult;
|
||||||
use crate::converters::finances_manager_converter::{
|
use crate::converters::finances_manager_converter::{
|
||||||
FinancesManagerAccount, FinancesManagerFile, FinancesManagerMovement,
|
FinancesManagerAccount, FinancesManagerFile, FinancesManagerMovement,
|
||||||
@ -7,9 +9,23 @@ use crate::extractors::file_extractor::FileExtractor;
|
|||||||
use crate::models::accounts::AccountType;
|
use crate::models::accounts::AccountType;
|
||||||
use crate::services::accounts_service::UpdateAccountQuery;
|
use crate::services::accounts_service::UpdateAccountQuery;
|
||||||
use crate::services::movements_service::UpdateMovementQuery;
|
use crate::services::movements_service::UpdateMovementQuery;
|
||||||
use crate::services::{accounts_service, movements_service};
|
use crate::services::{accounts_service, files_service, movements_service};
|
||||||
use crate::utils::time_utils::{format_date, time};
|
use crate::utils::time_utils::{format_date, time};
|
||||||
use actix_web::HttpResponse;
|
use actix_files::NamedFile;
|
||||||
|
use actix_web::{HttpRequest, HttpResponse};
|
||||||
|
use serde::Serialize;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use zip::ZipWriter;
|
||||||
|
use zip::write::SimpleFileOptions;
|
||||||
|
|
||||||
|
/// Generate export filename
|
||||||
|
fn export_filename(ext: &str) -> String {
|
||||||
|
format!(
|
||||||
|
"export_{}.{ext}",
|
||||||
|
format_date(time() as i64).unwrap().replace('/', "-")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Import data from a [FinancesManager](https://gitlab.com/pierre42100/cpp-financesmanager) file
|
/// Import data from a [FinancesManager](https://gitlab.com/pierre42100/cpp-financesmanager) file
|
||||||
pub async fn finances_manager_import(auth: AuthExtractor, file: FileExtractor) -> HttpResult {
|
pub async fn finances_manager_import(auth: AuthExtractor, file: FileExtractor) -> HttpResult {
|
||||||
@ -69,10 +85,71 @@ pub async fn finances_manager_export(auth: AuthExtractor) -> HttpResult {
|
|||||||
Ok(HttpResponse::Ok()
|
Ok(HttpResponse::Ok()
|
||||||
.insert_header((
|
.insert_header((
|
||||||
"Content-Disposition",
|
"Content-Disposition",
|
||||||
format!(
|
format!("attachment; filename={}", export_filename("finance")),
|
||||||
"attachment; filename=export_{}.finance",
|
|
||||||
format_date(time() as i64)?.replace('/', "-")
|
|
||||||
),
|
|
||||||
))
|
))
|
||||||
.body(out.encode()))
|
.body(out.encode()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add JSON file to ZIP
|
||||||
|
fn zip_json<E: Serialize>(
|
||||||
|
zip: &mut ZipWriter<File>,
|
||||||
|
path: &str,
|
||||||
|
content: &E,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let file_encoded = serde_json::to_string(&content)?;
|
||||||
|
|
||||||
|
let options = SimpleFileOptions::default()
|
||||||
|
.compression_method(zip::CompressionMethod::Deflated)
|
||||||
|
.unix_permissions(0o750);
|
||||||
|
|
||||||
|
zip.start_file(path, options)?;
|
||||||
|
zip.write_all(file_encoded.as_bytes())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Export all user data as ZIP
|
||||||
|
pub async fn zip_export(req: HttpRequest, auth: AuthExtractor) -> HttpResult {
|
||||||
|
let dest_dir = tempfile::tempdir_in(&AppConfig::get().temp_dir)?;
|
||||||
|
let zip_path = dest_dir.path().join("export.zip");
|
||||||
|
|
||||||
|
let file = File::create(&zip_path)?;
|
||||||
|
let mut zip = ZipWriter::new(file);
|
||||||
|
|
||||||
|
// Process all JSON documents
|
||||||
|
zip_json(
|
||||||
|
&mut zip,
|
||||||
|
constants::zip_export::ACCOUNTS_FILE,
|
||||||
|
&accounts_service::get_list_user(auth.user_id()).await?,
|
||||||
|
)?;
|
||||||
|
zip_json(
|
||||||
|
&mut zip,
|
||||||
|
constants::zip_export::MOVEMENTS_FILE,
|
||||||
|
&movements_service::get_all_movements_user(auth.user_id()).await?,
|
||||||
|
)?;
|
||||||
|
let files_list = files_service::get_all_files_user(auth.user_id()).await?;
|
||||||
|
zip_json(&mut zip, constants::zip_export::FILES_FILE, &files_list)?;
|
||||||
|
// TODO : inbox
|
||||||
|
|
||||||
|
// Process all files
|
||||||
|
for file in files_list {
|
||||||
|
let buff = files_service::get_file_content(&file).await?;
|
||||||
|
|
||||||
|
let options = SimpleFileOptions::default()
|
||||||
|
.compression_method(zip::CompressionMethod::Deflated)
|
||||||
|
.unix_permissions(0o750);
|
||||||
|
|
||||||
|
zip.start_file(
|
||||||
|
format!("{}{}", constants::zip_export::FILES_DIR, file.sha512),
|
||||||
|
options,
|
||||||
|
)?;
|
||||||
|
zip.write_all(&buff)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finalize ZIP and return response
|
||||||
|
zip.finish()?;
|
||||||
|
let file = File::open(zip_path)?;
|
||||||
|
|
||||||
|
let file = NamedFile::from_file(file, export_filename("zip"))?;
|
||||||
|
|
||||||
|
Ok(file.into_response(&req))
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use actix_web::http::StatusCode;
|
use actix_web::http::StatusCode;
|
||||||
use actix_web::{HttpResponse, ResponseError};
|
use actix_web::{HttpResponse, ResponseError};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use zip::result::ZipError;
|
||||||
|
|
||||||
pub mod accounts_controller;
|
pub mod accounts_controller;
|
||||||
pub mod auth_controller;
|
pub mod auth_controller;
|
||||||
@ -30,6 +31,10 @@ pub enum HttpFailure {
|
|||||||
InternalError(#[from] anyhow::Error),
|
InternalError(#[from] anyhow::Error),
|
||||||
#[error("a serde_json error occurred: {0}")]
|
#[error("a serde_json error occurred: {0}")]
|
||||||
SerdeJsonError(#[from] serde_json::error::Error),
|
SerdeJsonError(#[from] serde_json::error::Error),
|
||||||
|
#[error("a zip manipulation error occurred: {0}")]
|
||||||
|
ZipError(#[from] ZipError),
|
||||||
|
#[error("a standard I/O manipulation error occurred: {0}")]
|
||||||
|
StdIoError(#[from] std::io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResponseError for HttpFailure {
|
impl ResponseError for HttpFailure {
|
||||||
|
@ -170,6 +170,10 @@ async fn main() -> std::io::Result<()> {
|
|||||||
"/api/backup/finances_manager/export",
|
"/api/backup/finances_manager/export",
|
||||||
web::get().to(backup_controller::finances_manager_export),
|
web::get().to(backup_controller::finances_manager_export),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/api/backup/zip/export",
|
||||||
|
web::get().to(backup_controller::zip_export),
|
||||||
|
)
|
||||||
// Static assets
|
// Static assets
|
||||||
.route("/", web::get().to(static_controller::root_index))
|
.route("/", web::get().to(static_controller::root_index))
|
||||||
.route(
|
.route(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user