diff --git a/src/endpoints/get_quests.rs b/src/endpoints/get_quests.rs index c86a2025..094f6d41 100644 --- a/src/endpoints/get_quests.rs +++ b/src/endpoints/get_quests.rs @@ -13,6 +13,7 @@ use futures::TryStreamExt; use mongodb::bson; use mongodb::bson::doc; use serde::{Deserialize, Serialize}; +use std::collections::HashMap; use std::sync::Arc; #[derive(Debug, Serialize, Deserialize)] @@ -48,9 +49,10 @@ pub async fn handler(State(state): State>) -> impl IntoResponse { } ] }; + match collection.find(Some(filter), None).await { Ok(cursor) => { - let quests: Vec = cursor + let quests_temp: Vec = cursor .map(|result| { result.map(|mut quest: QuestDocument| { if let Some(expiry) = &quest.expiry { @@ -63,10 +65,21 @@ pub async fn handler(State(state): State>) -> impl IntoResponse { .try_collect() .await .unwrap_or_else(|_| vec![]); - if quests.is_empty() { + let mut res: HashMap> = HashMap::new(); + for quest in quests_temp { + let category = quest.category.clone(); + if res.contains_key(&category) { + let quests = res.get_mut(&category).unwrap(); + quests.push(quest); + } else { + res.insert(category, vec![quest]); + } + } + + if res.is_empty() { get_error("No quests found".to_string()) } else { - (StatusCode::OK, Json(quests)).into_response() + (StatusCode::OK, Json(res)).into_response() } } Err(_) => get_error("Error querying quests".to_string()), diff --git a/src/endpoints/get_trending_quests.rs b/src/endpoints/get_trending_quests.rs new file mode 100644 index 00000000..64885c9f --- /dev/null +++ b/src/endpoints/get_trending_quests.rs @@ -0,0 +1,77 @@ +use crate::{ + models::{AppState, QuestDocument}, + utils::get_error, +}; +use axum::{ + extract::State, + http::StatusCode, + response::{IntoResponse, Json}, +}; +use chrono::Utc; +use futures::StreamExt; +use futures::TryStreamExt; +use mongodb::bson; +use mongodb::bson::doc; +use serde::{Deserialize, Serialize}; +use std::sync::Arc; + +#[derive(Debug, Serialize, Deserialize)] +pub struct NFTItem { + img: String, + level: u32, +} + +pub async fn handler(State(state): State>) -> impl IntoResponse { + let collection = state.db.collection::("quests"); + let current_timestamp = bson::DateTime::from_millis(Utc::now().timestamp_millis()); + let filter = doc! { + "$and": [ + { + "$or": [ + { + "expiry": { + "$exists": false + } + }, + { + "expiry": { + "$gt": current_timestamp + } + } + ] + }, + { + "disabled": false + }, + { + "hidden": false + }, + { + "is_trending": true + } + ] + }; + match collection.find(Some(filter), None).await { + Ok(cursor) => { + let quests: Vec = cursor + .map(|result| { + result.map(|mut quest: QuestDocument| { + if let Some(expiry) = &quest.expiry { + let timestamp = expiry.timestamp_millis().to_string(); + quest.expiry_timestamp = Some(timestamp); + } + quest + }) + }) + .try_collect() + .await + .unwrap_or_else(|_| vec![]); + if quests.is_empty() { + get_error("No quests found".to_string()) + } else { + (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 5325e4a1..b403144a 100644 --- a/src/endpoints/mod.rs +++ b/src/endpoints/mod.rs @@ -3,4 +3,5 @@ pub mod get_quest; pub mod get_quests; pub mod get_quiz; pub mod get_tasks; +pub mod get_trending_quests; pub mod quests; diff --git a/src/main.rs b/src/main.rs index 77306ac2..7f6c349d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -70,6 +70,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_trending_quests", + get(endpoints::get_trending_quests::handler), + ) .route("/get_tasks", get(endpoints::get_tasks::handler)) .route( "/quests/starknetid/claimable",