implement bare basic functionality!!!
This commit is contained in:
parent
5f9bb732b8
commit
ed87d3fb51
7 changed files with 238 additions and 13 deletions
135
Cargo.lock
generated
135
Cargo.lock
generated
|
@ -53,6 +53,21 @@ version = "0.2.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android-tzdata"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstream"
|
name = "anstream"
|
||||||
version = "0.6.15"
|
version = "0.6.15"
|
||||||
|
@ -208,7 +223,9 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"axum",
|
"axum",
|
||||||
"axum-macros",
|
"axum-macros",
|
||||||
|
"chrono",
|
||||||
"chrono-tz",
|
"chrono-tz",
|
||||||
|
"http",
|
||||||
"maud",
|
"maud",
|
||||||
"rand",
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -263,6 +280,12 @@ dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
@ -311,7 +334,13 @@ version = "0.4.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"android-tzdata",
|
||||||
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"serde",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -410,6 +439,12 @@ version = "0.9.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
|
@ -842,6 +877,29 @@ dependencies = [
|
||||||
"tower-service",
|
"tower-service",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone"
|
||||||
|
version = "0.1.61"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone-haiku"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -893,6 +951,15 @@ version = "1.0.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.70"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a"
|
||||||
|
dependencies = [
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
@ -1701,6 +1768,7 @@ dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"chrono",
|
||||||
"crc",
|
"crc",
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
"either",
|
"either",
|
||||||
|
@ -1785,6 +1853,7 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"chrono",
|
||||||
"crc",
|
"crc",
|
||||||
"digest",
|
"digest",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
|
@ -1827,6 +1896,7 @@ dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"chrono",
|
||||||
"crc",
|
"crc",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"etcetera",
|
"etcetera",
|
||||||
|
@ -1863,6 +1933,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680"
|
checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
|
"chrono",
|
||||||
"flume",
|
"flume",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
@ -2256,6 +2327,61 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
|
checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.93"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.93"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.93"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.93"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.93"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-roots"
|
name = "webpki-roots"
|
||||||
version = "0.26.6"
|
version = "0.26.6"
|
||||||
|
@ -2297,6 +2423,15 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
|
|
|
@ -4,11 +4,13 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
http = "1"
|
||||||
axum = { version = "0.7.5", features = [ "json", "macros" ] }
|
axum = { version = "0.7.5", features = [ "json", "macros" ] }
|
||||||
axum-macros = "0.4.1"
|
axum-macros = "0.4.1"
|
||||||
|
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" ] }
|
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"
|
tokio-tungstenite = "0.24.0"
|
||||||
serde = { version = "1", features = [ "derive" ] }
|
serde = { version = "1", features = [ "derive" ] }
|
||||||
|
|
|
@ -10,8 +10,10 @@ create table chats (
|
||||||
|
|
||||||
create table messages (
|
create table messages (
|
||||||
id uuid default (gen_random_uuid()) primary key,
|
id uuid default (gen_random_uuid()) primary key,
|
||||||
timestamp timestamptz default (now()),
|
timestamp timestamptz not null default (now()),
|
||||||
chat_id uuid not null references chats(id),
|
chat_id uuid not null references chats(id),
|
||||||
content varchar(2000) not null,
|
content varchar(2000) not null,
|
||||||
from_admin boolean not null
|
from_admin boolean not null
|
||||||
)
|
);
|
||||||
|
|
||||||
|
insert into chats (url_path) values ('tstcht');
|
||||||
|
|
|
@ -1,18 +1,28 @@
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Path, State},
|
extract::{FromRef, Path, State},
|
||||||
response::Html,
|
http::{
|
||||||
Json,
|
header::{ACCEPT, CONTENT_TYPE},
|
||||||
|
HeaderMap, HeaderValue, StatusCode,
|
||||||
|
},
|
||||||
|
response::{Html, IntoResponse, Redirect},
|
||||||
|
Form, Json,
|
||||||
};
|
};
|
||||||
use maud::{html, Render};
|
use maud::{html, Render};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{Pool, Postgres};
|
use sqlx::{Pool, Postgres};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::model::{Chat, Message};
|
use crate::{
|
||||||
|
model::{Chat, Message},
|
||||||
|
ADMIN_TOK,
|
||||||
|
};
|
||||||
|
|
||||||
pub async fn get(
|
pub async fn get(
|
||||||
Path(url_path): Path<String>,
|
Path(url_path): Path<String>,
|
||||||
|
headers: HeaderMap,
|
||||||
State(pool): State<Pool<Postgres>>,
|
State(pool): State<Pool<Postgres>>,
|
||||||
) -> Json<Vec<Message>> {
|
) -> impl IntoResponse {
|
||||||
|
println!("headers: {headers:#?}");
|
||||||
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(&pool)
|
||||||
.await
|
.await
|
||||||
|
@ -25,5 +35,74 @@ pub async fn get(
|
||||||
.fetch_all(&pool)
|
.fetch_all(&pool)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Json(messages)
|
|
||||||
|
if Some(&HeaderValue::from_static("application/json")) == headers.get(ACCEPT) {
|
||||||
|
Json(messages).into_response()
|
||||||
|
} else {
|
||||||
|
Html(
|
||||||
|
html! {
|
||||||
|
main {
|
||||||
|
div #history {
|
||||||
|
@for msg in &messages {
|
||||||
|
div.message.(if msg.from_admin { "from_admin" } else { "from_user" }) {
|
||||||
|
p { (msg.content) "(" (msg.timestamp) ")" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
form #send method="post"{
|
||||||
|
textarea #msgcontent name="msgcontent" rows="1" cols="80" {}
|
||||||
|
button type="submit" { "Send!" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.into_string(),
|
||||||
|
)
|
||||||
|
.into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// - validation of msg length
|
||||||
|
// - fix terrible returns lmao
|
||||||
|
pub async fn post(
|
||||||
|
Path(url_path): Path<String>,
|
||||||
|
headers: HeaderMap,
|
||||||
|
State(pool): State<Pool<Postgres>>,
|
||||||
|
Form(FormMessageBody { msgcontent: body }): Form<FormMessageBody>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let chat = sqlx::query_as!(Chat, r#"select * from chats where url_path = $1"#, url_path)
|
||||||
|
.fetch_one(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if body.len() > 2000 {
|
||||||
|
return StatusCode::BAD_REQUEST.into_response();
|
||||||
|
}
|
||||||
|
|
||||||
|
if headers.get("x-admin-tok") == Some(&HeaderValue::from_static(ADMIN_TOK)) {
|
||||||
|
sqlx::query!(
|
||||||
|
r#"insert into messages (chat_id, content, from_admin) values ($1, $2, true);"#,
|
||||||
|
chat.id,
|
||||||
|
body
|
||||||
|
)
|
||||||
|
.execute(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
StatusCode::OK.into_response()
|
||||||
|
} else {
|
||||||
|
sqlx::query!(
|
||||||
|
r#"insert into messages (chat_id, content, from_admin) values ($1, $2, false);"#,
|
||||||
|
chat.id,
|
||||||
|
body
|
||||||
|
)
|
||||||
|
.execute(&pool)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
Redirect::to(&format!("/{url_path}")).into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct FormMessageBody {
|
||||||
|
msgcontent: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
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))
|
.route("/:path", get(chat::get).post(chat::post))
|
||||||
.with_state(pool.clone())
|
.with_state(pool.clone())
|
||||||
.nest("/stat", stat::router(pool.clone()))
|
.nest("/stat", stat::router(pool.clone()))
|
||||||
.nest("/admin", admin::router(pool.clone()));
|
.nest("/admin", admin::router(pool.clone()));
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use chrono::{DateTime, FixedOffset, Local, Utc};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use sqlx::{prelude::FromRow, Decode, Encode};
|
use sqlx::{prelude::FromRow, Decode, Encode};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -15,6 +16,7 @@ pub struct Message {
|
||||||
// Uuid but sqlx doesnt impl serde traits for them
|
// Uuid but sqlx doesnt impl serde traits for them
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub chat_id: Uuid,
|
pub chat_id: Uuid,
|
||||||
|
pub timestamp: DateTime<Utc>,
|
||||||
|
|
||||||
pub content: String,
|
pub content: String,
|
||||||
pub from_admin: bool,
|
pub from_admin: bool,
|
||||||
|
|
5
justfile
Normal file
5
justfile
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[no-cd]
|
||||||
|
reset-db:
|
||||||
|
#!/usr/bin/env nu
|
||||||
|
cd crates/backend
|
||||||
|
sqlx database reset
|
Loading…
Reference in a new issue