moving to using a rust api

This commit is contained in:
Chris Cochrun 2024-01-08 10:51:53 -06:00
parent 2d1424aeb2
commit f00ed3a04c
12 changed files with 1044 additions and 272 deletions

431
Cargo.lock generated
View file

@ -2,30 +2,6 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "actix"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f728064aca1c318585bf4bb04ffcfac9e75e508ab4e8b1bd9ba5dfe04e2cbed5"
dependencies = [
"actix-rt",
"actix_derive",
"bitflags",
"bytes",
"crossbeam-channel",
"futures-core",
"futures-sink",
"futures-task",
"futures-util",
"log",
"once_cell",
"parking_lot",
"pin-project-lite",
"smallvec",
"tokio",
"tokio-util",
]
[[package]] [[package]]
name = "actix-codec" name = "actix-codec"
version = "0.5.1" version = "0.5.1"
@ -53,7 +29,7 @@ dependencies = [
"actix-rt", "actix-rt",
"actix-service", "actix-service",
"actix-utils", "actix-utils",
"ahash 0.8.3", "ahash 0.8.7",
"base64", "base64",
"bitflags", "bitflags",
"brotli", "brotli",
@ -94,9 +70,9 @@ dependencies = [
[[package]] [[package]]
name = "actix-multipart" name = "actix-multipart"
version = "0.6.0" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dee489e3c01eae4d1c35b03c4493f71cb40d93f66b14558feb1b1a807671cc4e" checksum = "3b960e2aea75f49c8f069108063d12a48d329fc8b60b786dfc7552a9d5918d2d"
dependencies = [ dependencies = [
"actix-multipart-derive", "actix-multipart-derive",
"actix-utils", "actix-utils",
@ -119,15 +95,15 @@ dependencies = [
[[package]] [[package]]
name = "actix-multipart-derive" name = "actix-multipart-derive"
version = "0.6.0" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ec592f234db8a253cf80531246a4407c8a70530423eea80688a6c5a44a110e7" checksum = "0a0a77f836d869f700e5b47ac7c3c8b9c8bc82e4aec861954c6198abee3ebd4d"
dependencies = [ dependencies = [
"darling", "darling",
"parse-size", "parse-size",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 1.0.109", "syn 2.0.43",
] ]
[[package]] [[package]]
@ -167,7 +143,7 @@ dependencies = [
"futures-util", "futures-util",
"mio", "mio",
"num_cpus", "num_cpus",
"socket2", "socket2 0.4.9",
"tokio", "tokio",
"tracing", "tracing",
] ]
@ -229,7 +205,7 @@ dependencies = [
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
"smallvec", "smallvec",
"socket2", "socket2 0.4.9",
"time", "time",
"url", "url",
] ]
@ -246,17 +222,6 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "actix_derive"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d44b8fee1ced9671ba043476deddef739dd0959bf77030b26b738cc591737a7"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "adler" name = "adler"
version = "1.0.2" version = "1.0.2"
@ -276,21 +241,22 @@ dependencies = [
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.3" version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"getrandom", "getrandom",
"once_cell", "once_cell",
"version_check", "version_check",
"zerocopy",
] ]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "1.0.1" version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -310,6 +276,12 @@ dependencies = [
"alloc-no-stdlib", "alloc-no-stdlib",
] ]
[[package]]
name = "allocator-api2"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
[[package]] [[package]]
name = "async-channel" name = "async-channel"
version = "1.8.0" version = "1.8.0"
@ -330,7 +302,7 @@ dependencies = [
"async-lock", "async-lock",
"async-task", "async-task",
"concurrent-queue", "concurrent-queue",
"fastrand", "fastrand 1.9.0",
"futures-lite", "futures-lite",
"slab", "slab",
] ]
@ -366,7 +338,7 @@ dependencies = [
"polling", "polling",
"rustix", "rustix",
"slab", "slab",
"socket2", "socket2 0.4.9",
"waker-fn", "waker-fn",
] ]
@ -454,7 +426,7 @@ dependencies = [
"async-lock", "async-lock",
"async-task", "async-task",
"atomic-waker", "atomic-waker",
"fastrand", "fastrand 1.9.0",
"futures-lite", "futures-lite",
"log", "log",
] ]
@ -516,6 +488,16 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chumsky"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9"
dependencies = [
"hashbrown 0.14.3",
"stacker",
]
[[package]] [[package]]
name = "concurrent-queue" name = "concurrent-queue"
version = "2.2.0" version = "2.2.0"
@ -576,21 +558,11 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "crossbeam-channel"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.15" version = "0.8.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
] ]
@ -605,21 +577,11 @@ dependencies = [
"typenum", "typenum",
] ]
[[package]]
name = "ctor"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
dependencies = [
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.14.4" version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"darling_macro", "darling_macro",
@ -627,27 +589,27 @@ dependencies = [
[[package]] [[package]]
name = "darling_core" name = "darling_core"
version = "0.14.4" version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
dependencies = [ dependencies = [
"fnv", "fnv",
"ident_case", "ident_case",
"proc-macro2", "proc-macro2",
"quote", "quote",
"strsim", "strsim",
"syn 1.0.109", "syn 2.0.43",
] ]
[[package]] [[package]]
name = "darling_macro" name = "darling_macro"
version = "0.14.4" version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
"syn 1.0.109", "syn 2.0.43",
] ]
[[package]] [[package]]
@ -673,6 +635,22 @@ dependencies = [
"crypto-common", "crypto-common",
] ]
[[package]]
name = "email-encoding"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbfb21b9878cf7a348dcb8559109aabc0ec40d69924bd706fa5149846c4fef75"
dependencies = [
"base64",
"memchr",
]
[[package]]
name = "email_address"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112"
[[package]] [[package]]
name = "encoding_rs" name = "encoding_rs"
version = "0.8.32" version = "0.8.32"
@ -731,6 +709,12 @@ dependencies = [
"instant", "instant",
] ]
[[package]]
name = "fastrand"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.26" version = "1.0.26"
@ -764,9 +748,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]] [[package]]
name = "form_urlencoded" name = "form_urlencoded"
version = "1.1.0" version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [ dependencies = [
"percent-encoding", "percent-encoding",
] ]
@ -825,7 +809,7 @@ version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
dependencies = [ dependencies = [
"fastrand", "fastrand 1.9.0",
"futures-core", "futures-core",
"futures-io", "futures-io",
"memchr", "memchr",
@ -842,7 +826,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.18", "syn 2.0.43",
] ]
[[package]] [[package]]
@ -933,6 +917,16 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
dependencies = [
"ahash 0.8.7",
"allocator-api2",
]
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.2.6" version = "0.2.6"
@ -948,6 +942,17 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
[[package]]
name = "hostname"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
dependencies = [
"libc",
"match_cfg",
"winapi",
]
[[package]] [[package]]
name = "http" name = "http"
version = "0.2.9" version = "0.2.9"
@ -1005,7 +1010,7 @@ dependencies = [
"httpdate", "httpdate",
"itoa", "itoa",
"pin-project-lite", "pin-project-lite",
"socket2", "socket2 0.4.9",
"tokio", "tokio",
"tower-service", "tower-service",
"tracing", "tracing",
@ -1033,9 +1038,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]] [[package]]
name = "idna" name = "idna"
version = "0.3.0" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [ dependencies = [
"unicode-bidi", "unicode-bidi",
"unicode-normalization", "unicode-normalization",
@ -1048,7 +1053,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"hashbrown", "hashbrown 0.12.3",
] ]
[[package]] [[package]]
@ -1135,10 +1140,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "lettre"
version = "0.2.144" version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" checksum = "f5aaf628956b6b0852e12ac3505d20d7a12ecc1e32d5ea921f002af4a74036a5"
dependencies = [
"base64",
"chumsky",
"email-encoding",
"email_address",
"fastrand 2.0.1",
"futures-util",
"hostname",
"httpdate",
"idna",
"mime",
"native-tls",
"nom",
"quoted_printable",
"socket2 0.5.5",
"tokio",
"url",
]
[[package]]
name = "libc"
version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
@ -1176,19 +1205,44 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.17" version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
dependencies = [ dependencies = [
"cfg-if",
"value-bag", "value-bag",
] ]
[[package]] [[package]]
name = "memchr" name = "markup"
version = "2.5.0" version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" checksum = "74a887ad620fe1022257343ac77fcdd3720e92888e1b2e66e1b7a4707f453898"
dependencies = [
"markup-proc-macro",
]
[[package]]
name = "markup-proc-macro"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ab6ee21fd1855134cacf2f41afdf45f1bc456c7d7f6165d763b4647062dd2be"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.43",
]
[[package]]
name = "match_cfg"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
[[package]]
name = "memchr"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]] [[package]]
name = "mime" name = "mime"
@ -1206,6 +1260,12 @@ dependencies = [
"unicase", "unicase",
] ]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.7.1" version = "0.7.1"
@ -1227,24 +1287,6 @@ dependencies = [
"windows-sys 0.45.0", "windows-sys 0.45.0",
] ]
[[package]]
name = "multer"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2"
dependencies = [
"bytes",
"encoding_rs",
"futures-util",
"http",
"httparse",
"log",
"memchr",
"mime",
"spin",
"version_check",
]
[[package]] [[package]]
name = "native-tls" name = "native-tls"
version = "0.2.11" version = "0.2.11"
@ -1263,6 +1305,16 @@ dependencies = [
"tempfile", "tempfile",
] ]
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]] [[package]]
name = "num_cpus" name = "num_cpus"
version = "1.15.0" version = "1.15.0"
@ -1275,9 +1327,9 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.17.1" version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]] [[package]]
name = "openssl" name = "openssl"
@ -1302,7 +1354,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.18", "syn 2.0.43",
] ]
[[package]] [[package]]
@ -1366,9 +1418,9 @@ checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.2.0" version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
@ -1412,22 +1464,37 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.59" version = "1.0.76"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]] [[package]]
name = "quote" name = "psm"
version = "1.0.28" version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874"
dependencies = [
"cc",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "quoted_printable"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79ec282e887b434b68c18fe5c121d38e72a5cf35119b59e54ec5b992ea9c8eb0"
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.8.5" version = "0.8.5"
@ -1478,9 +1545,21 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.8.3" version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390" checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@ -1489,9 +1568,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.7.2" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]] [[package]]
name = "reqwest" name = "reqwest"
@ -1560,6 +1639,16 @@ version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]]
name = "sanitize-filename"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ed72fbaf78e6f2d41744923916966c4fbe3d7c74e3037a8ee482f1115572603"
dependencies = [
"lazy_static",
"regex",
]
[[package]] [[package]]
name = "schannel" name = "schannel"
version = "0.1.21" version = "0.1.21"
@ -1688,10 +1777,27 @@ dependencies = [
] ]
[[package]] [[package]]
name = "spin" name = "socket2"
version = "0.9.8" 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 = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
dependencies = [
"libc",
"windows-sys 0.48.0",
]
[[package]]
name = "stacker"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce"
dependencies = [
"cc",
"cfg-if",
"libc",
"psm",
"winapi",
]
[[package]] [[package]]
name = "strsim" name = "strsim"
@ -1712,9 +1818,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.18" version = "2.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1728,7 +1834,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand 1.9.0",
"redox_syscall 0.3.5", "redox_syscall 0.3.5",
"rustix", "rustix",
"windows-sys 0.45.0", "windows-sys 0.45.0",
@ -1747,7 +1853,6 @@ dependencies = [
name = "tfcconnection" name = "tfcconnection"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"actix",
"actix-multipart", "actix-multipart",
"actix-rt", "actix-rt",
"actix-web", "actix-web",
@ -1755,10 +1860,14 @@ dependencies = [
"env_logger", "env_logger",
"futures", "futures",
"futures-util", "futures-util",
"multer", "lettre",
"log",
"markup",
"reqwest", "reqwest",
"sanitize-filename",
"serde", "serde",
"serde_json", "serde_json",
"uuid",
] ]
[[package]] [[package]]
@ -1816,7 +1925,7 @@ dependencies = [
"parking_lot", "parking_lot",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry", "signal-hook-registry",
"socket2", "socket2 0.4.9",
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
@ -1915,9 +2024,9 @@ dependencies = [
[[package]] [[package]]
name = "url" name = "url"
version = "2.3.1" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
dependencies = [ dependencies = [
"form_urlencoded", "form_urlencoded",
"idna", "idna",
@ -1925,14 +2034,16 @@ dependencies = [
] ]
[[package]] [[package]]
name = "value-bag" name = "uuid"
version = "1.0.0-alpha.9" version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560"
dependencies = [
"ctor", [[package]]
"version_check", name = "value-bag"
] version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62ce5bb364b23e66b528d03168df78b38c0f7b6fe17386928f29d5ab2e7cb2f7"
[[package]] [[package]]
name = "vcpkg" name = "vcpkg"
@ -1989,7 +2100,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.18", "syn 2.0.43",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -2023,7 +2134,7 @@ checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.18", "syn 2.0.43",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -2231,6 +2342,26 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "zerocopy"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.43",
]
[[package]] [[package]]
name = "zstd" name = "zstd"
version = "0.12.3+zstd.1.5.2" version = "0.12.3+zstd.1.5.2"
@ -2259,4 +2390,4 @@ dependencies = [
"cc", "cc",
"libc", "libc",
"pkg-config", "pkg-config",
] ]

View file

@ -6,8 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
multer = "2.1.0"
actix = "0.13.0"
actix-rt = "2.8.0" actix-rt = "2.8.0"
actix-web = "4.3.1" actix-web = "4.3.1"
env_logger = "0.10.0" env_logger = "0.10.0"
@ -15,6 +13,11 @@ reqwest = { version = "0.11.18", features = ["json", "multipart"] }
serde = "1.0.163" serde = "1.0.163"
serde_json = "1.0.96" serde_json = "1.0.96"
async-std = "1.12.0" async-std = "1.12.0"
actix-multipart = "0.6.0" actix-multipart = "0.6.1"
futures = "0.3.28" futures = "0.3.28"
futures-util = "0.3.28" futures-util = "0.3.28"
log = "0.4.20"
uuid = "1.6.1"
sanitize-filename = "0.5.0"
lettre = { version = "0.11.3", features = ["smtp-transport"] }
markup = "0.15.0"

View file

@ -7,4 +7,6 @@ sharingLinks: false
--- ---
Here you can fill out your health form in order to go to larger TFC events like ice skating, camp, SPLASH, and mission trip! If you've already filled out a form in May, then you won't need another until the next May! The current active health form is from {{< health-form-year >}} Here you can fill out your health form in order to go to larger TFC events like ice skating, camp, SPLASH, and mission trip! If you've already filled out a form in May, then you won't need another until the next May! The current active health form is from {{< health-form-year >}}
However, if you are going on mission trip, you'll need to fill this out for sure, since any you've previously filled out will have expired.
{{< health-form >}} {{< health-form >}}

View file

@ -19,7 +19,7 @@ Requirements for this team are a flexible attitude and a willingness to do hands
- Estimated Support Goal of $850-$950 - Estimated Support Goal of $850-$950
## Puerto Escondido, Mexico - *May 31 - June 9 - Highschool only ## Puerto Escondido, Mexico - *June 2 - 9 - Highschool only
This trip is designed for students who have a desire to be used by Jesus to draw others into a relationship with Him and they will be trained to go with the Gospel as His ambassadors. We will be working with the ministry of Roca Blanca Mission Base in Puerto Escondido, Mexico. There are a variety of ways to serve this ministry, we might lead a VBS, work in their orphanage, assist with village ministry, work on building projects, or possibly help deliver food or clothing. This trip is designed for students who have a desire to be used by Jesus to draw others into a relationship with Him and they will be trained to go with the Gospel as His ambassadors. We will be working with the ministry of Roca Blanca Mission Base in Puerto Escondido, Mexico. There are a variety of ways to serve this ministry, we might lead a VBS, work in their orphanage, assist with village ministry, work on building projects, or possibly help deliver food or clothing.
Requirements for this team are a willingness and desire to share the gospel of Jesus verbally, Requirements for this team are a willingness and desire to share the gospel of Jesus verbally,

View file

@ -5,11 +5,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1685518550, "lastModified": 1701680307,
"narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -20,11 +20,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1685383865, "lastModified": 1704194953,
"narHash": "sha256-3uQytfnotO6QJv3r04ajSXbEFMII0dUtw0uqYlZ4dbk=", "narHash": "sha256-RtDKd8Mynhe5CFnVT8s0/0yqtWFMM9LmCzXv/YKxnq4=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "5e871d8aa6f57cc8e0dc087d1c5013f6e212b4ce", "rev": "bd645e8668ec6612439a9ee7e71f7eac4099d4f6",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -1,2 +1,2 @@
{{ time.Format "Jan 2006" "2022-05-01" }} - {{ time.Format "Jan 2006" "2023-05-01" }} -
{{ time.Format "Jan 2006" "2023-05-01" }}. {{ time.Format "Jan 2006" "2024-05-01" }}.

View file

@ -69,8 +69,8 @@
// For use in dev // For use in dev
// Can now start using this in production IF, // Can now start using this in production IF,
// I get the server running on the server // I get the server running on the server
let base = "https://api.tfcconnection.org/health-form"; /* let base = "https://api.tfcconnection.org/health-form"; */
/* let base = "http://localhost:4242/health-form"; */ let base = "http://localhost:4242/health-form";
fetch(base, { fetch(base, {
method: "POST", method: "POST",
body: data body: data
@ -141,6 +141,18 @@
document.getElementById('warning-insurance').style.margin = '0'; document.getElementById('warning-insurance').style.margin = '0';
document.getElementById('warning-policy').style.margin = '0'; document.getElementById('warning-policy').style.margin = '0';
document.getElementById('warning-image').style.margin = '0'; document.getElementById('warning-image').style.margin = '0';
// Prefill form based from MT form
document.getElementById('firstname').value = firstName;
document.getElementById('lastname').value = lastName;
document.getElementById('parentfirstname').value = parentFirstName;
document.getElementById('parentlastname').value = parentLastName;
document.getElementById('birthdate').value = birthdate;
document.getElementById('street').value = streetP;
document.getElementById('city').value = cityP;
document.getElementById('state').value = stateP;
document.getElementById('zip').value = zipP;
document.getElementById('cellphone').value = parentPhone;
} }
document.addEventListener('DOMContentLoaded', process); document.addEventListener('DOMContentLoaded', process);
@ -169,16 +181,28 @@
}; };
document.addEventListener('DOMContentLoaded', dated); document.addEventListener('DOMContentLoaded', dated);
const myUrl = new URL(window.location.toLocaleString()); const params = new URL(window.location.toLocaleString()).searchParams;
const mtRegistration = myUrl.searchParams.get('mtregistration'); const mtRegistration = params.get('mtregistration');
const registration = myUrl.searchParams.get('registration'); const registration = params.get('registration');
const firstName = params.get('firstName');
const lastName = params.get('lastName');
const parentFirstName = params.get('parentFirstName');
const parentLastName = params.get('parentLastName');
const birthdate = params.get('birthdate');
const streetP = params.get('street');
const cityP = params.get('city');
const stateP = params.get('state');
const zipP = params.get('zip');
const parentPhone = params.get('parentPhone');
console.log(mtRegistration); console.log(mtRegistration);
</script> </script>
<div id="health-form" class="form text-lg w-full"> <div id="health-form" class="form text-lg w-full">
<form id='form' onsubmit="submitForm(event);" autocomplete="on" method="post" target="_parent" class="w-full items-center flex flex-wrap"> <form id='form' onsubmit="submitForm(event);" autocomplete="on" method="post" target="_parent" class="w-full items-center flex flex-wrap">
<h3 class="basis-full">2023-2024 Health Form</h3> <h3 class="basis-full">2024-2025 Health Form</h3>
<div class="basis-full flex flex-wrap my-4"> <div class="basis-full flex flex-wrap my-4">
<label for="firstname" class="basis-full">What is your first and last name?</label> <label for="firstname" class="basis-full">What is your first and last name?</label>
<br/> <br/>

View file

@ -21,29 +21,21 @@
}).then((res) => { }).then((res) => {
console.log(res); console.log(res);
if (res.ok) { if (res.ok) {
//var payment = document.getElementById('registration').value; var payment = document.getElementById('registration').value;
//window.location.href = '/mt-health-form?mtregistration=' + payment; window.location.href = '/mt-health-form?mtregistration=' + payment +
"&firstName=" + data.get('firstname') +
"&lastName=" + data.get('lastname') +
"&parentFirstName=" + data.get('parentfirstname') +
"&parentLastName=" + data.get('parentlastname') +
"&birthdate=" + data.get('birthdate') +
"&street=" + data.get('street') +
"&city=" + data.get('city') +
"&state=" + data.get('state') +
"&zip=" + data.get('zip') +
"&parentPhone=" + data.get('parentphone');
console.log(res); console.log(res);
} }
}); });
/* var xhr = new XMLHttpRequest();
* xhr.onreadystatechange = function() {
* if (this.readyState == 4 && this.status == 200) {
* // Logic directing where to send the user after form submission based on results.
* // This is how to send them. window.location.href = '/thankyou/';
* var payment = document.getElementById('registration').value;
* window.location.href = '/mt-health-form?mtregistration=' + payment;
* // Need to eventually get the user here: https://secure.myvanco.com/L-Z772/campaign/C-13DM3
* }
* }; */
/* xhr.open("POST", "https://n8n.tfcconnection.org/webhook/mt-application"); */
/* xhr.open("POST", "https://n8n.tfcconnection.org/webhook/mt-application");
* xhr.send(data);
* console.log(data);
* console.log("Hallo!"); */
/* return false; */
} }
function calculate_age(dob) { function calculate_age(dob) {
@ -139,8 +131,8 @@
class="flex-auto form-input {{ $formClasses }}"> class="flex-auto form-input {{ $formClasses }}">
</div> </div>
<div class="flex-auto flex flex-wrap items-center"> <div class="flex-auto flex flex-wrap items-center">
<label for="homephone" class="basis-1/4 mr-4">Parent phone</label> <label for="parentphone" class="basis-1/4 mr-4">Parent phone</label>
<input type="tel" id="homephone" name="homephone" <input type="tel" id="parentphone" name="parentphone"
class="flex-auto form-input {{ $formClasses }}"> class="flex-auto form-input {{ $formClasses }}">
</div> </div>
<div class="basis-full flex items-center"> <div class="basis-full flex items-center">

1
src/api/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod mt_form;

526
src/api/mt_form.rs Normal file
View file

@ -0,0 +1,526 @@
use std::fs;
use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
use actix_web::{post, HttpResponse};
use lettre::{
message::{header::ContentType, Attachment, MultiPart},
transport::smtp::authentication::{Credentials, Mechanism},
Message, SmtpTransport, Transport,
};
#[derive(Debug, MultipartForm, Default)]
struct MtForm {
#[multipart(rename = "firstname")]
first_name: Option<Text<String>>,
#[multipart(rename = "lastname")]
last_name: Option<Text<String>>,
#[multipart(rename = "parentfirstname")]
parent_first_name: Option<Text<String>>,
#[multipart(rename = "parentlastname")]
parent_last_name: Option<Text<String>>,
birthdate: Option<Text<String>>,
gender: Option<Text<String>>,
street: Option<Text<String>>,
city: Option<Text<String>>,
state: Option<Text<String>>,
zip: Option<Text<i32>>,
cellphone: Option<Text<String>>,
parentphone: Option<Text<String>>,
email: Option<Text<String>>,
parentemail: Option<Text<String>>,
school: Option<Text<String>>,
grade: Option<Text<String>>,
#[multipart(rename = "pastorfirstname")]
pastor_first_name: Option<Text<String>>,
#[multipart(rename = "pastorlastname")]
pastor_last_name: Option<Text<String>>,
#[multipart(rename = "churchattendance")]
church_attendance: Option<Text<String>>,
#[multipart(rename = "tfcgroup")]
tfc_group: Option<Text<String>>,
shirt: Option<Text<String>>,
trip: Option<Text<String>>,
#[multipart(rename = "tripnotes")]
trip_notes: Option<Text<String>>,
#[multipart(rename = "relationship-with-jesus")]
relationship_with_jesus: Option<Text<String>>,
#[multipart(rename = "testimony")]
testimony: Option<Text<String>>,
#[multipart(rename = "involvement-with-group")]
involvement_with_group: Option<Text<String>>,
#[multipart(rename = "reasons-for-trip-choice")]
reasons: Option<Text<String>>,
strengths: Option<Text<String>>,
weaknesses: Option<Text<String>>,
#[multipart(rename = "previous-trip-info")]
previous_trip_info: Option<Text<String>>,
#[multipart(rename = "attitude-torward-work")]
attitude: Option<Text<String>>,
#[multipart(rename = "relevant-notes")]
relevant_notes: Option<Text<String>>,
#[multipart(rename = "final-agreement")]
final_agreement: Option<Text<String>>,
registration: Option<Text<String>>,
#[multipart(rename = "image")]
file: Option<TempFile>,
}
#[post("/mt-form")]
pub async fn mt_form(MultipartForm(form): MultipartForm<MtForm>) -> HttpResponse {
let first = form.first_name.as_ref().unwrap().0.clone();
let last = form.last_name.as_ref().unwrap().0.clone();
let email_subject = format!("{} {} signed up for mission trip!", first, last);
let filename_noext = String::from(format!("{}_{}", first, last));
let parent = format!(
"{} {}",
form.parent_first_name.as_ref().unwrap().0.clone(),
form.parent_last_name.as_ref().unwrap().0.clone()
);
let birthdate = form
.birthdate
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let gender = form
.gender
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let street = form
.street
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let city = form
.city
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let state = form
.state
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let zip = form.zip.as_ref().unwrap_or(&Text { 0: 0 }).0.clone();
let cellphone = form
.cellphone
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let parentphone = form
.parentphone
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let email = form
.email
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let parentemail = form
.parentemail
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let school = form
.school
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let grade = form
.grade
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let pastor = format!(
"{} {}",
form.pastor_first_name
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone(),
form.pastor_last_name
.as_ref()
.unwrap_or(&Text {
0: String::from("")
})
.0
.clone()
);
let church_attendance = form
.church_attendance
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let tfc_group = form
.tfc_group
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let shirt = form
.shirt
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let trip = form
.trip
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let trip_notes = form
.trip_notes
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let relationship = form
.relationship_with_jesus
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let testimony = form
.testimony
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let involvement = form
.involvement_with_group
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let reasons = form
.reasons
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let strengths = form
.strengths
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let weaknesses = form
.weaknesses
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let previous_trip = form
.previous_trip_info
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let attitude = form
.attitude
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let relevant = form
.relevant_notes
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let final_agreement = form
.final_agreement
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
let registration = form
.registration
.as_ref()
.unwrap_or(&Text {
0: String::from(""),
})
.0
.clone();
log::info!("{first} {last} signed up for mission trip!");
let email = markup::new! {
@markup::doctype()
html {
head {
title { @format!("{} {} signed up for mission trip!", first, last) }
style {
"table { border-collapse: collapse; width: 100% }"
"td, th { padding: 8px }"
"td { text-align: left; width: 70%; word-wrap: break-word }"
"th { text-align: right; border-right: 1px solid #ddd }"
"tr { border-bottom: 1px solid #ddd }"
"h1 { text-align: center }"
}
}
body {
h1 { @format!("Mission trip form for {} {}!", first, last) }
hr;
table {
tr {
th { "Name" }
td { @format!("{} {}", first, last) }
}
tr {
th { "Parent" }
td { @parent }
}
tr {
th { "Birthdate" }
td { @birthdate }
}
tr {
th { "Gender" }
td { @gender }
}
tr {
th { "Street" }
td { @street }
}
tr {
th { "City" }
td { @city }
}
tr {
th { "State" }
td { @state }
}
tr {
th { "Zip" }
td { @zip }
}
tr {
th { "Phone" }
td { @cellphone }
}
tr {
th { "Parent Phone" }
td { @parentphone }
}
tr {
th { "Email" }
td { @email }
}
tr {
th { "Parent Email" }
td { @parentemail }
}
tr {
th { "School" }
td { @school }
}
tr {
th { "Grade" }
td { @grade }
}
tr {
th { "Pastor" }
td { @pastor }
}
tr {
th { "Church Attendance" }
td { @church_attendance }
}
tr {
th { "TFC Group" }
td { @tfc_group }
}
tr {
th { "T-Shirt Size" }
td { @shirt }
}
tr {
th { "Trip Choice" }
td { @trip }
}
tr {
th { "Extra Trip Notes" }
td { @trip_notes }
}
tr {
th { "Relationship with Jesus" }
td { @relationship }
}
tr {
th { "Testimony" }
td { @testimony }
}
tr {
th { "Involvement with TFC or Youth Group" }
td { @involvement }
}
tr {
th { "Reasons for trip choice" }
td { @reasons }
}
tr {
th { "Strengths" }
td { @strengths }
}
tr {
th { "Weaknesses" }
td { @weaknesses }
}
tr {
th { "Previous Trips" }
td { @previous_trip }
}
tr {
th { "Attitude Torward Work" }
td { @attitude }
}
tr {
th { "Other Relevant Info" }
td { @relevant }
}
tr {
th { "Final Agreement" }
td { @final_agreement }
}
tr {
th { "Registration" }
td { @registration }
}
}
}
}
};
let mut path: Option<String> = Some(String::from(""));
let mut file_exists = false;
log::info!("{:?}", form);
log::info!("{:?}", file_exists);
if let Some(f) = form.file {
if let Some(file) = f.file_name {
if let Some(ext) = file.rsplit(".").next() {
path = Some(format!("./tmp/{}.{}", filename_noext, ext));
} else {
path = Some(format!("./tmp/{}", file));
}
// let path = format!("./tmp/{}", file);
log::info!("saving to {}", path.clone().unwrap());
match f.file.persist(path.clone().unwrap()) {
Ok(f) => {
log::info!("{:?}", f);
if f.metadata().unwrap().len() > 0 {
file_exists = true;
}
}
Err(e) => log::info!("{:?}: Probably a missing image", e),
}
}
}
let multi = if file_exists {
let filebody = fs::read(path.clone().unwrap_or_default());
let content_type = ContentType::parse("image/jpg").unwrap();
let attachment =
Attachment::new(path.unwrap_or_default()).body(filebody.unwrap(), content_type);
log::info!("{:?}", attachment);
MultiPart::alternative_plain_html(String::from("Testing"), email.to_string())
.singlepart(attachment)
} else {
MultiPart::alternative_plain_html(String::from("Testing"), email.to_string())
};
if let Ok(m) = Message::builder()
.from(
"TFC ADMIN <no-reply@mail.tfcconnection.org>"
.parse()
.unwrap(),
)
.to("Chris Cochrun <chris@tfcconnection.org>".parse().unwrap())
.to("Ethan Rose <ethan@tfcconnection.org>".parse().unwrap())
.subject(email_subject)
.multipart(multi)
{
let sender = SmtpTransport::relay("mail.tfcconnection.org")
.ok()
.unwrap()
.credentials(Credentials::new(
"no-reply@mail.tfcconnection.org".to_owned(),
"r9f36mNZFtiW4f".to_owned(),
))
.authentication(vec![Mechanism::Plain])
.build();
match sender.send(&m) {
Ok(res) => log::info!("{:?}", res),
Err(e) => log::info!("{e}"),
}
} else {
log::info!("Email incorrect");
}
HttpResponse::Ok().body("hi")
}

View file

@ -283,32 +283,94 @@ with the image attached to us"
(uiop:println form) (uiop:println form)
(let ((first-name (cdr (assoc "firstname" form :test 'string=))) (let ((first-name (cdr (assoc "firstname" form :test 'string=)))
(last-name (cdr (assoc "lastname" form :test 'string=)))) (last-name (cdr (assoc "lastname" form :test 'string=))))
(cl-smtp:send-email (not (cl-smtp:send-email
"mail.tfcconnection.org" "mail.tfcconnection.org"
"no-reply@mail.tfcconnection.org" "no-reply@mail.tfcconnection.org"
'("chris@tfcconnection.org" "chris@cochrun.xyz") "chris@cochrun.xyz"
(format nil "~a ~a filled out a Mission Trip Form!" first-name last-name) (format nil "~a ~a filled out a Mission Trip Form!" first-name last-name)
(format nil "Mission Trip Form for ~a ~a" first-name last-name) (format nil "Mission Trip Form for ~a ~a" first-name last-name)
:display-name "TFC ADMIN" :display-name "TFC ADMIN"
:ssl :tls :ssl :tls
:authentication '(:login "no-reply@mail.tfcconnection.org" "r9f36mNZFtiW4f") :authentication '(:login "no-reply@mail.tfcconnection.org" "r9f36mNZFtiW4f")
:attachments attachment :attachments attachment
:html-message :html-message
(with-html-string (with-html-string
(:doctype) (:doctype)
(:html (:html
(:head (:title "TFC Mission Trip Form") (:head (:title "TFC Mission Trip Form")
(:style (apply #'lass:compile-and-write *mail-css*))) (:style (apply #'lass:compile-and-write *mail-css*)))
(:body (:body
(:h1 (format nil "Mission Trip Form for ~a ~a" first-name last-name)) (:h1 (format nil "Mission Trip Form for ~a ~a" first-name last-name))
(:hr) (:hr)
(:table (:table
(loop for row in form (loop for row in form
do (:tr do (:tr
(:th (car row)) (:th (trim-whitespace (car row)))
(:td (trim-whitespace (:td (trim-whitespace
(cdr row))))))))))) (cdr row)))))))))))))
(uiop:println "Mail sent!"))
(cl-smtp:send-email
"mail.tfcconnection.org"
"no-reply@mail.tfcconnection.org"
"chris@cochrun.xyz"
(format nil "~a ~a filled out a Mission Trip Form!" "Chris" "Ccohrun")
"hi"
:html-message
(let ((form '(("age" . "150")
("registration" . "later")
("final-agreement" . "yes")
("relevant-notes" . "")
("attitude-toward-work" . "")
("previous-trip-info" . "")
("weaknesses" . "")
("strengths" . "")
("reasons-for-trip-choice" . "")
("involvement-with-group" . "")
("testimony" . "")
("relationship-with-jesus" . "")
("tripnotes" . "")
("trip" . "New Mexico")
("shirt" . "small")
("tfcgroup" . "Phillipsburg")
("churchattendanceother" . "")
("churchattendance" . "yes")
("church" . "")
("pastorphone" . "9991112222")
("pastorlastname" . "The White")
("pastorfirstname" . "Gandalf")
("grade" . "sophomore")
("school" . "A cool one")
("parentemail" . "bilbosmells@braggins.xyz")
("email" . "chris@cochrun.xyz")
("parentphone" . "8889990000")
("cellphone" . "7853021664")
("zip" . "67661")
("state" . "Middle Earth")
("city" . "The Shire")
("street" . "1234 Bag End, 98 Hobbiton")
("gender" . "Male")
("birthdate" . "1873-11-23")
("parentlastname" . "Braggins")
("parentfirstname" . "Bilbo")
("lastname" . "Braggins")
("firstname" . "Frodo"))))
(with-html-string
(:doctype)
(:html
(:head (:title "TFC Mission Trip Form")
(:style (apply #'lass:compile-and-write *mail-css*)))
(:body
(:h1 (format nil "Mission Trip Form for ~a ~a" "Chris" "Ccohrun"))
(:hr)
(:table
(loop for row in form
do (:tr
(:th (trim-whitespace (car row)))
(:td (trim-whitespace
(cdr row))))))))))
:ssl :tls
:authentication '(:login "no-reply@mail.tfcconnection.org" "r9f36mNZFtiW4f")
)
(defun mail-form (form attachment) (defun mail-form (form attachment)
"Takes the form as an alist and sends a table formatted email "Takes the form as an alist and sends a table formatted email
@ -450,65 +512,70 @@ with the image attached"
((eq request-type :post) ((eq request-type :post)
(loop :for i :in parts (loop :for i :in parts
:do (let* ((content-disposition :do (let* ((content-disposition
(nth 1 (nth 1
(serapeum:lines i (serapeum:lines i
:eol-style :eol-style
:crlf :crlf
:honor-crlf t))) :honor-crlf t)))
(start (if content-disposition (start (if content-disposition
(position #\" content-disposition))) (position #\" content-disposition)))
(end (if start (end (if start
(position #\" content-disposition (position #\" content-disposition
:start (1+ start)) nil)) :start (1+ start)) nil))
(name (if end (name (if end
(if start (if start
(subseq content-disposition (subseq content-disposition
(1+ start) end) nil) nil)) (1+ start) end) nil) nil))
(content (content
(if (string= name "image") (if (string= name "image")
(butlast nil
(rest ;; (butlast
(rest ;; (rest
(rest ;; (rest
(rest ;; (rest
(serapeum:lines i ;; (rest
:eol-style ;; (serapeum:lines i
:crlf ;; :eol-style
:honor-crlf t ;; :crlf
:keep-eols t)))))) ;; :honor-crlf t
(trim-whitespace ;; :keep-eols t))))))
(car (trim-whitespace
(butlast (car
(rest (butlast
(rest (rest
(rest (rest
(serapeum:lines i :eol-style :crlf (rest
:honor-crlf t (serapeum:lines i :eol-style :crlf
:keep-eols t))))))))) :honor-crlf t
(file-start :keep-eols t)))))))))
(if (string= name "image") (file-start
(position #\" content-disposition (if (string= name "image")
:start 44))) (position #\" content-disposition
(file-end :start 44)))
(if file-start (file-end
(position #\" content-disposition (if file-start
:start (1+ file-start)) nil)) (position #\" content-disposition
(image-file-name :start (1+ file-start)) nil))
(if (string= name "image") (image-file-name
(subseq content-disposition (if (string= name "image")
(1+ file-start) file-end) nil))) (subseq content-disposition
(1+ file-start) file-end) nil)))
(if name (if name
(if (string= name "image") (if (string= name "image")
(if (uiop:file-exists-p image-file-name) (when (stringp content)
(progn (progn
(save-string-file (if (not (uiop:file-exists-p image-file-name))
(apply #'concatenate 'string content) (save-string-file
image-file-name) (apply #'concatenate 'string content)
(setq form-list (acons name image-file-name form-list)) image-file-name))
(setf attachment image-file-name))) (setf attachment image-file-name)
(delete-file image-file-name)))
(setq form-list (acons name content form-list)))))) (setq form-list (acons name content form-list))))))
(if (mail-mt-form form-list attachment) (if (mail-mt-form form-list attachment)
(format nil "thankyou")))))) (progn
(uiop:println "Mail sent")
(format nil "thankyou")))))))
(hunchentoot:define-easy-handler (respond :uri "/health-form") () (hunchentoot:define-easy-handler (respond :uri "/health-form") ()
(setf (hunchentoot:content-type*) "plain/text") (setf (hunchentoot:content-type*) "plain/text")

26
src/main.rs Normal file
View file

@ -0,0 +1,26 @@
mod api;
use actix_multipart::form::tempfile::TempFileConfig;
use actix_web::{middleware, App, HttpServer};
use api::mt_form::mt_form;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
log::info!("creating temporary upload directory");
std::fs::create_dir_all("./tmp")?;
log::info!("starting HTTP server at http://localhost:4242");
HttpServer::new(|| {
App::new()
.wrap(middleware::Logger::default())
.app_data(TempFileConfig::default().directory("./tmp"))
.service(mt_form)
})
.bind(("127.0.0.1", 4242))?
.workers(2)
.run()
.await
}