Add user stats route
This commit is contained in:
@@ -1,13 +1,20 @@
|
||||
use std::i64;
|
||||
|
||||
use anyhow::Result;
|
||||
use serde::Serialize;
|
||||
use sqlx::{Row, SqlitePool};
|
||||
use std::i64;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Database {
|
||||
pool: SqlitePool,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct UserStats {
|
||||
pub name: String,
|
||||
pub rating_count: i64,
|
||||
pub average_rating: f64,
|
||||
}
|
||||
|
||||
impl Database {
|
||||
pub async fn new() -> Result<Self> {
|
||||
let pool = SqlitePool::connect("sqlite://ratings.db?mode=rwc").await?;
|
||||
@@ -218,7 +225,7 @@ impl Database {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_user_most_ratings(&self) -> Result<()> {
|
||||
pub async fn get_user_most_ratings(&self) -> Result<Vec<UserStats>> {
|
||||
let mut conn = self.pool.acquire().await?;
|
||||
|
||||
let records = sqlx::query(
|
||||
@@ -233,16 +240,16 @@ impl Database {
|
||||
.fetch_all(&mut *conn)
|
||||
.await?;
|
||||
|
||||
//let id = record.try_get("id")?;
|
||||
|
||||
// Map the database records into our new struct
|
||||
let mut stats = Vec::new();
|
||||
for r in records {
|
||||
let name: &str = r.try_get("name")?;
|
||||
let count: i64 = r.try_get("c")?;
|
||||
let avg: f64 = r.try_get("avg(rating)")?;
|
||||
|
||||
println!("Name: {name}, Ratings: {count}, Average: {avg}");
|
||||
stats.push(UserStats {
|
||||
name: r.try_get("name")?,
|
||||
rating_count: r.try_get("c")?,
|
||||
average_rating: r.try_get("avg(rating)")?,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(stats)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,10 @@ use axum::{
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
routing::get,
|
||||
Router,
|
||||
Json, Router,
|
||||
};
|
||||
use tokio::sync::watch::Sender;
|
||||
use tower_http::services::ServeDir;
|
||||
|
||||
use crate::database::Database;
|
||||
|
||||
@@ -31,6 +32,8 @@ pub async fn http_serve(database: &Database, mpris_producer: Sender<(String, Str
|
||||
};
|
||||
|
||||
let app = Router::new()
|
||||
.fallback_service(ServeDir::new("static"))
|
||||
.route("/stats", get(get_stats))
|
||||
.route("/", get(root))
|
||||
.route("/rating/:rating", get(cache_rating_only))
|
||||
.route("/userid/:user_id", get(add_userid))
|
||||
@@ -127,3 +130,17 @@ async fn add_userid_by_card(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_stats(State(shared): State<SharedState>) -> Response {
|
||||
match shared.database.get_user_most_ratings().await {
|
||||
Ok(stats) => {
|
||||
// axum::Json automatically serializes the Vec<UserStats> into a JSON array
|
||||
// and sets the correct "Content-Type: application/json" headers.
|
||||
(StatusCode::OK, Json(stats)).into_response()
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Database error: {e}");
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Failed to fetch stats").into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user