diff --git a/sqlx-data.json b/sqlx-data.json index 493f7238..5400f625 100644 --- a/sqlx-data.json +++ b/sqlx-data.json @@ -1014,6 +1014,27 @@ }, "query": "\n SELECT short, name FROM licenses\n WHERE id = $1\n " }, + "250e7deb143373fc326bb54cf6f82b9790051329b5beb55f5942673d432e2c24": { + "describe": { + "columns": [ + { + "name": "count", + "ordinal": 0, + "type_info": "Int8" + } + ], + "nullable": [ + null + ], + "parameters": { + "Left": [ + "Text", + "Text" + ] + } + }, + "query": "\n SELECT COUNT(id)\n FROM mods\n WHERE\n status = ( SELECT id FROM statuses WHERE status = $1 ) OR\n status = ( SELECT id FROM statuses WHERE status = $2 )\n " + }, "25131559cb73a088000ab6379a769233440ade6c7511542da410065190d203fc": { "describe": { "columns": [ @@ -1867,6 +1888,27 @@ }, "query": "\n UPDATE mods\n SET server_side = $1\n WHERE (id = $2)\n " }, + "4ac5d28c1d3fa26f0a42460ee1e515c3bd4a849fdff4d58c2a138c415186ab3d": { + "describe": { + "columns": [ + { + "name": "count", + "ordinal": 0, + "type_info": "Int8" + } + ], + "nullable": [ + null + ], + "parameters": { + "Left": [ + "Text", + "Text" + ] + } + }, + "query": "\n SELECT COUNT(f.id) FROM files f\n INNER JOIN versions v on f.version_id = v.id\n INNER JOIN mods m on v.mod_id = m.id\n WHERE\n status = ( SELECT id FROM statuses WHERE status = $1 ) OR\n status = ( SELECT id FROM statuses WHERE status = $2 )\n " + }, "4b14b5c69f6a0ee4e06e41d7cea425c7c34d6db45895275a2ce8adfa28dc8f72": { "describe": { "columns": [ @@ -3528,6 +3570,27 @@ }, "query": "\n SELECT u.id, u.name, u.email,\n u.avatar_url, u.username, u.bio,\n u.created, u.role, u.badges,\n u.balance, u.payout_wallet, u.payout_wallet_type,\n u.payout_address\n FROM users u\n WHERE u.github_id = $1\n " }, + "8a4d05106f27de01a1a8ebf5266727b71fa5b6a34b48cd9ba3996fe8ec1ab78a": { + "describe": { + "columns": [ + { + "name": "count", + "ordinal": 0, + "type_info": "Int8" + } + ], + "nullable": [ + null + ], + "parameters": { + "Left": [ + "Text", + "Text" + ] + } + }, + "query": "\n SELECT COUNT(DISTINCT u.id)\n FROM users u\n INNER JOIN team_members tm on u.id = tm.user_id AND tm.accepted = TRUE\n INNER JOIN mods m on tm.team_id = m.team_id AND (\n m.status = ( SELECT s.id FROM statuses s WHERE s.status = $1 ) OR\n m.status = ( SELECT s.id FROM statuses s WHERE s.status = $2 )\n )\n " + }, "8a7b2bc070e5e8308e2853ff125bc98f40b22c1d0deeb013dd90ce5768bd0ce8": { "describe": { "columns": [], @@ -6815,6 +6878,27 @@ }, "query": "\n SELECT short, name FROM donation_platforms\n WHERE id = $1\n " }, + "fb81707d46632f5733222bc3d9c4c5574366db130b130263fcb0eabcf7983b78": { + "describe": { + "columns": [ + { + "name": "count", + "ordinal": 0, + "type_info": "Int8" + } + ], + "nullable": [ + null + ], + "parameters": { + "Left": [ + "Text", + "Text" + ] + } + }, + "query": "\n SELECT COUNT(v.id)\n FROM versions v\n INNER JOIN mods m on v.mod_id = m.id\n WHERE\n status = ( SELECT id FROM statuses WHERE status = $1 ) OR\n status = ( SELECT id FROM statuses WHERE status = $2 )\n " + }, "fb955ca41b95120f66c98c0b528b1db10c4be4a55e9641bb104d772e390c9bb7": { "describe": { "columns": [ diff --git a/src/routes/mod.rs b/src/routes/mod.rs index cd723b33..6eccca29 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -13,6 +13,7 @@ mod notifications; pub(crate) mod project_creation; mod projects; mod reports; +mod statistics; mod tags; mod teams; mod updates; @@ -42,6 +43,7 @@ pub fn v2_config(cfg: &mut web::ServiceConfig) { .configure(moderation_config) .configure(reports_config) .configure(notifications_config) + .configure(statistics_config) .configure(admin_config) .configure(midas_config), ); @@ -169,6 +171,10 @@ pub fn reports_config(cfg: &mut web::ServiceConfig) { cfg.service(reports::delete_report); } +pub fn statistics_config(cfg: &mut web::ServiceConfig) { + cfg.service(statistics::get_stats); +} + pub fn admin_config(cfg: &mut web::ServiceConfig) { cfg.service( web::scope("admin") diff --git a/src/routes/statistics.rs b/src/routes/statistics.rs new file mode 100644 index 00000000..4cd1f664 --- /dev/null +++ b/src/routes/statistics.rs @@ -0,0 +1,77 @@ +use crate::routes::ApiError; +use actix_web::{get, web, HttpResponse}; +use serde_json::json; +use sqlx::PgPool; + +#[get("statistics")] +pub async fn get_stats( + pool: web::Data, +) -> Result { + let projects = sqlx::query!( + " + SELECT COUNT(id) + FROM mods + WHERE + status = ( SELECT id FROM statuses WHERE status = $1 ) OR + status = ( SELECT id FROM statuses WHERE status = $2 ) + ", + crate::models::projects::ProjectStatus::Approved.as_str(), + crate::models::projects::ProjectStatus::Archived.as_str() + ) + .fetch_one(&**pool); + + let versions = sqlx::query!( + " + SELECT COUNT(v.id) + FROM versions v + INNER JOIN mods m on v.mod_id = m.id + WHERE + status = ( SELECT id FROM statuses WHERE status = $1 ) OR + status = ( SELECT id FROM statuses WHERE status = $2 ) + ", + crate::models::projects::ProjectStatus::Approved.as_str(), + crate::models::projects::ProjectStatus::Archived.as_str() + ) + .fetch_one(&**pool); + + let authors = sqlx::query!( + " + SELECT COUNT(DISTINCT u.id) + FROM users u + INNER JOIN team_members tm on u.id = tm.user_id AND tm.accepted = TRUE + INNER JOIN mods m on tm.team_id = m.team_id AND ( + m.status = ( SELECT s.id FROM statuses s WHERE s.status = $1 ) OR + m.status = ( SELECT s.id FROM statuses s WHERE s.status = $2 ) + ) + ", + crate::models::projects::ProjectStatus::Approved.as_str(), + crate::models::projects::ProjectStatus::Archived.as_str() + ) + .fetch_one(&**pool); + + let files = sqlx::query!( + " + SELECT COUNT(f.id) FROM files f + INNER JOIN versions v on f.version_id = v.id + INNER JOIN mods m on v.mod_id = m.id + WHERE + status = ( SELECT id FROM statuses WHERE status = $1 ) OR + status = ( SELECT id FROM statuses WHERE status = $2 ) + ", + crate::models::projects::ProjectStatus::Approved.as_str(), + crate::models::projects::ProjectStatus::Archived.as_str() + ) + .fetch_one(&**pool); + + let (projects, versions, authors, files) = + futures::future::try_join4(projects, versions, authors, files).await?; + + let json = json!({ + "projects": projects.count, + "versions": versions.count, + "authors": authors.count, + "files": files.count, + }); + + Ok(HttpResponse::Ok().json(json)) +}