From 46d7e71e205a4ac50c3968ec38aacd5496d4f939 Mon Sep 17 00:00:00 2001 From: nicolasito1411 <60229704+Marchand-Nicolas@users.noreply.github.com> Date: Sun, 15 Oct 2023 12:02:36 +0200 Subject: [PATCH] feat: get quest participants --- src/endpoints/get_quest_participants.rs | 100 ++++++++++++++++++++++++ src/endpoints/mod.rs | 1 + src/main.rs | 4 + 3 files changed, 105 insertions(+) create mode 100644 src/endpoints/get_quest_participants.rs diff --git a/src/endpoints/get_quest_participants.rs b/src/endpoints/get_quest_participants.rs new file mode 100644 index 00000000..46c7a85f --- /dev/null +++ b/src/endpoints/get_quest_participants.rs @@ -0,0 +1,100 @@ +use crate::{models::AppState, utils::get_error}; +use axum::{ + extract::{Query, State}, + response::IntoResponse, + Json, +}; + +use futures::StreamExt; +use mongodb::bson::{doc, Document}; +use reqwest::StatusCode; +use serde::{Deserialize, Serialize}; +use std::sync::Arc; + +#[derive(Debug, Serialize, Deserialize)] + +pub struct GetQuestParticipantsQuery { + quest_id: u32, +} + +pub async fn handler( + State(state): State>, + Query(query): Query, +) -> impl IntoResponse { + // Convert to int + let quest_id = query.quest_id.to_string().parse::().unwrap(); + let tasks_collection = state.db.collection::("tasks"); + let tasks_ids = tasks_collection + .find(doc! { "quest_id": quest_id }, None) + .await + .unwrap() + .map(|task_doc| { + task_doc + .unwrap() + .get("id") + .unwrap() + .to_string() + .parse::() + .unwrap() + }) + .collect::>() + .await; + + let pipeline = vec![ + doc! { + "$match": { + "task_id": { + "$in": tasks_ids + } + } + }, + doc! { + "$group": { + "_id": "$address", + } + }, + doc! { + "$facet": { + "count": [ + { + "$count": "count" + } + ], + "firstParticipants": [ + { + "$limit": 3 + } + ] + } + }, + doc! { + "$project": { + "count": { + "$arrayElemAt": [ + "$count.count", + 0 + ] + }, + "firstParticipants": "$firstParticipants._id" + } + }, + ]; + + let completed_tasks_collection = state.db.collection::("completed_tasks"); + let mut cursor = completed_tasks_collection + .aggregate(pipeline, None) + .await + .unwrap(); + + let mut res: Document = Document::new(); + while let Some(result) = cursor.next().await { + match result { + Ok(document) => { + res = document; + } + Err(_) => return get_error("Error querying quest participants".to_string()), + } + } + + return (StatusCode::OK, Json(res)).into_response(); +} diff --git a/src/endpoints/mod.rs b/src/endpoints/mod.rs index 8a8f95df..0e452d55 100644 --- a/src/endpoints/mod.rs +++ b/src/endpoints/mod.rs @@ -1,6 +1,7 @@ pub mod achievements; pub mod get_completed_quests; pub mod get_quest; +pub mod get_quest_participants; pub mod get_quests; pub mod get_quiz; pub mod get_tasks; diff --git a/src/main.rs b/src/main.rs index 20ffa004..6b53773f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -61,6 +61,10 @@ async fn main() { "/get_completed_quests", get(endpoints::get_completed_quests::handler), ) + .route( + "/get_quest_participants", + get(endpoints::get_quest_participants::handler), + ) .route( "/get_trending_quests", get(endpoints::get_trending_quests::handler),