get this to work a slight bit more
This commit is contained in:
parent
ed87d3fb51
commit
5160929958
10 changed files with 484 additions and 108 deletions
302
Cargo.lock
generated
302
Cargo.lock
generated
|
@ -4,9 +4,9 @@ version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
version = "0.24.1"
|
version = "0.24.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375"
|
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gimli",
|
"gimli",
|
||||||
]
|
]
|
||||||
|
@ -145,19 +145,20 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.3.0"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum"
|
name = "axum"
|
||||||
version = "0.7.6"
|
version = "0.7.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f43644eed690f5374f1af436ecd6aea01cd201f6fbdf0178adaf6907afb2cec"
|
checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum-core",
|
"axum-core",
|
||||||
"axum-macros",
|
"axum-macros",
|
||||||
|
"base64",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http",
|
||||||
|
@ -176,8 +177,10 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_path_to_error",
|
"serde_path_to_error",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
|
"sha1",
|
||||||
"sync_wrapper 1.0.1",
|
"sync_wrapper 1.0.1",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-tungstenite",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
|
@ -186,9 +189,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum-core"
|
name = "axum-core"
|
||||||
version = "0.4.4"
|
version = "0.4.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e6b8ba012a258d63c9adfa28b9ddcf66149da6f986c5b5452e629d5ee64bf00"
|
checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -216,6 +219,16 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "axum_static"
|
||||||
|
version = "1.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d134d2aeabd596bc82e44748f999c9b0e535a7b756cb36c62df0de6d2445d6e"
|
||||||
|
dependencies = [
|
||||||
|
"axum",
|
||||||
|
"tower-http",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backend"
|
name = "backend"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -223,15 +236,19 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"axum",
|
"axum",
|
||||||
"axum-macros",
|
"axum-macros",
|
||||||
|
"axum_static",
|
||||||
"chrono",
|
"chrono",
|
||||||
"chrono-tz",
|
"chrono-tz",
|
||||||
|
"dashmap",
|
||||||
"http",
|
"http",
|
||||||
"maud",
|
"maud",
|
||||||
"rand",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-tungstenite",
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -315,9 +332,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.1.21"
|
version = "1.1.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0"
|
checksum = "677207f6eaec43fcfd092a718c847fc38aa261d0e19b8ef6797e0ccbe789e738"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
@ -366,9 +383,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.18"
|
version = "4.5.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3"
|
checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
|
@ -376,9 +393,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.18"
|
version = "4.5.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b"
|
checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
|
@ -519,6 +536,20 @@ dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dashmap"
|
||||||
|
version = "6.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"hashbrown 0.14.5",
|
||||||
|
"lock_api",
|
||||||
|
"once_cell",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "data-encoding"
|
name = "data-encoding"
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
|
@ -635,9 +666,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
|
@ -645,15 +676,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-executor"
|
name = "futures-executor"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
|
@ -673,27 +704,27 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-io"
|
name = "futures-io"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-util"
|
name = "futures-util"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-io",
|
"futures-io",
|
||||||
|
@ -728,9 +759,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.31.0"
|
version = "0.31.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
|
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
|
@ -742,13 +773,19 @@ dependencies = [
|
||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashlink"
|
name = "hashlink"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
|
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown",
|
"hashbrown 0.14.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -831,10 +868,16 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httparse"
|
name = "http-range-header"
|
||||||
version = "1.9.4"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
|
checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httparse"
|
||||||
|
version = "1.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httpdate"
|
name = "httpdate"
|
||||||
|
@ -912,12 +955,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.5.0"
|
version = "2.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
|
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown 0.15.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1020,7 +1063,7 @@ version = "0.12.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904"
|
checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown",
|
"hashbrown 0.14.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1073,6 +1116,16 @@ version = "0.3.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime_guess"
|
||||||
|
version = "2.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
|
||||||
|
dependencies = [
|
||||||
|
"mime",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "minimal-lexical"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
@ -1111,6 +1164,16 @@ dependencies = [
|
||||||
"minimal-lexical",
|
"minimal-lexical",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nu-ansi-term"
|
||||||
|
version = "0.46.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||||
|
dependencies = [
|
||||||
|
"overload",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-bigint-dig"
|
name = "num-bigint-dig"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
|
@ -1160,18 +1223,24 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.36.4"
|
version = "0.36.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
|
checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.19.0"
|
version = "1.20.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "overload"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking"
|
name = "parking"
|
||||||
|
@ -1412,18 +1481,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.6"
|
version = "0.5.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b"
|
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.10.6"
|
version = "1.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
|
checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
@ -1433,9 +1502,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.4.7"
|
version = "0.4.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
|
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
@ -1444,9 +1513,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.8.4"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
|
@ -1504,9 +1573,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.23.13"
|
version = "0.23.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8"
|
checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"ring",
|
"ring",
|
||||||
|
@ -1518,19 +1587,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pemfile"
|
name = "rustls-pemfile"
|
||||||
version = "2.1.3"
|
version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425"
|
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pki-types"
|
name = "rustls-pki-types"
|
||||||
version = "1.8.0"
|
version = "1.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
|
checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
|
@ -1637,6 +1705,15 @@ dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sharded-slab"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
@ -1778,7 +1855,7 @@ dependencies = [
|
||||||
"futures-intrusive",
|
"futures-intrusive",
|
||||||
"futures-io",
|
"futures-io",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"hashbrown",
|
"hashbrown 0.14.5",
|
||||||
"hashlink",
|
"hashlink",
|
||||||
"hex",
|
"hex",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
|
@ -2004,9 +2081,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.77"
|
version = "2.0.79"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
|
checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2027,9 +2104,9 @@ checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.12.0"
|
version = "3.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
|
checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"fastrand",
|
"fastrand",
|
||||||
|
@ -2058,6 +2135,16 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinyvec"
|
name = "tinyvec"
|
||||||
version = "1.8.0"
|
version = "1.8.0"
|
||||||
|
@ -2125,6 +2212,19 @@ dependencies = [
|
||||||
"tungstenite",
|
"tungstenite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-util"
|
||||||
|
version = "0.7.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower"
|
name = "tower"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
@ -2141,6 +2241,31 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-http"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"bytes",
|
||||||
|
"futures-util",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"http-body-util",
|
||||||
|
"http-range-header",
|
||||||
|
"httpdate",
|
||||||
|
"mime",
|
||||||
|
"mime_guess",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-layer"
|
name = "tower-layer"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
|
@ -2183,6 +2308,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"valuable",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-log"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-subscriber"
|
||||||
|
version = "0.3.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||||
|
dependencies = [
|
||||||
|
"nu-ansi-term",
|
||||||
|
"sharded-slab",
|
||||||
|
"smallvec",
|
||||||
|
"thread_local",
|
||||||
|
"tracing-core",
|
||||||
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2210,10 +2361,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicase"
|
||||||
version = "0.3.15"
|
version = "2.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
|
||||||
|
dependencies = [
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-bidi"
|
||||||
|
version = "0.3.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
|
@ -2232,9 +2392,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-properties"
|
name = "unicode-properties"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524"
|
checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
|
@ -2303,6 +2463,12 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "valuable"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
|
|
@ -5,15 +5,19 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
http = "1"
|
http = "1"
|
||||||
axum = { version = "0.7.5", features = [ "json", "macros" ] }
|
axum = { version = "0.7.5", features = [ "json", "macros", "ws" ] }
|
||||||
axum-macros = "0.4.1"
|
axum-macros = "0.4.1"
|
||||||
chrono = { version = "0.4", features = [ "serde" ] }
|
chrono = { version = "0.4", features = [ "serde" ] }
|
||||||
chrono-tz = "0.10.0"
|
chrono-tz = "0.10.0"
|
||||||
maud = "0.26.0"
|
maud = "0.26.0"
|
||||||
sqlx = { version = "0.8.2", features = [ "postgres", "runtime-tokio", "tls-rustls-ring", "uuid", "chrono" ] }
|
sqlx = { version = "0.8.2", features = [ "postgres", "runtime-tokio", "tls-rustls-ring", "uuid", "chrono" ] }
|
||||||
tokio = { version = "1.40.0", features = [ "full" ] }
|
tokio = { version = "1.40.0", features = [ "full" ] }
|
||||||
tokio-tungstenite = "0.24.0"
|
dashmap = "6"
|
||||||
serde = { version = "1", features = [ "derive" ] }
|
serde = { version = "1", features = [ "derive" ] }
|
||||||
|
thiserror = "1"
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
uuid = { version = "1.10.0", features = [ "serde" ] }
|
uuid = { version = "1.10.0", features = [ "serde" ] }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
tracing = "0.1.40"
|
||||||
|
tracing-subscriber = "0.3.18"
|
||||||
|
axum_static = "1.7.1"
|
||||||
|
|
|
@ -6,15 +6,15 @@ use axum::{
|
||||||
use rand::distributions::{Alphanumeric, DistString};
|
use rand::distributions::{Alphanumeric, DistString};
|
||||||
use sqlx::{Pool, Postgres, QueryBuilder};
|
use sqlx::{Pool, Postgres, QueryBuilder};
|
||||||
|
|
||||||
use crate::model::Chat;
|
use crate::{model::Chat, state::AppState};
|
||||||
|
|
||||||
pub fn router(pool: Pool<Postgres>) -> Router {
|
pub fn router(state: AppState) -> Router {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/new/:amount", get(create))
|
.route("/new/:amount", get(create))
|
||||||
.with_state(pool)
|
.with_state(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create(Path(amount): Path<u8>, State(pool): State<Pool<Postgres>>) -> Json<Vec<Chat>> {
|
async fn create(Path(amount): Path<u8>, State(state): State<AppState>) -> Json<Vec<Chat>> {
|
||||||
let paths: Vec<String> = (0..amount)
|
let paths: Vec<String> = (0..amount)
|
||||||
.map(|_| Alphanumeric.sample_string(&mut rand::thread_rng(), 6))
|
.map(|_| Alphanumeric.sample_string(&mut rand::thread_rng(), 6))
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -25,7 +25,7 @@ async fn create(Path(amount): Path<u8>, State(pool): State<Pool<Postgres>>) -> J
|
||||||
})
|
})
|
||||||
.push("returning *")
|
.push("returning *")
|
||||||
.build_query_as()
|
.build_query_as()
|
||||||
.fetch_all(&pool)
|
.fetch_all(state.pool())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
|
@ -10,42 +10,55 @@ use axum::{
|
||||||
use maud::{html, Render};
|
use maud::{html, Render};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{Pool, Postgres};
|
use sqlx::{Pool, Postgres};
|
||||||
|
use tracing::error;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
markup_response::{simple_error_page, MarkupResponse},
|
||||||
model::{Chat, Message},
|
model::{Chat, Message},
|
||||||
|
state::AppState,
|
||||||
ADMIN_TOK,
|
ADMIN_TOK,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub async fn get(
|
pub async fn get(
|
||||||
Path(url_path): Path<String>,
|
Path(url_path): Path<String>,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
State(pool): State<Pool<Postgres>>,
|
State(state): State<AppState>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
println!("headers: {headers:#?}");
|
println!("headers: {headers:#?}");
|
||||||
let chat = sqlx::query_as!(Chat, r#"select * from chats where url_path = $1"#, url_path)
|
// TODO: Error handling
|
||||||
.fetch_one(&pool)
|
let chat = match state.fetch_chat_by_url_path(&url_path).await {
|
||||||
.await
|
Ok(v) => v,
|
||||||
.unwrap();
|
Err(err) => {
|
||||||
let messages = sqlx::query_as!(
|
error!("Error fetching chat: {err:?}");
|
||||||
Message,
|
return simple_error_page(err.into()).into_response();
|
||||||
r#"select * from messages where chat_id = $1"#,
|
}
|
||||||
chat.id
|
};
|
||||||
)
|
let messages = match state.fetch_messages(&chat).await {
|
||||||
.fetch_all(&pool)
|
Ok(v) => v,
|
||||||
.await
|
Err(err) => {
|
||||||
.unwrap();
|
error!("Error fetching messages for chat {}: {err:?}", chat.id);
|
||||||
|
return simple_error_page(err.into()).into_response();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if Some(&HeaderValue::from_static("application/json")) == headers.get(ACCEPT) {
|
if Some(&HeaderValue::from_static("application/json")) == headers.get(ACCEPT) {
|
||||||
Json(messages).into_response()
|
Json(messages).into_response()
|
||||||
} else {
|
} else {
|
||||||
Html(
|
MarkupResponse::new(
|
||||||
html! {
|
html! {
|
||||||
|
template #chatmessage {
|
||||||
|
div.message {
|
||||||
|
p { }
|
||||||
|
span.timestamp { }
|
||||||
|
}
|
||||||
|
}
|
||||||
main {
|
main {
|
||||||
div #history {
|
div #history {
|
||||||
@for msg in &messages {
|
@for msg in &messages {
|
||||||
div.message.(if msg.from_admin { "from_admin" } else { "from_user" }) {
|
div.message.(if msg.from_admin { "from_admin" } else { "from_user" }) #(msg.id) {
|
||||||
p { (msg.content) "(" (msg.timestamp) ")" }
|
p { (msg.content) }
|
||||||
|
span.timestamp { (msg.timestamp) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,24 +67,45 @@ pub async fn get(
|
||||||
button type="submit" { "Send!" }
|
button type="submit" { "Send!" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
script src="/static/chat.js" {};
|
||||||
.into_string(),
|
|
||||||
|
},
|
||||||
|
"Cursed Messenger from hell",
|
||||||
)
|
)
|
||||||
.into_response()
|
.into_response()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn poll(Path(message): Path<Uuid>, State(state): State<AppState>) -> impl IntoResponse {
|
||||||
|
let message = sqlx::query_as!(Message, r#"select * from messages where id = $1"#, message)
|
||||||
|
.fetch_one(state.pool())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let new_messages = sqlx::query_as!(
|
||||||
|
Message,
|
||||||
|
r#"select * from messages where chat_id = $1 and timestamp > $2;"#,
|
||||||
|
message.chat_id,
|
||||||
|
message.timestamp
|
||||||
|
)
|
||||||
|
.fetch_all(state.pool())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Json(new_messages)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - validation of msg length
|
// - validation of msg length
|
||||||
// - fix terrible returns lmao
|
// - fix terrible returns lmao
|
||||||
pub async fn post(
|
pub async fn post(
|
||||||
Path(url_path): Path<String>,
|
Path(url_path): Path<String>,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
State(pool): State<Pool<Postgres>>,
|
State(state): State<AppState>,
|
||||||
Form(FormMessageBody { msgcontent: body }): Form<FormMessageBody>,
|
Form(FormMessageBody { msgcontent: body }): Form<FormMessageBody>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let chat = sqlx::query_as!(Chat, r#"select * from chats where url_path = $1"#, url_path)
|
let chat = sqlx::query_as!(Chat, r#"select * from chats where url_path = $1"#, url_path)
|
||||||
.fetch_one(&pool)
|
.fetch_one(state.pool())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -85,7 +119,7 @@ pub async fn post(
|
||||||
chat.id,
|
chat.id,
|
||||||
body
|
body
|
||||||
)
|
)
|
||||||
.execute(&pool)
|
.execute(state.pool())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
StatusCode::OK.into_response()
|
StatusCode::OK.into_response()
|
||||||
|
@ -95,7 +129,7 @@ pub async fn post(
|
||||||
chat.id,
|
chat.id,
|
||||||
body
|
body
|
||||||
)
|
)
|
||||||
.execute(&pool)
|
.execute(state.pool())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Redirect::to(&format!("/{url_path}")).into_response()
|
Redirect::to(&format!("/{url_path}")).into_response()
|
||||||
|
|
|
@ -1,26 +1,36 @@
|
||||||
use axum::{routing::get, Router};
|
use axum::{routing::get, Router};
|
||||||
use sqlx::{Pool, Postgres};
|
use sqlx::{Pool, Postgres};
|
||||||
|
use state::AppState;
|
||||||
|
use tracing::Level;
|
||||||
|
use tracing_subscriber::FmtSubscriber;
|
||||||
|
|
||||||
const DB_URL: &str = "postgres://localhost/chatdings";
|
|
||||||
const ADMIN_TOK: &str = "meow";
|
const ADMIN_TOK: &str = "meow";
|
||||||
|
|
||||||
mod admin;
|
mod admin;
|
||||||
mod chat;
|
mod chat;
|
||||||
|
mod markup_response;
|
||||||
mod model;
|
mod model;
|
||||||
mod stat;
|
mod stat;
|
||||||
|
mod state;
|
||||||
|
mod ws;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
let pool = Pool::<Postgres>::connect(DB_URL).await?;
|
let subscriber = FmtSubscriber::builder()
|
||||||
|
.with_max_level(Level::TRACE)
|
||||||
|
.finish();
|
||||||
|
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
|
||||||
|
|
||||||
sqlx::migrate!().run(&pool).await?;
|
let state = AppState::init().await?;
|
||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(|| async { "<h1>gay</h1>" }))
|
.route("/", get(|| async { "<h1>gay</h1>" }))
|
||||||
.route("/:path", get(chat::get).post(chat::post))
|
.route("/:path", get(chat::get).post(chat::post))
|
||||||
.with_state(pool.clone())
|
.route("/poll/:msg", get(chat::poll))
|
||||||
.nest("/stat", stat::router(pool.clone()))
|
.with_state(state.clone())
|
||||||
.nest("/admin", admin::router(pool.clone()));
|
.nest("/stat", stat::router(state.clone()))
|
||||||
|
.nest("/admin", admin::router(state.clone()))
|
||||||
|
.nest("/static", axum_static::static_router("static"));
|
||||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
|
||||||
axum::serve(listener, app).await?;
|
axum::serve(listener, app).await?;
|
||||||
|
|
||||||
|
|
47
crates/backend/src/markup_response.rs
Normal file
47
crates/backend/src/markup_response.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
use axum::response::{Html, IntoResponse};
|
||||||
|
use http::StatusCode;
|
||||||
|
use maud::{html, Markup, DOCTYPE};
|
||||||
|
|
||||||
|
pub struct MarkupResponse {
|
||||||
|
title: String,
|
||||||
|
body: Markup,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MarkupResponse {
|
||||||
|
pub fn new(body: Markup, title: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
title: title.to_owned(),
|
||||||
|
body,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoResponse for MarkupResponse {
|
||||||
|
fn into_response(self) -> axum::response::Response {
|
||||||
|
Html::from(base_page(&self.title, &self.body).into_string()).into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn base_page(title: &str, markup: &Markup) -> Markup {
|
||||||
|
html! {
|
||||||
|
(DOCTYPE)
|
||||||
|
html lang="en" {
|
||||||
|
head {
|
||||||
|
meta charset="utf-8";
|
||||||
|
meta name="viewport" content="width=device-width, initial-scale=1";
|
||||||
|
title { (title) }
|
||||||
|
// link rel="stylesheet" href="/style";
|
||||||
|
}
|
||||||
|
body { (markup) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn simple_error_page(status: StatusCode) -> MarkupResponse {
|
||||||
|
MarkupResponse::new(
|
||||||
|
html! {
|
||||||
|
img src=(format!("https://http.cat/{}", status.as_u16()));
|
||||||
|
},
|
||||||
|
"Error",
|
||||||
|
)
|
||||||
|
}
|
|
@ -3,16 +3,16 @@ use std::sync::Arc;
|
||||||
use axum::{extract::State, routing::get, Json, Router};
|
use axum::{extract::State, routing::get, Json, Router};
|
||||||
use sqlx::{types::Uuid, Pool, Postgres};
|
use sqlx::{types::Uuid, Pool, Postgres};
|
||||||
|
|
||||||
use crate::model::Chat;
|
use crate::{model::Chat, state::AppState};
|
||||||
|
|
||||||
// TODO: /stat/* should require authentication
|
// TODO: /stat/* should require authentication
|
||||||
pub fn router(pool: Pool<Postgres>) -> Router {
|
pub fn router(state: AppState) -> Router {
|
||||||
Router::new().route("/chats", get(chats)).with_state(pool)
|
Router::new().route("/chats", get(chats)).with_state(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn chats(State(pool): State<Pool<Postgres>>) -> Json<Vec<Chat>> {
|
async fn chats(State(state): State<AppState>) -> Json<Vec<Chat>> {
|
||||||
let r = sqlx::query_as!(Chat, "select * from chats;")
|
let r = sqlx::query_as!(Chat, "select * from chats;")
|
||||||
.fetch_all(&pool)
|
.fetch_all(state.pool())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
74
crates/backend/src/state.rs
Normal file
74
crates/backend/src/state.rs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
use axum::response::IntoResponse;
|
||||||
|
use http::StatusCode;
|
||||||
|
use sqlx::{Pool, Postgres};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
use crate::model::{Chat, Message};
|
||||||
|
|
||||||
|
type Result<T> = std::result::Result<T, AppStateError>;
|
||||||
|
const DB_URL: &str = "postgres://localhost/chatdings";
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct AppState {
|
||||||
|
pool: Pool<Postgres>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppState {
|
||||||
|
pub async fn init() -> Result<Self> {
|
||||||
|
let pool = Pool::<Postgres>::connect(DB_URL).await?;
|
||||||
|
|
||||||
|
sqlx::migrate!()
|
||||||
|
.run(&pool)
|
||||||
|
.await
|
||||||
|
.expect("migration should not fail");
|
||||||
|
|
||||||
|
Ok(Self { pool })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn fetch_chat_by_url_path(&self, url_path: &str) -> Result<Chat> {
|
||||||
|
Ok(
|
||||||
|
sqlx::query_as!(Chat, r#"select * from chats where url_path = $1"#, url_path)
|
||||||
|
.fetch_one(&self.pool)
|
||||||
|
.await?,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn fetch_messages(&self, chat: &Chat) -> Result<Vec<Message>> {
|
||||||
|
Ok(sqlx::query_as!(
|
||||||
|
Message,
|
||||||
|
r#"select * from messages where chat_id = $1"#,
|
||||||
|
chat.id
|
||||||
|
)
|
||||||
|
.fetch_all(&self.pool)
|
||||||
|
.await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_message(&self, chat: &Chat, content: String, from_admin: bool) -> Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pool(&self) -> &Pool<Postgres> {
|
||||||
|
&self.pool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum AppStateError {
|
||||||
|
#[error("database error")]
|
||||||
|
Sqlx(#[from] sqlx::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoResponse for AppStateError {
|
||||||
|
fn into_response(self) -> axum::response::Response {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AppStateError> for StatusCode {
|
||||||
|
fn from(value: AppStateError) -> Self {
|
||||||
|
match value {
|
||||||
|
AppStateError::Sqlx(sqlx::Error::RowNotFound) => Self::NOT_FOUND,
|
||||||
|
AppStateError::Sqlx(_) => Self::INTERNAL_SERVER_ERROR,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
crates/backend/src/ws.rs
Normal file
15
crates/backend/src/ws.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
use axum::{
|
||||||
|
extract::{ws::WebSocket, Path, State, WebSocketUpgrade},
|
||||||
|
response::Response,
|
||||||
|
};
|
||||||
|
use sqlx::{Pool, Postgres};
|
||||||
|
|
||||||
|
fn get(
|
||||||
|
Path(url_path): Path<String>,
|
||||||
|
ws: WebSocketUpgrade,
|
||||||
|
State(pool): State<Pool<Postgres>>,
|
||||||
|
) -> Response {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn handle_socket(socket: WebSocket, pool: Pool<Postgres>)
|
26
static/chat.js
Normal file
26
static/chat.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
init_polling();
|
||||||
|
|
||||||
|
// terrible hack. uses polling.
|
||||||
|
function init_polling() {
|
||||||
|
let history_el = document.getElementById("history");
|
||||||
|
let msg_template = document.querySelector("#chatmessage");
|
||||||
|
setInterval(() => {
|
||||||
|
let messages = document.getElementsByClassName("message");
|
||||||
|
let last_msg_uuid = messages[messages.length - 1].id;
|
||||||
|
fetch(`/poll/${last_msg_uuid}`)
|
||||||
|
.then(data => data.text().then(bleh => {
|
||||||
|
let new_messages = JSON.parse(bleh);
|
||||||
|
for (const message of new_messages) {
|
||||||
|
const clone = msg_template.content.cloneNode(true);
|
||||||
|
let msgclone = clone.querySelector("div");
|
||||||
|
msgclone.id = message.id;
|
||||||
|
msgclone.classList.add(message.from_admin ? "from_admin" : "from_user");
|
||||||
|
let content = msgclone.querySelector("p");
|
||||||
|
content.textContent = message.content;
|
||||||
|
let ts = msgclone.querySelector(".timestamp");
|
||||||
|
ts.textContent = message.timestamp;
|
||||||
|
history_el.appendChild(msgclone);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}, 5000)
|
||||||
|
}
|
Loading…
Reference in a new issue