Updates to backend, added uploading images with s3.

This commit is contained in:
Franklin 2023-04-22 20:45:15 -04:00
parent 5f1823ab4f
commit 403064ac6c
19 changed files with 889 additions and 121 deletions

605
Cargo.lock generated
View File

@ -241,9 +241,9 @@ dependencies = [
[[package]]
name = "aho-corasick"
version = "0.7.20"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04"
dependencies = [
"memchr",
]
@ -287,6 +287,367 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "aws-config"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd62464d1c4ad70f8b6cd693e7f30229f36bebdcdf3fce8c11803e1bdc0bc052"
dependencies = [
"aws-credential-types",
"aws-http",
"aws-sdk-sso",
"aws-sdk-sts",
"aws-smithy-async",
"aws-smithy-client",
"aws-smithy-http",
"aws-smithy-http-tower",
"aws-smithy-json",
"aws-smithy-types",
"aws-types",
"bytes",
"fastrand",
"hex",
"http",
"hyper",
"ring",
"time 0.3.20",
"tokio",
"tower",
"tracing",
"zeroize",
]
[[package]]
name = "aws-credential-types"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4232d3729eefc287adc0d5a8adc97b7d94eefffe6bbe94312cc86c7ab6b06ce"
dependencies = [
"aws-smithy-async",
"aws-smithy-types",
"fastrand",
"tokio",
"tracing",
"zeroize",
]
[[package]]
name = "aws-endpoint"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f04ab03b3f1cca91f7cccaa213056d732accb14e2e65debfacc1d28627d162"
dependencies = [
"aws-smithy-http",
"aws-smithy-types",
"aws-types",
"http",
"regex",
"tracing",
]
[[package]]
name = "aws-http"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ad8c53f7560baaf635b6aa811f3213d39b50555d100f83e43801652d4e318e"
dependencies = [
"aws-credential-types",
"aws-smithy-http",
"aws-smithy-types",
"aws-types",
"bytes",
"http",
"http-body",
"lazy_static",
"percent-encoding",
"pin-project-lite",
"tracing",
]
[[package]]
name = "aws-sdk-s3"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4b64fc8b7d76d09e53f4a64ebe2cd44894adb902011a26878aebd0576234d41"
dependencies = [
"aws-credential-types",
"aws-endpoint",
"aws-http",
"aws-sig-auth",
"aws-sigv4",
"aws-smithy-async",
"aws-smithy-checksums",
"aws-smithy-client",
"aws-smithy-eventstream",
"aws-smithy-http",
"aws-smithy-http-tower",
"aws-smithy-json",
"aws-smithy-types",
"aws-smithy-xml",
"aws-types",
"bytes",
"http",
"http-body",
"once_cell",
"percent-encoding",
"regex",
"tokio-stream",
"tower",
"tracing",
"url",
]
[[package]]
name = "aws-sdk-sso"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "143953d46f77a0b18480e7d8bb1a651080b9484e0bb94c27b8645eaeb3c3e231"
dependencies = [
"aws-credential-types",
"aws-endpoint",
"aws-http",
"aws-sig-auth",
"aws-smithy-async",
"aws-smithy-client",
"aws-smithy-http",
"aws-smithy-http-tower",
"aws-smithy-json",
"aws-smithy-types",
"aws-types",
"bytes",
"http",
"regex",
"tokio-stream",
"tower",
"tracing",
]
[[package]]
name = "aws-sdk-sts"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7255c0d8053b89e8b5cdabb52e1dbf596e9968b1f45dce7a56b2cd57038fcfc9"
dependencies = [
"aws-credential-types",
"aws-endpoint",
"aws-http",
"aws-sig-auth",
"aws-smithy-async",
"aws-smithy-client",
"aws-smithy-http",
"aws-smithy-http-tower",
"aws-smithy-json",
"aws-smithy-query",
"aws-smithy-types",
"aws-smithy-xml",
"aws-types",
"bytes",
"http",
"regex",
"tower",
"tracing",
]
[[package]]
name = "aws-sig-auth"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d77d879ab210e958ba65a6d3842969a596738c024989cd3e490cf9f9b560ec"
dependencies = [
"aws-credential-types",
"aws-sigv4",
"aws-smithy-eventstream",
"aws-smithy-http",
"aws-types",
"http",
"tracing",
]
[[package]]
name = "aws-sigv4"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ab4eebc8ec484fb9eab04b15a5d1e71f3dc13bee8fdd2d9ed78bcd6ecbd7192"
dependencies = [
"aws-smithy-eventstream",
"aws-smithy-http",
"bytes",
"form_urlencoded",
"hex",
"hmac",
"http",
"once_cell",
"percent-encoding",
"regex",
"sha2",
"time 0.3.20",
"tracing",
]
[[package]]
name = "aws-smithy-async"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88573bcfbe1dcfd54d4912846df028b42d6255cbf9ce07be216b1bbfd11fc4b9"
dependencies = [
"futures-util",
"pin-project-lite",
"tokio",
"tokio-stream",
]
[[package]]
name = "aws-smithy-checksums"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71a63d4f1c04b3abb7603001e4513f19617427bf27ca185b2ac663a1e342d39e"
dependencies = [
"aws-smithy-http",
"aws-smithy-types",
"bytes",
"crc32c",
"crc32fast",
"hex",
"http",
"http-body",
"md-5",
"pin-project-lite",
"sha1",
"sha2",
"tracing",
]
[[package]]
name = "aws-smithy-client"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2f52352bae50d3337d5d6151b695d31a8c10ebea113eca5bead531f8301b067"
dependencies = [
"aws-smithy-async",
"aws-smithy-http",
"aws-smithy-http-tower",
"aws-smithy-types",
"bytes",
"fastrand",
"http",
"http-body",
"hyper",
"hyper-rustls",
"lazy_static",
"pin-project-lite",
"rustls",
"tokio",
"tower",
"tracing",
]
[[package]]
name = "aws-smithy-eventstream"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168f08f8439c8b317b578a695e514c5cd7b869e73849a2d6b71ced4de6ce193d"
dependencies = [
"aws-smithy-types",
"bytes",
"crc32fast",
]
[[package]]
name = "aws-smithy-http"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03bcc02d7ed9649d855c8ce4a735e9848d7b8f7568aad0504c158e3baa955df8"
dependencies = [
"aws-smithy-eventstream",
"aws-smithy-types",
"bytes",
"bytes-utils",
"futures-core",
"http",
"http-body",
"hyper",
"once_cell",
"percent-encoding",
"pin-project-lite",
"pin-utils",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "aws-smithy-http-tower"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da88b3a860f65505996c29192d800f1aeb9480440f56d63aad33a3c12045017a"
dependencies = [
"aws-smithy-http",
"aws-smithy-types",
"bytes",
"http",
"http-body",
"pin-project-lite",
"tower",
"tracing",
]
[[package]]
name = "aws-smithy-json"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b0c1e87d75cac889dca2a7f5ba280da2cde8122448e7fec1d614194dfa00c70"
dependencies = [
"aws-smithy-types",
]
[[package]]
name = "aws-smithy-query"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6b50d15f446c19e088009ecb00e2fb2d13133d6fe1db702e9aa67ad135bf6a6"
dependencies = [
"aws-smithy-types",
"urlencoding",
]
[[package]]
name = "aws-smithy-types"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd0afc731fd1417d791f9145a1e0c30e23ae0beaab9b4814017708ead2fc20f1"
dependencies = [
"base64-simd",
"itoa",
"num-integer",
"ryu",
"time 0.3.20",
]
[[package]]
name = "aws-smithy-xml"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b5398c1c25dfc6f8c282b1552a66aa807c9d6e15e1b3a84b94aa44e7859bec3"
dependencies = [
"xmlparser",
]
[[package]]
name = "aws-types"
version = "0.55.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9b082e329d9a304d39e193ad5c7ab363a0d6507aca6965e0673a746686fb0cc"
dependencies = [
"aws-credential-types",
"aws-smithy-async",
"aws-smithy-client",
"aws-smithy-http",
"aws-smithy-types",
"http",
"rustc_version",
"tracing",
]
[[package]]
name = "base64"
version = "0.13.1"
@ -299,6 +660,16 @@ version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
[[package]]
name = "base64-simd"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195"
dependencies = [
"outref",
"vsimd",
]
[[package]]
name = "bincode"
version = "1.3.3"
@ -346,9 +717,9 @@ dependencies = [
[[package]]
name = "bumpalo"
version = "3.12.0"
version = "3.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8"
[[package]]
name = "byteorder"
@ -362,6 +733,16 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
[[package]]
name = "bytes-utils"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e47d3a8076e283f3acd27400535992edb3ba4b5bb72f8891ad8fbe7932a7d4b9"
dependencies = [
"bytes",
"either",
]
[[package]]
name = "bytestring"
version = "1.3.0"
@ -451,6 +832,16 @@ dependencies = [
"version_check",
]
[[package]]
name = "core-foundation"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.4"
@ -459,9 +850,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]]
name = "cpufeatures"
version = "0.2.6"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181"
checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58"
dependencies = [
"libc",
]
@ -481,6 +872,15 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484"
[[package]]
name = "crc32c"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfea2db42e9927a3845fb268a10a72faed6d416065f77873f05e411457c363e"
dependencies = [
"rustc_version",
]
[[package]]
name = "crc32fast"
version = "1.3.2"
@ -663,6 +1063,15 @@ version = "2.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "fastrand"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
dependencies = [
"instant",
]
[[package]]
name = "flate2"
version = "1.0.25"
@ -781,9 +1190,9 @@ dependencies = [
[[package]]
name = "h2"
version = "0.3.17"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66b91535aa35fea1523ad1b86cb6b53c28e0ae566ba4a460f4457e936cad7c6f"
checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21"
dependencies = [
"bytes",
"fnv",
@ -924,7 +1333,9 @@ checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c"
dependencies = [
"http",
"hyper",
"log",
"rustls",
"rustls-native-certs",
"tokio",
"tokio-rustls",
]
@ -1010,6 +1421,8 @@ dependencies = [
"actix-cors",
"actix-web",
"actix-web-utils",
"aws-config",
"aws-sdk-s3",
"chrono",
"chrono-tz",
"dotenv",
@ -1017,6 +1430,7 @@ dependencies = [
"dotenvy_macro",
"err",
"jl-types",
"rand",
"reqwest",
"serde",
"serde_json",
@ -1065,10 +1479,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
[[package]]
name = "libc"
version = "0.2.141"
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.142"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"
[[package]]
name = "link-cplusplus"
@ -1162,7 +1582,7 @@ dependencies = [
"libc",
"log",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys",
"windows-sys 0.45.0",
]
[[package]]
@ -1210,6 +1630,18 @@ version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "openssl-probe"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "outref"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a"
[[package]]
name = "parking_lot"
version = "0.11.2"
@ -1255,7 +1687,7 @@ dependencies = [
"libc",
"redox_syscall",
"smallvec",
"windows-sys",
"windows-sys 0.45.0",
]
[[package]]
@ -1317,6 +1749,26 @@ dependencies = [
"siphasher",
]
[[package]]
name = "pin-project"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "pin-project-lite"
version = "0.2.9"
@ -1411,9 +1863,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.7.3"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d"
checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
dependencies = [
"aho-corasick",
"memchr",
@ -1422,9 +1874,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.29"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
[[package]]
name = "reqwest"
@ -1501,6 +1953,18 @@ dependencies = [
"webpki",
]
[[package]]
name = "rustls-native-certs"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50"
dependencies = [
"openssl-probe",
"rustls-pemfile",
"schannel",
"security-framework",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.2"
@ -1516,6 +1980,15 @@ version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]]
name = "schannel"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
dependencies = [
"windows-sys 0.42.0",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
@ -1538,6 +2011,29 @@ dependencies = [
"untrusted",
]
[[package]]
name = "security-framework"
version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254"
dependencies = [
"bitflags",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "semver"
version = "1.0.17"
@ -1900,7 +2396,7 @@ dependencies = [
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys",
"windows-sys 0.45.0",
]
[[package]]
@ -1950,6 +2446,28 @@ dependencies = [
"tracing",
]
[[package]]
name = "tower"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
dependencies = [
"futures-core",
"futures-util",
"pin-project",
"pin-project-lite",
"tokio",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
[[package]]
name = "tower-service"
version = "0.3.2"
@ -1965,9 +2483,21 @@ dependencies = [
"cfg-if",
"log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "tracing-core"
version = "0.1.30"
@ -2045,6 +2575,12 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "urlencoding"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9"
[[package]]
name = "uuid"
version = "1.3.1"
@ -2074,6 +2610,12 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "vsimd"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64"
[[package]]
name = "want"
version = "0.3.0"
@ -2241,6 +2783,21 @@ dependencies = [
"windows-targets 0.48.0",
]
[[package]]
name = "windows-sys"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm 0.42.2",
"windows_aarch64_msvc 0.42.2",
"windows_i686_gnu 0.42.2",
"windows_i686_msvc 0.42.2",
"windows_x86_64_gnu 0.42.2",
"windows_x86_64_gnullvm 0.42.2",
"windows_x86_64_msvc 0.42.2",
]
[[package]]
name = "windows-sys"
version = "0.45.0"
@ -2373,6 +2930,18 @@ dependencies = [
"winapi",
]
[[package]]
name = "xmlparser"
version = "0.13.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d25c75bf9ea12c4040a97f829154768bbbce366287e2dc044af160cd79a13fd"
[[package]]
name = "zeroize"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
[[package]]
name = "zstd"
version = "0.12.3+zstd.1.5.2"

View File

@ -23,4 +23,8 @@ uuid = { version = "1.3.0", features = ["v4", "fast-rng", "macro-diagnostics"] }
actix-web-utils = { git = "https://git.franklinblanco.dev/franklinblanco/actix-web-utils.git" }
err = { git = "https://git.franklinblanco.dev/franklinblanco/err.git" }
aws-config = "0.55.1"
aws-sdk-s3 = "0.26.0"
rand = "0.8.5"
jl-types = { path = "../jl-types", features = ["sqlx"]}

View File

@ -8,4 +8,4 @@ SELECT
time_created,
last_updated
FROM agent
ORDER BY full_name DESC;
ORDER BY full_name ASC;

View File

@ -7,5 +7,4 @@ SELECT
profile_picture_url,
time_created,
last_updated
FROM agent where shortcode = $1
ORDER BY time_created DESC;
FROM agent where shortcode = $1;

View File

@ -12,7 +12,7 @@
},
"query": "DELETE FROM agent WHERE id = $1;"
},
"181ffb1869d9acb225071b9a5650510f29fca447892f698ae597d370764e35ad": {
"11b388533d1cece58959754172768a0fa4bfd430ad29a3bf0eca81bbbe7ecc22": {
"describe": {
"columns": [
{
@ -79,11 +79,12 @@
"Text",
"Text",
"Text",
"Int2",
"Int8"
]
}
},
"query": "SELECT \n p.id,\n p.project_state as \"project_state: _\",\n p.project_type as \"project_type: _\",\n p.project_condition as \"project_condition: _\",\n l.city,\n (SELECT (SELECT u.price_usd FROM unit u WHERE u.project_id = p.id ORDER BY u.price_usd DESC LIMIT 1)) as starts_from,\n l.district,\n p.finish_date,\n p.media as \"media: _\"\nFROM project p, location l\nWHERE p.location_id = l.id\n-- Filters here:\nAND (LOWER(l.city) LIKE '%' || LOWER($1) || '%' OR $1 IS null) -- City Filter\nAND (LOWER(l.district) LIKE '%' || LOWER($2) || '%' OR $2 IS null) -- District Filter\nAND (p.project_type = $3 OR $3 IS null) -- ProjectType\nAND (p.project_condition = $4 OR $4 IS null) -- ProjectCondition\nAND (p.project_state = $5 OR $5 IS null) -- ProjectState\n-- End of filters\nORDER BY p.time_created DESC\nLIMIT 50 OFFSET $6;"
"query": "SELECT \n p.id,\n p.project_state as \"project_state: _\",\n p.project_type as \"project_type: _\",\n p.project_condition as \"project_condition: _\",\n l.city,\n (SELECT (SELECT u.price_usd FROM unit u WHERE u.project_id = p.id ORDER BY u.price_usd DESC LIMIT 1)) as starts_from,\n l.district,\n p.finish_date,\n p.media as \"media: _\"\nFROM project p, location l\nWHERE p.location_id = l.id\n-- Filters here:\nAND (LOWER(l.city) LIKE '%' || LOWER($1) || '%' OR $1 IS null) -- City Filter\nAND (LOWER(l.district) LIKE '%' || LOWER($2) || '%' OR $2 IS null) -- District Filter\nAND (p.project_type = $3 OR $3 IS null) -- ProjectType\nAND (p.project_condition = $4 OR $4 IS null) -- ProjectCondition\nAND (p.project_state = $5 OR $5 IS null) -- ProjectState\nAND ((SELECT COUNT(*) FROM unit u WHERE u.project_id = p.id AND u.rooms = $6) > 0 OR $6 IS NULL)\n-- End of filters\nORDER BY p.time_created DESC\nLIMIT 50 OFFSET $7;"
},
"19a20556f5e3621438cd583aae4984c8cf510f359f65ec599f8a6b46d9153ec4": {
"describe": {
@ -217,6 +218,68 @@
},
"query": "DELETE FROM location where id = $1;"
},
"44a6ca26f099484f650c58858cc54aae7e1210b9618ad6b123f22e02db729381": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "shortcode",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "full_name",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "credential",
"ordinal": 3,
"type_info": "Varchar"
},
{
"name": "credential_type: _",
"ordinal": 4,
"type_info": "Varchar"
},
{
"name": "profile_picture_url",
"ordinal": 5,
"type_info": "Varchar"
},
{
"name": "time_created",
"ordinal": 6,
"type_info": "Timestamptz"
},
{
"name": "last_updated",
"ordinal": 7,
"type_info": "Timestamptz"
}
],
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false
],
"parameters": {
"Left": [
"Text"
]
}
},
"query": "SELECT \n id,\n shortcode,\n full_name,\n credential,\n credential_type as \"credential_type: _\",\n profile_picture_url,\n time_created,\n last_updated\nFROM agent where shortcode = $1;"
},
"4ef2f2177dd00503913e281cf97bd922bcdc4b30ed834505eb8ea9a396f73331": {
"describe": {
"columns": [],
@ -303,25 +366,7 @@
},
"query": "DELETE FROM unit WHERE id = $1;"
},
"70fa05f0ac30cba1fb2c3c356d1da567a1b3b417bdfd313f1d3b55c550e217f0": {
"describe": {
"columns": [
{
"name": "count",
"ordinal": 0,
"type_info": "Int8"
}
],
"nullable": [
null
],
"parameters": {
"Left": []
}
},
"query": "SELECT COUNT(*) FROM visit;"
},
"7792ad0bec652b57156e4ac7010324a97984263434702de060ceab7cdcf691c0": {
"58c56b5239d3756507a0dbedf40217a7e345c4a60b1042d0cbabf49dc80d1aa4": {
"describe": {
"columns": [
{
@ -379,7 +424,25 @@
"Left": []
}
},
"query": "SELECT\n id,\n shortcode,\n full_name,\n credential,\n credential_type as \"credential_type: _\",\n profile_picture_url,\n time_created,\n last_updated\nFROM agent\nORDER BY full_name DESC;"
"query": "SELECT\n id,\n shortcode,\n full_name,\n credential,\n credential_type as \"credential_type: _\",\n profile_picture_url,\n time_created,\n last_updated\nFROM agent\nORDER BY full_name ASC;"
},
"70fa05f0ac30cba1fb2c3c356d1da567a1b3b417bdfd313f1d3b55c550e217f0": {
"describe": {
"columns": [
{
"name": "count",
"ordinal": 0,
"type_info": "Int8"
}
],
"nullable": [
null
],
"parameters": {
"Left": []
}
},
"query": "SELECT COUNT(*) FROM visit;"
},
"825e1ac484241349c54e75bb77186ce41ea98fd17cabd7308e737a6c9c5812a9": {
"describe": {

View File

@ -30,6 +30,15 @@ pub async fn get_agent_with_id(
.await
}
pub async fn get_agent_with_shortcode(
conn: &PgPool,
shortcode: &String,
) -> Result<Option<Agent>, sqlx::Error> {
sqlx::query_file_as!(Agent, "sql/agent/get_with_shortcode.sql", shortcode)
.fetch_optional(conn)
.await
}
pub async fn get_agents_with_ids(
conn: &PgPool,
agent_ids: &Vec<Uuid>,

View File

@ -1,4 +1,4 @@
use jl_types::domain::{count::Count, contact::Contact};
use jl_types::domain::{contact::Contact, count::Count};
use sqlx::{postgres::PgQueryResult, PgPool};
pub async fn insert(db_conn: &PgPool, contact: &Contact) -> Result<PgQueryResult, sqlx::Error> {
@ -15,9 +15,13 @@ pub async fn insert(db_conn: &PgPool, contact: &Contact) -> Result<PgQueryResult
}
pub async fn get_all(db_conn: &PgPool) -> Result<Vec<Contact>, sqlx::Error> {
sqlx::query_file_as!(Contact, "sql/contact/get_all.sql").fetch_all(db_conn).await
sqlx::query_file_as!(Contact, "sql/contact/get_all.sql")
.fetch_all(db_conn)
.await
}
pub async fn get_count(db_conn: &PgPool) -> Result<Count, sqlx::Error> {
sqlx::query_file_as!(Count, "sql/contact/get_count.sql").fetch_one(db_conn).await
}
sqlx::query_file_as!(Count, "sql/contact/get_count.sql")
.fetch_one(db_conn)
.await
}

View File

@ -1,7 +1,7 @@
pub mod agent;
pub mod contact;
pub mod location;
pub mod main_dao;
pub mod project;
pub mod unit;
pub mod visit;
pub mod contact;

View File

@ -88,7 +88,7 @@ pub async fn fetch_with_filters_paged(
let mut city_filter = None;
let mut district_filter = None;
let mut project_type_filter = None;
let mut project_state_filter = ProjectState::InConstruction;
let mut project_state_filter = None;
let mut project_condition_filter = None;
let mut project_room_count_filter = None;
@ -96,14 +96,13 @@ pub async fn fetch_with_filters_paged(
match filter {
Filter::InCity(city) => city_filter = Some(city),
Filter::InDistrict(district) => district_filter = Some(district),
Filter::Finished => project_state_filter = ProjectState::Finished,
Filter::Finished => project_state_filter = Some(ProjectState::Finished),
Filter::InConstruction => project_state_filter = Some(ProjectState::InConstruction),
Filter::ByProjectType(project_type) => project_type_filter = Some(project_type),
Filter::ByProjectCondition(project_condition) => {
project_condition_filter = Some(project_condition)
}
Filter::ByRoomCount(room_count) => {
project_room_count_filter = Some(room_count)
},
Filter::ByRoomCount(room_count) => project_room_count_filter = Some(room_count),
}
}

View File

@ -1,16 +1,14 @@
use jl_types::domain::{visit::Visit, count::Count};
use jl_types::domain::{count::Count, visit::Visit};
use sqlx::{postgres::PgQueryResult, PgPool};
pub async fn insert(db_conn: &PgPool, visit: &Visit) -> Result<PgQueryResult, sqlx::Error> {
sqlx::query_file!(
"sql/visit/insert.sql",
visit.ip_addr,
visit.time_created,
)
.execute(db_conn)
.await
sqlx::query_file!("sql/visit/insert.sql", visit.ip_addr, visit.time_created,)
.execute(db_conn)
.await
}
pub async fn get_count(db_conn: &PgPool) -> Result<Count, sqlx::Error> {
sqlx::query_file_as!(Count, "sql/visit/get_count.sql").fetch_one(db_conn).await
}
sqlx::query_file_as!(Count, "sql/visit/get_count.sql")
.fetch_one(db_conn)
.await
}

View File

@ -19,3 +19,16 @@ async fn main() {
.await
.unwrap();
}
#[cfg(test)]
mod tests {
/*use crate::utils::s3;
#[tokio::test]
async fn test_aws_s3_put_object() {
let client = s3::init_aws_client().await;
let result = s3::upload_image(&client).await;
println!("{:?}", result);
assert!(result.is_ok());
}*/
}

View File

@ -1,12 +1,15 @@
use std::sync::Arc;
use actix_web::{
delete, post, put,
web::{self, Path}, get,
delete, get, post, put,
web::{self, Path},
};
use actix_web_utils::extensions::typed_response::TypedHttpResponse;
use jl_types::{
domain::{agent::Agent, location::Location, project::Project, unit::Unit, count::Count, contact::Contact},
domain::{
agent::Agent, contact::Contact, count::Count, location::Location, project::Project,
unit::Unit,
},
dto::payloads::{
agent::{NewAgentPayload, UpdateAgentPayload},
location::NewLocationPayload,
@ -17,7 +20,7 @@ use jl_types::{
use sqlx::PgPool;
use uuid::Uuid;
use crate::services;
use crate::{services, utils::s3::Item};
#[post("/agent")]
pub async fn create_new_agent_profile(
@ -122,4 +125,7 @@ pub async fn get_all_contacts(db_conn: web::Data<Arc<PgPool>>) -> TypedHttpRespo
services::admin::get_all_contacts(&db_conn).await
}
#[post("images/{item}/{id}/{file_name}")]
pub async fn upload_image(aws_client: web::Data<Arc<aws_sdk_s3::Client>>, path_vars: Path<(Item, Uuid, String)>) -> TypedHttpResponse<String> {
services::admin::upload_image(&aws_client, path_vars.0.clone(), path_vars.1, path_vars.2.clone()).await
}

View File

@ -1,16 +1,19 @@
use std::sync::Arc;
use actix_cors::Cors;
use actix_web::{web, App, HttpServer};
use actix_web::{web::{self}, App, HttpServer};
use chrono::Utc;
use reqwest::Client;
use sqlx::PgPool;
use crate::utils::s3;
pub const HOST_ADDR: &str = "0.0.0.0";
pub const HOST_PORT: u16 = 8095;
pub async fn start_all_routes(start_time: i64, db_conn: Arc<PgPool>) -> Result<(), std::io::Error> {
let client_state = web::Data::new(Arc::new(Client::new()));
let aws_client = web::Data::new(Arc::new(s3::init_aws_client().await));
// Start server code that turns into a future to be executed below
let server_future = HttpServer::new(move || {
let cors_policy = Cors::permissive();
@ -18,29 +21,35 @@ pub async fn start_all_routes(start_time: i64, db_conn: Arc<PgPool>) -> Result<(
.wrap(cors_policy)
.app_data(client_state.clone())
.app_data(web::Data::new(db_conn.clone()))
.app_data(aws_client.clone())
.service(
web::scope("/admin")
.service(super::admin::create_new_agent_profile)
.service(super::admin::create_new_location)
.service(super::admin::create_new_project)
.service(super::admin::create_new_unit)
.service(super::admin::update_agent)
.service(super::admin::update_project)
.service(super::admin::update_unit)
.service(super::admin::delete_agent)
.service(super::admin::delete_location)
.service(super::admin::delete_project)
.service(super::admin::delete_unit)
.service(super::admin::get_all_contacts)
.service(super::admin::get_contacts_count)
.service(super::admin::get_visits_count))
.service(web::scope("/read")
.service(super::read::get_all_agents)
.service(super::read::get_all_locations)
.service(super::read::get_locations_in_city)
.service(super::read::get_projects_paged)
.service(super::read::get_project_data)
.service(super::read::create_contact_request))
.service(super::admin::create_new_agent_profile)
.service(super::admin::create_new_location)
.service(super::admin::create_new_project)
.service(super::admin::create_new_unit)
.service(super::admin::update_agent)
.service(super::admin::update_project)
.service(super::admin::update_unit)
.service(super::admin::delete_agent)
.service(super::admin::delete_location)
.service(super::admin::delete_project)
.service(super::admin::delete_unit)
.service(super::admin::get_all_contacts)
.service(super::admin::get_contacts_count)
.service(super::admin::get_visits_count)
.service(super::admin::upload_image)
)
.service(
web::scope("/read")
.service(super::read::get_all_agents)
.service(super::read::get_all_locations)
.service(super::read::get_locations_in_city)
.service(super::read::get_projects_paged)
.service(super::read::get_project_data)
.service(super::read::create_contact_request)
.service(super::read::get_agent_with_shortcode),
)
})
.bind((HOST_ADDR, HOST_PORT))?
.run();

View File

@ -1,17 +1,22 @@
use std::{collections::{HashMap, HashSet}, str::FromStr, sync::Arc};
use std::{
collections::{HashMap, HashSet},
str::FromStr,
sync::Arc,
};
use actix_web::{
get,
web::{self, Path}, HttpRequest, post,
get, post,
web::{self, Path},
HttpRequest,
};
use actix_web_utils::extensions::typed_response::TypedHttpResponse;
use err::MessageResource;
use jl_types::{
domain::{
agent::Agent, project_condition::ProjectCondition,
project_type::ProjectType,
domain::{agent::Agent, project_condition::ProjectCondition, project_type::ProjectType},
dto::{
filters::Filter, listing::Listing, payloads::contact::ContactPayload,
project_card::ProjectCardDto,
},
dto::{filters::Filter, listing::Listing, project_card::ProjectCardDto, payloads::contact::ContactPayload},
};
use sqlx::PgPool;
use uuid::Uuid;
@ -23,6 +28,14 @@ pub async fn get_all_agents(db_conn: web::Data<Arc<PgPool>>) -> TypedHttpRespons
services::read::get_all_agents(&db_conn).await
}
#[get("/agent/{shortcode}")]
pub async fn get_agent_with_shortcode(
db_conn: web::Data<Arc<PgPool>>,
shortcode: web::Path<String>,
) -> TypedHttpResponse<Agent> {
services::read::get_agent_with_shortcode(&db_conn, &shortcode).await
}
#[get("/locations")]
pub async fn get_all_locations(
db_conn: web::Data<Arc<PgPool>>,
@ -62,7 +75,10 @@ pub async fn get_project_data(
}
#[post("/contact")]
pub async fn create_contact_request(db_conn: web::Data<Arc<PgPool>>, contact: web::Json<ContactPayload>) -> TypedHttpResponse<()> {
pub async fn create_contact_request(
db_conn: web::Data<Arc<PgPool>>,
contact: web::Json<ContactPayload>,
) -> TypedHttpResponse<()> {
services::read::create_contact(&db_conn, contact.0).await
}
@ -80,9 +96,8 @@ fn parse_params_into_filters(
let district = params.get(key).unwrap();
filters.push(Filter::InDistrict(district.clone()));
}
"finished" => {
filters.push(Filter::Finished);
}
"finished" => filters.push(Filter::Finished),
"inconstruction" => filters.push(Filter::InConstruction),
"byprojecttype" => {
let project_type = params.get(key).unwrap();
match ProjectType::from_str(project_type) {
@ -101,9 +116,9 @@ fn parse_params_into_filters(
let room_count = params.get(key).unwrap();
match i32::from_str(&room_count) {
Ok(room_count) => filters.push(Filter::ByRoomCount(room_count)),
Err(_) => {},
Err(_) => {}
}
},
}
_ => {}
};
}

View File

@ -1,6 +1,9 @@
use actix_web_utils::extensions::typed_response::TypedHttpResponse;
use jl_types::{
domain::{agent::Agent, location::Location, project::Project, unit::Unit, count::Count, contact::Contact},
domain::{
agent::Agent, contact::Contact, count::Count, location::Location, project::Project,
unit::Unit,
},
dto::payloads::{
agent::{NewAgentPayload, UpdateAgentPayload},
location::NewLocationPayload,
@ -12,7 +15,7 @@ use jl_types::{
use sqlx::PgPool;
use uuid::Uuid;
use crate::{dao, handle_db_read_op, handle_db_write_op, handle_tx, success, unwrap_or_not_found};
use crate::{dao, handle_db_read_op, handle_db_write_op, handle_tx, success, unwrap_or_not_found, utils::s3::{Item}};
//
// Insert Methods
@ -191,4 +194,9 @@ pub async fn get_all_contacts(conn: &PgPool) -> TypedHttpResponse<Vec<Contact>>
pub async fn get_contact_count(conn: &PgPool) -> TypedHttpResponse<Count> {
let count = handle_db_read_op!(dao::contact::get_count(conn));
success!(count)
}
pub async fn upload_image(_client: &aws_sdk_s3::Client, _item: Item, _id: Uuid, _file_name: String) -> TypedHttpResponse<String> {
success!(String::new())
}

View File

@ -2,8 +2,11 @@ use std::collections::HashSet;
use actix_web_utils::extensions::typed_response::TypedHttpResponse;
use jl_types::{
domain::{agent::Agent},
dto::{filters::Filter, listing::Listing, project_card::ProjectCardDto, payloads::contact::ContactPayload},
domain::agent::Agent,
dto::{
filters::Filter, listing::Listing, payloads::contact::ContactPayload,
project_card::ProjectCardDto,
},
};
use sqlx::PgPool;
use uuid::Uuid;
@ -14,10 +17,22 @@ pub async fn get_all_agents(conn: &PgPool) -> TypedHttpResponse<Vec<Agent>> {
success!(handle_db_read_op!(dao::agent::fetch_all(conn)))
}
pub async fn get_agent_with_shortcode(
conn: &PgPool,
shortcode: &String,
) -> TypedHttpResponse<Agent> {
success!(unwrap_or_not_found!(
handle_db_read_op!(dao::agent::get_agent_with_shortcode(conn, shortcode)),
"agents"
))
}
pub async fn get_all_locations(conn: &PgPool) -> TypedHttpResponse<HashSet<String>> {
let locations: HashSet<String> = handle_db_read_op!(dao::location::fetch_all_locations(conn)).into_iter().map(|location| location.city).collect();
let locations: HashSet<String> = handle_db_read_op!(dao::location::fetch_all_locations(conn))
.into_iter()
.map(|location| location.city)
.collect();
success!(locations)
}
@ -25,9 +40,12 @@ pub async fn get_all_locations_in_city(
conn: &PgPool,
city: &String,
) -> TypedHttpResponse<HashSet<String>> {
success!(handle_db_read_op!(dao::location::get_locations_in_city(
conn, city
)).into_iter().map(|location| location.district).collect())
success!(
handle_db_read_op!(dao::location::get_locations_in_city(conn, city))
.into_iter()
.map(|location| location.district)
.collect()
)
}
pub async fn get_projects_paged(
@ -64,4 +82,4 @@ pub async fn get_project_data(conn: &PgPool, project_id: &Uuid) -> TypedHttpResp
pub async fn create_contact(conn: &PgPool, contact: ContactPayload) -> TypedHttpResponse<()> {
let _ = handle_db_read_op!(dao::contact::insert(conn, &contact.into()));
success!(())
}
}

View File

@ -1,2 +1,3 @@
pub mod macros;
pub mod visit;
pub mod s3;
pub mod visit;

53
src/utils/s3.rs Normal file
View File

@ -0,0 +1,53 @@
use std::fmt::Display;
use aws_sdk_s3::{
error::SdkError,
operation::put_object::{PutObjectError},
primitives::ByteStream,
Client,
};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
pub enum Item {
#[default]
Project,
Unit,
Agent,
}
impl Display for Item {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Item::Project => write!(f, "Project"),
Item::Unit => write!(f, "Unit"),
Item::Agent => write!(f, "Agent"),
}
}
}
pub async fn init_aws_client() -> Client {
dotenv::dotenv().expect("Failed loading env");
let config = aws_config::load_from_env().await;
Client::new(&config)
}
pub async fn upload_image(
client: &Client,
id: Uuid,
item: Item,
file_name: String,
) -> Result<String, SdkError<PutObjectError>> {
let path = format!("jl-images/{item}/{id}/{file_name}");
match client
.put_object()
.bucket("jorge-ledesma-bucket")
.key(path.clone())
.body(ByteStream::from_static("Hey there".as_bytes()))
.acl(aws_sdk_s3::types::ObjectCannedAcl::PublicRead)
.send()
.await {
Ok(_) => Ok(format!("https://jorge-ledesma-bucket.s3.us-east-2.amazonaws.com/{path}")),
Err(error) => Err(error),
}
}

View File

@ -6,15 +6,15 @@ use sqlx::PgPool;
use crate::dao;
pub fn store_visit_concurrent(db_conn: &Arc<PgPool>, request: HttpRequest) {
let ip = request.peer_addr().unwrap();
let db_conn = db_conn.clone();
tokio::spawn(async move {
match dao::visit::insert(&db_conn, &Visit::new(ip.to_string())).await {
Ok(_) => {},
Err(error) => { println!("{}", error) },
};
Ok(_) => {}
Err(error) => {
println!("{}", error)
}
};
});
}
}