Some minor restructuring and improvements
This commit is contained in:
96
Cargo.lock
generated
96
Cargo.lock
generated
@@ -152,6 +152,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
|
"common",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
"diesel_async_migrations",
|
"diesel_async_migrations",
|
||||||
@@ -287,6 +288,13 @@ version = "1.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "186dce98367766de751c42c4f03970fc60fc012296e706ccbb9d5df9b6c1e271"
|
checksum = "186dce98367766de751c42c4f03970fc60fc012296e706ccbb9d5df9b6c1e271"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "common"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "config"
|
name = "config"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
@@ -631,8 +639,11 @@ dependencies = [
|
|||||||
name = "frontend"
|
name = "frontend"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"common",
|
||||||
"leptos",
|
"leptos",
|
||||||
|
"leptos_router",
|
||||||
"reqwasm",
|
"reqwasm",
|
||||||
|
"stylers",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1235,6 +1246,32 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leptos_router"
|
||||||
|
version = "0.6.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5006e35b7c768905286dbea0d3525396cd39d961cb7b9fb664aa00b0c984ae6"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"gloo-net 0.6.0",
|
||||||
|
"itertools",
|
||||||
|
"js-sys",
|
||||||
|
"lazy_static",
|
||||||
|
"leptos",
|
||||||
|
"linear-map",
|
||||||
|
"once_cell",
|
||||||
|
"percent-encoding",
|
||||||
|
"send_wrapper",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_qs 0.13.0",
|
||||||
|
"thiserror",
|
||||||
|
"tracing",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leptos_server"
|
name = "leptos_server"
|
||||||
version = "0.6.14"
|
version = "0.6.14"
|
||||||
@@ -1251,18 +1288,43 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "levenshtein"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.158"
|
version = "0.2.158"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linear-map"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bfae20f6b19ad527b550c223fddc3077a547fc70cda94b9b566575423fd303ee"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_test",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.4.14"
|
version = "0.4.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "litrs"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
@@ -2071,6 +2133,17 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_qs"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd34f36fe4c5ba9654417139a9b3a20d2e1de6012ee678ad14d240c22c78d8d6"
|
||||||
|
dependencies = [
|
||||||
|
"percent-encoding",
|
||||||
|
"serde",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_spanned"
|
name = "serde_spanned"
|
||||||
version = "0.6.7"
|
version = "0.6.7"
|
||||||
@@ -2080,6 +2153,15 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_test"
|
||||||
|
version = "1.0.177"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f901ee573cab6b3060453d2d5f0bae4e6d628c23c0a962ff9b5f1d7c8d4f1ed"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_urlencoded"
|
name = "serde_urlencoded"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@@ -2110,7 +2192,7 @@ dependencies = [
|
|||||||
"send_wrapper",
|
"send_wrapper",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_qs",
|
"serde_qs 0.12.0",
|
||||||
"server_fn_macro_default",
|
"server_fn_macro_default",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"url",
|
"url",
|
||||||
@@ -2249,6 +2331,18 @@ version = "0.11.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stylers"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "03e306edf4b3cb5cff4b2e21b8895ed9e70fbd1bbb3a8dfb7e4cc245a763a955"
|
||||||
|
dependencies = [
|
||||||
|
"levenshtein",
|
||||||
|
"litrs",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.6.1"
|
version = "2.6.1"
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = ["backend", "frontend"]
|
members = ["backend", "common", "frontend"]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|||||||
@@ -20,3 +20,5 @@ diesel = { version = "2.2", features = ["serde_json"] }
|
|||||||
diesel-async = { version = "0.5", features = ["postgres"] }
|
diesel-async = { version = "0.5", features = ["postgres"] }
|
||||||
serde_json = "1.0.128"
|
serde_json = "1.0.128"
|
||||||
diesel_async_migrations = { version = "0.15" }
|
diesel_async_migrations = { version = "0.15" }
|
||||||
|
|
||||||
|
common = { path = "../common/" }
|
||||||
|
|||||||
115
backend/src/api.rs
Normal file
115
backend/src/api.rs
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
pub mod demos {
|
||||||
|
use crate::UserSession;
|
||||||
|
use diesel_async::RunQueryDsl;
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use axum::extract::{State, Path};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
struct DemoState {
|
||||||
|
upload_folder: std::path::PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn router<P>(upload_folder: P) -> axum::Router where P: Into<std::path::PathBuf> {
|
||||||
|
axum::Router::new()
|
||||||
|
.route("/list", axum::routing::get(list))
|
||||||
|
.route("/upload", axum::routing::post(upload).layer(axum::extract::DefaultBodyLimit::max(500*1024*1024)))
|
||||||
|
.route("/:id/info", axum::routing::get(info))
|
||||||
|
.with_state(Arc::new(DemoState {
|
||||||
|
upload_folder: upload_folder.into(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn list(session: UserSession) -> Result<axum::response::Json<Vec<common::BaseDemoInfo>>, axum::http::StatusCode> {
|
||||||
|
let steam_id = session.data().steam_id.ok_or_else(|| axum::http::StatusCode::UNAUTHORIZED)?;
|
||||||
|
tracing::info!("SteamID: {:?}", steam_id);
|
||||||
|
|
||||||
|
let query = crate::schema::demos::dsl::demos.filter(crate::schema::demos::dsl::steam_id.eq(steam_id as i64));
|
||||||
|
let results: Vec<crate::models::Demo> = query.load(&mut crate::db_connection().await).await.unwrap();
|
||||||
|
|
||||||
|
Ok(axum::response::Json(results.into_iter().map(|demo| common::BaseDemoInfo {
|
||||||
|
id: demo.demo_id,
|
||||||
|
}).collect::<Vec<_>>()))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn upload(State(state): State<Arc<DemoState>>, session: crate::UserSession, form: axum::extract::Multipart) -> Result<axum::response::Redirect, (axum::http::StatusCode, &'static str)> {
|
||||||
|
let steam_id = session.data().steam_id.ok_or_else(|| (axum::http::StatusCode::UNAUTHORIZED, "Not logged in"))?;
|
||||||
|
|
||||||
|
tracing::info!("Upload for Session: {:?}", steam_id);
|
||||||
|
|
||||||
|
let file_content = crate::get_demo_from_upload("demo", form).await.unwrap();
|
||||||
|
|
||||||
|
let user_folder = std::path::Path::new(&state.upload_folder).join(format!("{}/", steam_id));
|
||||||
|
if !tokio::fs::try_exists(&user_folder).await.unwrap_or(false) {
|
||||||
|
tokio::fs::create_dir_all(&user_folder).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let timestamp_secs = std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH).unwrap().as_secs();
|
||||||
|
let demo_file_path = user_folder.join(format!("{}.dem", timestamp_secs));
|
||||||
|
|
||||||
|
tokio::fs::write(demo_file_path, file_content).await.unwrap();
|
||||||
|
|
||||||
|
let query = diesel::dsl::insert_into(crate::schema::demos::dsl::demos).values(crate::models::Demo {
|
||||||
|
demo_id: timestamp_secs as i64,
|
||||||
|
steam_id: steam_id as i64,
|
||||||
|
});
|
||||||
|
query.execute(&mut crate::db_connection().await).await.unwrap();
|
||||||
|
|
||||||
|
Ok(axum::response::Redirect::to("/"))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn info(session: UserSession, Path(demo_id): Path<i64>) -> Result<(), axum::http::StatusCode> {
|
||||||
|
tracing::info!("Get info for Demo: {:?}", demo_id);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod steam {
|
||||||
|
use axum::extract::State;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub fn router(url: &str, callback_path: &str) -> axum::Router {
|
||||||
|
axum::Router::new()
|
||||||
|
.route("/login", axum::routing::get(steam_login))
|
||||||
|
.route("/callback", axum::routing::get(steam_callback))
|
||||||
|
.with_state(Arc::new(steam_openid::SteamOpenId::new(url, callback_path).unwrap()))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn steam_login(State(openid): State<Arc<steam_openid::SteamOpenId>>) -> Result<axum::response::Redirect, axum::http::StatusCode> {
|
||||||
|
let url = openid.get_redirect_url();
|
||||||
|
|
||||||
|
Ok(axum::response::Redirect::to(url))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn steam_callback(
|
||||||
|
State(openid): State<Arc<steam_openid::SteamOpenId>>,
|
||||||
|
mut session: crate::UserSession,
|
||||||
|
request: axum::extract::Request,
|
||||||
|
) -> Result<axum::response::Redirect, axum::http::StatusCode> {
|
||||||
|
tracing::info!("Steam Callback");
|
||||||
|
|
||||||
|
let query = request.uri().query().ok_or_else(|| {
|
||||||
|
tracing::error!("Missing query in parameters");
|
||||||
|
axum::http::StatusCode::BAD_REQUEST
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let id = openid.verify(query).await.map_err(|e| {
|
||||||
|
tracing::error!("Verifying OpenID: {:?}", e);
|
||||||
|
axum::http::StatusCode::BAD_REQUEST
|
||||||
|
})?;
|
||||||
|
|
||||||
|
session
|
||||||
|
.modify_data(|data| {
|
||||||
|
data.steam_id = Some(id);
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
|
Ok(axum::response::Redirect::to("/"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn router() -> axum::Router {
|
||||||
|
axum::Router::new()
|
||||||
|
.nest("/steam/", steam::router("http://192.168.0.156:3000", "/api/steam/callback"))
|
||||||
|
.nest("/demos/", demos::router("uploads/"))
|
||||||
|
}
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
pub mod models;
|
pub mod models;
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
|
|
||||||
@@ -34,3 +32,5 @@ pub async fn get_demo_from_upload(name: &str, mut form: axum::extract::Multipart
|
|||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod api;
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt;
|
use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt;
|
||||||
|
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use diesel_async::{RunQueryDsl, AsyncConnection, AsyncPgConnection};
|
use diesel_async::RunQueryDsl;
|
||||||
|
|
||||||
static OPENID: std::sync::LazyLock<steam_openid::SteamOpenId> = std::sync::LazyLock::new(|| {
|
|
||||||
steam_openid::SteamOpenId::new("http://192.168.0.156:3000", "/api/steam/callback").unwrap()
|
|
||||||
});
|
|
||||||
static UPLOAD_FOLDER: &str = "uploads/";
|
static UPLOAD_FOLDER: &str = "uploads/";
|
||||||
|
|
||||||
const MIGRATIONS: diesel_async_migrations::EmbeddedMigrations = diesel_async_migrations::embed_migrations!("../migrations/");
|
const MIGRATIONS: diesel_async_migrations::EmbeddedMigrations = diesel_async_migrations::embed_migrations!("../migrations/");
|
||||||
@@ -33,7 +30,7 @@ async fn main() {
|
|||||||
let session_layer = tower_sessions::SessionManagerLayer::new(session_store)
|
let session_layer = tower_sessions::SessionManagerLayer::new(session_store)
|
||||||
.with_secure(false)
|
.with_secure(false)
|
||||||
.with_expiry(tower_sessions::Expiry::OnInactivity(
|
.with_expiry(tower_sessions::Expiry::OnInactivity(
|
||||||
time::Duration::minutes(15),
|
time::Duration::hours(48),
|
||||||
));
|
));
|
||||||
|
|
||||||
if !tokio::fs::try_exists(UPLOAD_FOLDER).await.unwrap_or(false) {
|
if !tokio::fs::try_exists(UPLOAD_FOLDER).await.unwrap_or(false) {
|
||||||
@@ -41,14 +38,7 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let router = axum::Router::new()
|
let router = axum::Router::new()
|
||||||
.nest_service(
|
.nest("/api/", backend::api::router())
|
||||||
"/api/",
|
|
||||||
axum::Router::new()
|
|
||||||
.route("/steam/callback", axum::routing::get(steam_callback))
|
|
||||||
.route("/steam/login", axum::routing::get(steam_login))
|
|
||||||
.route("/demos/upload", axum::routing::post(upload).layer(axum::extract::DefaultBodyLimit::max(1024*1024*500)))
|
|
||||||
.route("/demos/list", axum::routing::get(demos_list))
|
|
||||||
)
|
|
||||||
.layer(session_layer)
|
.layer(session_layer)
|
||||||
.nest_service("/", tower_http::services::ServeDir::new("frontend/dist/"));
|
.nest_service("/", tower_http::services::ServeDir::new("frontend/dist/"));
|
||||||
|
|
||||||
@@ -56,71 +46,6 @@ async fn main() {
|
|||||||
axum::serve(listener, router).await.unwrap();
|
axum::serve(listener, router).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn upload(session: backend::UserSession, form: axum::extract::Multipart) -> Result<axum::response::Redirect, (axum::http::StatusCode, &'static str)> {
|
async fn demo_info(session: backend::UserSession) -> Result<(), axum::http::StatusCode> {
|
||||||
let steam_id = session.data().steam_id.ok_or_else(|| (axum::http::StatusCode::UNAUTHORIZED, "Not logged in"))?;
|
|
||||||
|
|
||||||
tracing::info!("Upload for Session: {:?}", steam_id);
|
|
||||||
|
|
||||||
let file_content = backend::get_demo_from_upload("demo", form).await.unwrap();
|
|
||||||
|
|
||||||
let user_folder = std::path::Path::new(UPLOAD_FOLDER).join(format!("{}/", steam_id));
|
|
||||||
if !tokio::fs::try_exists(&user_folder).await.unwrap_or(false) {
|
|
||||||
tokio::fs::create_dir_all(&user_folder).await.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let timestamp_secs = std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH).unwrap().as_secs();
|
|
||||||
let demo_file_path = user_folder.join(format!("{}.dem", timestamp_secs));
|
|
||||||
|
|
||||||
tokio::fs::write(demo_file_path, file_content).await.unwrap();
|
|
||||||
|
|
||||||
let query = diesel::dsl::insert_into(backend::schema::demos::dsl::demos).values(backend::models::Demo {
|
|
||||||
demo_id: timestamp_secs as i64,
|
|
||||||
steam_id: steam_id as i64,
|
|
||||||
});
|
|
||||||
query.execute(&mut backend::db_connection().await).await.unwrap();
|
|
||||||
|
|
||||||
Ok(axum::response::Redirect::to("/"))
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn steam_login() -> Result<axum::response::Redirect, axum::http::StatusCode> {
|
|
||||||
let url = OPENID.get_redirect_url();
|
|
||||||
|
|
||||||
Ok(axum::response::Redirect::to(url))
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn steam_callback(
|
|
||||||
mut session: backend::UserSession,
|
|
||||||
request: axum::extract::Request,
|
|
||||||
) -> Result<axum::response::Redirect, axum::http::StatusCode> {
|
|
||||||
tracing::info!("Steam Callback");
|
|
||||||
|
|
||||||
let query = request.uri().query().ok_or_else(|| {
|
|
||||||
tracing::error!("Missing query in parameters");
|
|
||||||
axum::http::StatusCode::BAD_REQUEST
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let id = OPENID.verify(query).await.map_err(|e| {
|
|
||||||
tracing::error!("Verifying OpenID: {:?}", e);
|
|
||||||
axum::http::StatusCode::BAD_REQUEST
|
|
||||||
})?;
|
|
||||||
|
|
||||||
session
|
|
||||||
.modify_data(|data| {
|
|
||||||
data.steam_id = Some(id);
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
|
|
||||||
Ok(axum::response::Redirect::to("/"))
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn demos_list(session: backend::UserSession) -> Result<(), axum::http::StatusCode> {
|
|
||||||
let steam_id = session.data().steam_id.ok_or_else(|| axum::http::StatusCode::UNAUTHORIZED)?;
|
|
||||||
tracing::info!("SteamID: {:?}", steam_id);
|
|
||||||
|
|
||||||
let query = backend::schema::demos::dsl::demos.filter(backend::schema::demos::dsl::steam_id.eq(steam_id as i64));
|
|
||||||
let results: Vec<backend::models::Demo> = query.load(&mut backend::db_connection().await).await.unwrap();
|
|
||||||
|
|
||||||
dbg!(&results);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
use diesel::prelude::*;
|
|
||||||
use diesel_async::RunQueryDsl;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
pub struct UserSessionData {
|
pub struct UserSessionData {
|
||||||
pub steam_id: Option<u64>,
|
pub steam_id: Option<u64>,
|
||||||
|
|||||||
7
common/Cargo.toml
Normal file
7
common/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "common"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
4
common/src/lib.rs
Normal file
4
common/src/lib.rs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct BaseDemoInfo {
|
||||||
|
pub id: i64,
|
||||||
|
}
|
||||||
@@ -5,4 +5,8 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
leptos = { version = "0.6", features = ["csr", "nightly"] }
|
leptos = { version = "0.6", features = ["csr", "nightly"] }
|
||||||
|
leptos_router = { version = "0.6", features = ["csr"] }
|
||||||
reqwasm = "0.5.0"
|
reqwasm = "0.5.0"
|
||||||
|
stylers = { version = "0.3" }
|
||||||
|
|
||||||
|
common = { path = "../common/" }
|
||||||
|
|||||||
4
frontend/Trunk.toml
Normal file
4
frontend/Trunk.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[[hooks]]
|
||||||
|
stage = "post_build"
|
||||||
|
command = "sh"
|
||||||
|
command_arguments = ["-c", "cp ../target/stylers/main.css $TRUNK_STAGING_DIR/"]
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head></head>
|
<head>
|
||||||
|
<link rel="stylesheet" href="/main.css">
|
||||||
|
</head>
|
||||||
<body></body>
|
<body></body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
17
frontend/src/demo.rs
Normal file
17
frontend/src/demo.rs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
use leptos::*;
|
||||||
|
|
||||||
|
#[leptos::component]
|
||||||
|
pub fn demo() -> impl leptos::IntoView {
|
||||||
|
let params = leptos_router::use_params_map();
|
||||||
|
let id = move || params.with(|params| params.get("id").cloned().unwrap_or_default());
|
||||||
|
|
||||||
|
let demo_info = create_resource(|| (), move |_| async move {
|
||||||
|
let res = reqwasm::http::Request::get(&format!("/api/demos/{}/info", id())).send().await.unwrap();
|
||||||
|
dbg!(res.text().await);
|
||||||
|
0
|
||||||
|
});
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<h2>Demo - {id}</h2>
|
||||||
|
}
|
||||||
|
}
|
||||||
107
frontend/src/lib.rs
Normal file
107
frontend/src/lib.rs
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
use leptos::*;
|
||||||
|
use leptos_router::A;
|
||||||
|
|
||||||
|
mod demo;
|
||||||
|
pub use demo::Demo;
|
||||||
|
|
||||||
|
#[leptos::component]
|
||||||
|
pub fn demo_list_entry(demo: common::BaseDemoInfo) -> impl leptos::IntoView {
|
||||||
|
view! {
|
||||||
|
<li>
|
||||||
|
<A href=format!("/demo/{}", demo.id)>Demo: {demo.id}</A>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[leptos::component]
|
||||||
|
pub fn steam_login(height: &'static str, width: &'static str) -> impl leptos::IntoView {
|
||||||
|
view! {
|
||||||
|
<a href="/api/steam/login">
|
||||||
|
<img src="https://community.akamai.steamstatic.com/public/images/signinthroughsteam/sits_01.png" alt="Steam Login" style=format!("height: {height}; width: {width}") />
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[leptos::component]
|
||||||
|
pub fn upload_demo() -> impl leptos::IntoView {
|
||||||
|
use leptos_router::Form;
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<div>
|
||||||
|
<Form action="/api/demos/upload" method="post" enctype="multipart/form-data".to_string()>
|
||||||
|
<p> Select File to upload </p>
|
||||||
|
<input type="file" name="demo" id="demo"></input>
|
||||||
|
<input type="submit" value="Upload Image" name="submit"></input>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[leptos::component]
|
||||||
|
pub fn top_bar() -> impl leptos::IntoView {
|
||||||
|
let style = stylers::style! {
|
||||||
|
"TopBar",
|
||||||
|
.bar {
|
||||||
|
width: 100%;
|
||||||
|
height: 4vh;
|
||||||
|
padding-top: 0.5vh;
|
||||||
|
padding-bottom: 0.5vh;
|
||||||
|
|
||||||
|
background-color: #28282f;
|
||||||
|
color: #d5d5d5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.elem {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
color: #d5d5d5;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
view! {class = style,
|
||||||
|
<div class="bar">
|
||||||
|
<A href="/" class="group">
|
||||||
|
<p class="logo">Knifer</p>
|
||||||
|
</A>
|
||||||
|
|
||||||
|
<div class="group" style="float: right">
|
||||||
|
<div class="elem">
|
||||||
|
Upload Demo
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="elem">
|
||||||
|
<SteamLogin height="4vh" width="auto" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[leptos::component]
|
||||||
|
pub fn homepage() -> impl leptos::IntoView {
|
||||||
|
let demo_data = create_resource(|| (), |_| async move {
|
||||||
|
let res = reqwasm::http::Request::get("/api/demos/list").send().await.unwrap();
|
||||||
|
let demos: Vec<common::BaseDemoInfo> = res.json().await.unwrap();
|
||||||
|
demos
|
||||||
|
});
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<h2>Demos</h2>
|
||||||
|
<UploadDemo />
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
{ move || demo_data.get().unwrap_or_default().into_iter().map(|demo| crate::DemoListEntry(DemoListEntryProps {
|
||||||
|
demo
|
||||||
|
})).collect::<Vec<_>>() }
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos::prelude::*;
|
use leptos_router::*;
|
||||||
|
|
||||||
async fn load_demos() -> usize {
|
use frontend::{UploadDemo, TopBar, Homepage, Demo};
|
||||||
|
|
||||||
|
async fn load_demos() -> Vec<common::BaseDemoInfo> {
|
||||||
let res = reqwasm::http::Request::get("/api/demos/list").send().await.unwrap();
|
let res = reqwasm::http::Request::get("/api/demos/list").send().await.unwrap();
|
||||||
dbg!(res);
|
let demos: Vec<common::BaseDemoInfo> = res.json().await.unwrap();
|
||||||
|
|
||||||
0
|
demos
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -14,16 +16,16 @@ fn main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
mount_to_body(move || view! {
|
mount_to_body(move || view! {
|
||||||
<p>"Hello, world!"</p>
|
<Router>
|
||||||
<a href="/api/steam/login">Steam Login</a> { move || match async_data.get() {
|
<nav>
|
||||||
None => 123,
|
<TopBar />
|
||||||
Some(v) => v,
|
</nav>
|
||||||
} }
|
<main>
|
||||||
|
<Routes>
|
||||||
<form action="/api/demos/upload" method="post" enctype="multipart/form-data">
|
<Route path="/" view=Homepage />
|
||||||
Select File to upload
|
<Route path="/demo/:id" view=Demo />
|
||||||
<input type="file" name="demo" id="demo"></input>
|
</Routes>
|
||||||
<input type="submit" value="Upload Image" name="submit"></input>
|
</main>
|
||||||
</form>
|
</Router>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
-- Your SQL goes here
|
-- Your SQL goes here
|
||||||
CREATE TABLE IF NOT EXISTS demos (
|
CREATE TABLE IF NOT EXISTS demos (
|
||||||
steam_id bigint PRIMARY KEY,
|
steam_id bigint,
|
||||||
demo_id bigint
|
demo_id bigint,
|
||||||
|
PRIMARY KEY(steam_id, demo_id)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// @generated automatically by Diesel CLI.
|
// @generated automatically by Diesel CLI.
|
||||||
|
|
||||||
diesel::table! {
|
diesel::table! {
|
||||||
demos (steam_id) {
|
demos (steam_id, demo_id) {
|
||||||
steam_id -> Int8,
|
steam_id -> Int8,
|
||||||
demo_id -> Nullable<Int8>,
|
demo_id -> Int8,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user