From 81ddcc74a71d55917e36a1448228f35618edd541 Mon Sep 17 00:00:00 2001 From: nicolasito1411 <60229704+Marchand-Nicolas@users.noreply.github.com> Date: Sat, 30 Sep 2023 14:46:26 +0200 Subject: [PATCH] feat: get_completed_quests route --- src/endpoints/get_completed_quests.rs | 90 +++++++++++++++++++++++++++ src/endpoints/mod.rs | 1 + src/main.rs | 6 +- 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/endpoints/get_completed_quests.rs diff --git a/src/endpoints/get_completed_quests.rs b/src/endpoints/get_completed_quests.rs new file mode 100644 index 00000000..b0ee14ff --- /dev/null +++ b/src/endpoints/get_completed_quests.rs @@ -0,0 +1,90 @@ +use crate::{models::AppState, utils::get_error}; +use axum::{ + extract::{Query, State}, + response::IntoResponse, + Json, +}; + +use futures::TryStreamExt; +use mongodb::bson::{doc, Document}; +use reqwest::StatusCode; +use serde::{Deserialize, Serialize}; +use starknet::core::types::FieldElement; +use std::sync::Arc; + +#[derive(Debug, Serialize, Deserialize)] + +pub struct GetCompletedQuestsQuery { + addr: FieldElement, +} + +pub async fn handler( + State(state): State>, + Query(query): Query, +) -> impl IntoResponse { + let address = query.addr.to_string(); + println!("address: {}", address); + let pipeline = vec![ + doc! { + "$match": doc! { + "address": address + } + }, + doc! { + "$lookup": doc! { + "from": "tasks", + "localField": "task_id", + "foreignField": "id", + "as": "associatedTask" + } + }, + doc! { + "$unwind": "$associatedTask" + }, + doc! { + "$group": doc! { + "_id": "$associatedTask.quest_id", + "done": doc! { + "$sum": 1 + } + } + }, + doc! { + "$lookup": doc! { + "from": "tasks", + "localField": "_id", + "foreignField": "quest_id", + "as": "tasks" + } + }, + doc! { + "$match": doc! { + "$expr": doc! { + "$eq": [ + "$done", + doc! { + "$size": "$tasks" + } + ] + } + } + }, + doc! { + "$project": doc! { + "quest_id": "$_id", + "_id": 0 + } + }, + ]; + let tasks_collection = state.db.collection::("completed_tasks"); + match tasks_collection.aggregate(pipeline, None).await { + Ok(mut cursor) => { + let mut quests: Vec = Vec::new(); + while let Some(result) = cursor.try_next().await.unwrap() { + quests.push(result); + } + (StatusCode::OK, Json(quests)).into_response() + } + Err(_) => get_error("Error querying quests".to_string()), + } +} diff --git a/src/endpoints/mod.rs b/src/endpoints/mod.rs index b403144a..8a8f95df 100644 --- a/src/endpoints/mod.rs +++ b/src/endpoints/mod.rs @@ -1,4 +1,5 @@ pub mod achievements; +pub mod get_completed_quests; pub mod get_quest; pub mod get_quests; pub mod get_quiz; diff --git a/src/main.rs b/src/main.rs index ee2b2633..513e7061 100644 --- a/src/main.rs +++ b/src/main.rs @@ -74,6 +74,10 @@ async fn main() { .route("/get_quiz", get(endpoints::get_quiz::handler)) .route("/get_quest", get(endpoints::get_quest::handler)) .route("/get_quests", get(endpoints::get_quests::handler)) + .route( + "/get_completed_quests", + get(endpoints::get_completed_quests::handler), + ) .route( "/get_trending_quests", get(endpoints::get_trending_quests::handler), @@ -250,7 +254,7 @@ async fn main() { .with_state(shared_state) .layer(cors); - let addr = SocketAddr::from(([0, 0, 0, 0], conf.server.port)); + let addr = SocketAddr::from(([127, 0, 0, 1], conf.server.port)); println!("server: listening on http://0.0.0.0:{}", conf.server.port); axum::Server::bind(&addr) .serve(app.into_make_service_with_connect_info::())