mirror of
https://codeberg.org/demostf/frontend.git
synced 2026-06-03 18:24:12 +02:00
more tracing
This commit is contained in:
parent
a1a3f9984b
commit
2b8cdfc736
16 changed files with 116 additions and 65 deletions
|
|
@ -12,7 +12,7 @@ use sea_query_binder::SqlxBinder;
|
|||
use serde::{Deserialize, Deserializer};
|
||||
use sqlx::{query_as, Executor, FromRow, Postgres};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Write;
|
||||
use std::fmt::{Debug, Formatter, Write};
|
||||
use std::ops::Range;
|
||||
use std::str::FromStr;
|
||||
use time::format_description::well_known::Iso8601;
|
||||
|
|
@ -41,6 +41,14 @@ pub struct Demo {
|
|||
pub chat: Vec<Chat>,
|
||||
}
|
||||
|
||||
impl Debug for Demo {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Demo")
|
||||
.field("id", &self.id)
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
impl Demo {
|
||||
#[instrument(skip(connection))]
|
||||
pub async fn by_id(
|
||||
|
|
@ -150,7 +158,7 @@ impl Render for ViewerUrl {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, FromRow)]
|
||||
#[derive(FromRow)]
|
||||
pub struct ListDemo {
|
||||
pub id: i32,
|
||||
pub name: String,
|
||||
|
|
@ -163,6 +171,14 @@ pub struct ListDemo {
|
|||
pub player_count: i32,
|
||||
}
|
||||
|
||||
impl Debug for ListDemo {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("ListDemo")
|
||||
.field("id", &self.id)
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
impl ListDemo {
|
||||
#[instrument(skip(connection))]
|
||||
pub async fn list(
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use crate::Result;
|
||||
use maud::Render;
|
||||
use sqlx::{query, Executor, Postgres};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use tracing::instrument;
|
||||
|
||||
#[instrument(skip(connection))]
|
||||
pub async fn map_list(
|
||||
connection: impl Executor<'_, Database = Postgres>,
|
||||
) -> Result<impl Iterator<Item = String>> {
|
||||
Ok(query!(
|
||||
pub async fn map_list(connection: impl Executor<'_, Database = Postgres>) -> Result<MapList> {
|
||||
let maps = query!(
|
||||
r#"SELECT
|
||||
map as "map!"
|
||||
FROM map_list
|
||||
|
|
@ -15,5 +15,27 @@ pub async fn map_list(
|
|||
.fetch_all(connection)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|res| res.map))
|
||||
.map(|res| res.map);
|
||||
Ok(MapList(maps.collect()))
|
||||
}
|
||||
|
||||
pub struct MapList(Vec<String>);
|
||||
|
||||
impl Debug for MapList {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{} maps", self.0.len())
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for MapList {
|
||||
fn render_to(&self, buffer: &mut String) {
|
||||
let mut first = true;
|
||||
for map in self.0.iter() {
|
||||
if !first {
|
||||
buffer.push(',');
|
||||
}
|
||||
buffer.push_str(map);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,39 @@
|
|||
use crate::data::steam_id::SteamId;
|
||||
use crate::{Error, Result};
|
||||
use maud::Render;
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::Rng;
|
||||
use reqwest::get;
|
||||
use serde::ser::SerializeStruct;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{query, query_as, Executor, Postgres};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct User {
|
||||
pub steam_id: SteamId,
|
||||
pub name: String,
|
||||
pub token: String,
|
||||
pub token: Token,
|
||||
}
|
||||
|
||||
impl Debug for User {
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct Token(String);
|
||||
|
||||
impl Debug for Token {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("User")
|
||||
.field("steam_id", &self.steam_id)
|
||||
.field("name", &self.name)
|
||||
.finish_non_exhaustive()
|
||||
f.write_str("redacted")
|
||||
}
|
||||
}
|
||||
|
||||
impl Token {
|
||||
pub fn new(token: String) -> Self {
|
||||
Token(token)
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for Token {
|
||||
fn render_to(&self, buffer: &mut String) {
|
||||
self.0.render_to(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +72,7 @@ impl User {
|
|||
if let Some(user) = user {
|
||||
Ok(User {
|
||||
steam_id,
|
||||
token: user.token,
|
||||
token: Token::new(user.token),
|
||||
name: user.name,
|
||||
})
|
||||
} else {
|
||||
|
|
@ -82,7 +95,7 @@ impl User {
|
|||
.await?;
|
||||
Ok(User {
|
||||
steam_id,
|
||||
token,
|
||||
token: Token::new(token),
|
||||
name: profile.name,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
25
src/main.rs
25
src/main.rs
|
|
@ -10,7 +10,7 @@ use crate::asset::{guess_mime, serve_asset};
|
|||
pub use crate::config::Config;
|
||||
use crate::config::Listen;
|
||||
use crate::data::demo::{Demo, Filter, ListDemo};
|
||||
use crate::data::maps::map_list;
|
||||
use crate::data::maps::{map_list, MapList};
|
||||
use crate::data::steam_id::SteamId;
|
||||
use crate::data::user::User;
|
||||
use crate::error::SetupError;
|
||||
|
|
@ -52,7 +52,7 @@ use steam_openid::SteamOpenId;
|
|||
use tokio::signal::ctrl_c;
|
||||
use tonic::transport::{ClientTlsConfig, Identity};
|
||||
use tower_http::trace::TraceLayer;
|
||||
use tracing::{error, info, info_span};
|
||||
use tracing::{error, info, info_span, instrument};
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Layer};
|
||||
|
||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||
|
|
@ -62,7 +62,7 @@ struct App {
|
|||
openid: SteamOpenId,
|
||||
api: String,
|
||||
maps: String,
|
||||
map_list: Vec<String>,
|
||||
map_list: MapList,
|
||||
pub session_store: MemoryStore,
|
||||
}
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ async fn main() -> Result<()> {
|
|||
let config = setup()?;
|
||||
let connection = config.database.connect().await?;
|
||||
|
||||
let map_list = map_list(&connection).await?.collect();
|
||||
let map_list = map_list(&connection).await?;
|
||||
let session_store = MemoryStore::new();
|
||||
|
||||
let state = Arc::new(App {
|
||||
|
|
@ -235,7 +235,7 @@ async fn main() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
#[instrument(skip(app))]
|
||||
async fn index(
|
||||
State(app): State<Arc<App>>,
|
||||
session: SessionData,
|
||||
|
|
@ -253,6 +253,7 @@ async fn index(
|
|||
))
|
||||
}
|
||||
|
||||
#[instrument(skip(_app))]
|
||||
async fn about(State(_app): State<Arc<App>>, session: SessionData) -> Result<Markup> {
|
||||
Ok(render(
|
||||
AboutPage {
|
||||
|
|
@ -262,6 +263,7 @@ async fn about(State(_app): State<Arc<App>>, session: SessionData) -> Result<Mar
|
|||
))
|
||||
}
|
||||
|
||||
#[instrument(skip(app))]
|
||||
async fn api(State(app): State<Arc<App>>, session: SessionData) -> Result<Markup> {
|
||||
Ok(render(
|
||||
ApiPage {
|
||||
|
|
@ -272,6 +274,7 @@ async fn api(State(app): State<Arc<App>>, session: SessionData) -> Result<Markup
|
|||
))
|
||||
}
|
||||
|
||||
#[instrument(skip(app))]
|
||||
async fn demo(
|
||||
State(app): State<Arc<App>>,
|
||||
Path(id): Path<String>,
|
||||
|
|
@ -321,6 +324,7 @@ async fn login_callback(
|
|||
))
|
||||
}
|
||||
|
||||
#[instrument(skip(app))]
|
||||
async fn login(State(app): State<Arc<App>>) -> impl IntoResponse {
|
||||
(
|
||||
StatusCode::FOUND,
|
||||
|
|
@ -331,6 +335,7 @@ async fn login(State(app): State<Arc<App>>) -> impl IntoResponse {
|
|||
)
|
||||
}
|
||||
|
||||
#[instrument(skip(app, cookie))]
|
||||
async fn logout(
|
||||
State(app): State<Arc<App>>,
|
||||
cookie: Option<TypedHeader<Cookie>>,
|
||||
|
|
@ -356,11 +361,12 @@ async fn logout(
|
|||
)
|
||||
}
|
||||
|
||||
#[instrument(skip(app))]
|
||||
async fn upload(State(app): State<Arc<App>>, session: SessionData) -> impl IntoResponse {
|
||||
if let Some(token) = session.token() {
|
||||
render(
|
||||
UploadPage {
|
||||
key: token.as_str(),
|
||||
key: &token,
|
||||
api: app.api.as_str(),
|
||||
},
|
||||
session,
|
||||
|
|
@ -375,14 +381,14 @@ async fn upload(State(app): State<Arc<App>>, session: SessionData) -> impl IntoR
|
|||
}
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
#[instrument(skip(app))]
|
||||
async fn demo_list(State(app): State<Arc<App>>, filter: Option<Query<Filter>>) -> Result<Markup> {
|
||||
let filter = filter.map(|filter| filter.0).unwrap_or_default();
|
||||
let demos = ListDemo::list(&app.connection, filter).await?;
|
||||
Ok(DemoList { demos: &demos }.render())
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
#[instrument(skip(app))]
|
||||
async fn uploads(
|
||||
State(app): State<Arc<App>>,
|
||||
session: SessionData,
|
||||
|
|
@ -407,7 +413,7 @@ async fn uploads(
|
|||
))
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
#[instrument(skip(app))]
|
||||
async fn profiles(
|
||||
State(app): State<Arc<App>>,
|
||||
session: SessionData,
|
||||
|
|
@ -432,6 +438,7 @@ async fn profiles(
|
|||
))
|
||||
}
|
||||
|
||||
#[instrument(skip(app))]
|
||||
async fn viewer(
|
||||
State(app): State<Arc<App>>,
|
||||
id: Option<Path<String>>,
|
||||
|
|
|
|||
|
|
@ -1,16 +1,18 @@
|
|||
use crate::data::user::Token;
|
||||
use crate::pages::plugin_section::PluginSection;
|
||||
use crate::pages::Page;
|
||||
use maud::{html, Markup};
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AboutPage {
|
||||
pub key: Option<String>,
|
||||
pub key: Option<Token>,
|
||||
}
|
||||
|
||||
impl AboutPage {
|
||||
pub fn plugin_section(&self) -> PluginSection {
|
||||
PluginSection {
|
||||
key: self.key.as_deref(),
|
||||
key: self.key.as_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use maud::{html, Markup};
|
|||
use std::borrow::Cow;
|
||||
use std::fmt::Display;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ApiPage<'a> {
|
||||
pub api_base: &'a str,
|
||||
pub steam_id: SteamId,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use std::borrow::Cow;
|
|||
#[asset(source = "style/pages/class-icons.css", url = "/class-icons.css")]
|
||||
pub struct ClassIconsStyle;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DemoPage {
|
||||
pub demo: Demo,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use demostf_build::Asset;
|
|||
use maud::{html, Markup};
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EditorPage;
|
||||
|
||||
#[derive(Asset)]
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
use crate::data::demo::ListDemo;
|
||||
use crate::data::maps::MapList;
|
||||
use crate::fragments::demo_list::DemoList;
|
||||
use crate::pages::Page;
|
||||
use demostf_build::Asset;
|
||||
use maud::{html, Markup, Render};
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Index<'a> {
|
||||
pub demos: &'a [ListDemo],
|
||||
pub maps: &'a [String],
|
||||
pub maps: &'a MapList,
|
||||
pub api: &'a str,
|
||||
}
|
||||
|
||||
|
|
@ -16,9 +18,6 @@ pub struct Index<'a> {
|
|||
pub struct DemoListScript;
|
||||
|
||||
impl<'a> Index<'a> {
|
||||
fn map_list(&self) -> impl Render + 'a {
|
||||
MapList(self.maps)
|
||||
}
|
||||
fn demo_list(&self) -> impl Render + 'a {
|
||||
DemoList { demos: self.demos }
|
||||
}
|
||||
|
|
@ -33,7 +32,7 @@ impl Page for Index<'_> {
|
|||
let script = DemoListScript::url();
|
||||
html! {
|
||||
h1 { "Demos" }
|
||||
#filter-bar data-maps = (self.map_list()) data-api-base = (self.api) {}
|
||||
#filter-bar data-maps = (self.maps) data-api-base = (self.api) {}
|
||||
table.demolist {
|
||||
thead {
|
||||
tr {
|
||||
|
|
@ -53,18 +52,3 @@ impl Page for Index<'_> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MapList<'a>(pub &'a [String]);
|
||||
|
||||
impl Render for MapList<'_> {
|
||||
fn render_to(&self, buffer: &mut String) {
|
||||
let mut first = true;
|
||||
for map in self.0 {
|
||||
if !first {
|
||||
buffer.push(',');
|
||||
}
|
||||
buffer.push_str(map);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use crate::session::SessionData;
|
|||
use demostf_build::Asset;
|
||||
use maud::{html, Markup, DOCTYPE};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Debug;
|
||||
use tracing::instrument;
|
||||
|
||||
pub trait Page {
|
||||
|
|
@ -25,7 +26,7 @@ pub trait Page {
|
|||
pub struct GlobalStyle;
|
||||
|
||||
#[instrument]
|
||||
pub fn render<T: Page>(page: T, session: SessionData) -> Markup {
|
||||
pub fn render<T: Page + Debug>(page: T, session: SessionData) -> Markup {
|
||||
let style_url = GlobalStyle::url();
|
||||
html! {
|
||||
(DOCTYPE)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
use crate::data::user::Token;
|
||||
use maud::{html, Markup, Render};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PluginSection<'a> {
|
||||
pub key: Option<&'a str>,
|
||||
pub key: Option<&'a Token>,
|
||||
}
|
||||
|
||||
impl Render for PluginSection<'_> {
|
||||
|
|
|
|||
|
|
@ -1,23 +1,22 @@
|
|||
use crate::data::demo::ListDemo;
|
||||
use crate::data::maps::MapList;
|
||||
use crate::data::user::User;
|
||||
use crate::fragments::demo_list::DemoList;
|
||||
use crate::pages::index::{DemoListScript, MapList};
|
||||
use crate::pages::index::DemoListScript;
|
||||
use crate::pages::Page;
|
||||
use demostf_build::Asset;
|
||||
use maud::{html, Markup, Render};
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Profile<'a> {
|
||||
pub user: User,
|
||||
pub demos: &'a [ListDemo],
|
||||
pub maps: &'a [String],
|
||||
pub maps: &'a MapList,
|
||||
pub api: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> Profile<'a> {
|
||||
fn map_list(&self) -> impl Render + 'a {
|
||||
MapList(self.maps)
|
||||
}
|
||||
fn demo_list(&self) -> impl Render + 'a {
|
||||
DemoList { demos: self.demos }
|
||||
}
|
||||
|
|
@ -35,7 +34,7 @@ impl Page for Profile<'_> {
|
|||
"Demos with "
|
||||
(self.user.name)
|
||||
}
|
||||
#filter-bar data-maps = (self.map_list()) data-api-base = (self.api) {}
|
||||
#filter-bar data-maps = (self.maps) data-api-base = (self.api) {}
|
||||
table.demolist {
|
||||
thead {
|
||||
tr {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
use crate::data::user::Token;
|
||||
use crate::pages::plugin_section::PluginSection;
|
||||
use crate::pages::Page;
|
||||
use demostf_build::Asset;
|
||||
use maud::{html, Markup};
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UploadPage<'a> {
|
||||
pub key: &'a str,
|
||||
pub key: &'a Token,
|
||||
pub api: &'a str,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,22 @@
|
|||
use crate::data::demo::ListDemo;
|
||||
use crate::data::maps::MapList;
|
||||
use crate::data::user::User;
|
||||
use crate::fragments::demo_list::DemoList;
|
||||
use crate::pages::index::{DemoListScript, MapList};
|
||||
use crate::pages::index::DemoListScript;
|
||||
use crate::pages::Page;
|
||||
use demostf_build::Asset;
|
||||
use maud::{html, Markup, Render};
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Uploads<'a> {
|
||||
pub user: User,
|
||||
pub demos: &'a [ListDemo],
|
||||
pub maps: &'a [String],
|
||||
pub maps: &'a MapList,
|
||||
pub api: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> Uploads<'a> {
|
||||
fn map_list(&self) -> impl Render + 'a {
|
||||
MapList(self.maps)
|
||||
}
|
||||
fn demo_list(&self) -> impl Render + 'a {
|
||||
DemoList { demos: self.demos }
|
||||
}
|
||||
|
|
@ -35,7 +34,7 @@ impl Page for Uploads<'_> {
|
|||
"Uploads by "
|
||||
(self.user.name)
|
||||
}
|
||||
#filter-bar data-maps = (self.map_list()) data-api-base = (self.api) {}
|
||||
#filter-bar data-maps = (self.maps) data-api-base = (self.api) {}
|
||||
table.demolist {
|
||||
thead {
|
||||
tr {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use demostf_build::Asset;
|
|||
use maud::{html, Markup};
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ViewerPage<'a> {
|
||||
pub demo: Option<Demo>,
|
||||
pub maps: &'a str,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::data::steam_id::SteamId;
|
||||
use crate::data::user::User;
|
||||
use crate::data::user::{Token, User};
|
||||
use crate::{App, Result};
|
||||
use async_session::SessionStore as _;
|
||||
use axum::extract::{FromRef, FromRequestParts};
|
||||
|
|
@ -18,7 +18,7 @@ pub enum SessionData {
|
|||
}
|
||||
|
||||
impl SessionData {
|
||||
pub fn token(&self) -> Option<String> {
|
||||
pub fn token(&self) -> Option<Token> {
|
||||
match self {
|
||||
SessionData::Authenticated(user) => Some(user.token.clone()),
|
||||
SessionData::UnAuthenticated => None,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue