Skip to content

Commit

Permalink
feat: add leaderboard updated endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
ayushtom committed Jan 4, 2024
1 parent ee2f22c commit fbd6ff8
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 51 deletions.
52 changes: 20 additions & 32 deletions src/endpoints/leaderboard/get_ranking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,26 @@ use axum::{
Json,
};

use crate::utils::get_timestamp_from_days;
use axum::http::{header, Response};
use chrono::Utc;
use futures::TryStreamExt;
use mongodb::bson::{doc, Document};
use mongodb::Collection;
use reqwest::StatusCode;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use axum::http::{header, Response};
use chrono::Utc;

pub async fn get_user_rank(
collection: &Collection<Document>,
address: &String,
start_timestamp: &i64,
end_timestamp: &i64,
timestamp: &i64,
) -> Document {
let user_rank_pipeline = vec![
doc! {
"$match": doc! {
"timestamp": doc! {
"$gte": start_timestamp,
"$lte": end_timestamp
"$gte": timestamp,
}
}
},
Expand Down Expand Up @@ -232,28 +231,24 @@ pub struct GetCompletedQuestsQuery {
*/
shift: i64,

/*
start of the timestamp range
-> How many days back you want to start the leaderboard
*/
start_timestamp: i64,

/*
end of the timestamp range
-> When do you want to end it (ideally the moment the frontend makes the request till that timestamp)
*/
end_timestamp: i64,
duration: String,
}

pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<GetCompletedQuestsQuery>,
) -> impl IntoResponse {
let start_timestamp = query.start_timestamp;
let end_timestamp = query.end_timestamp;

if start_timestamp > end_timestamp {
return get_error("Error querying ranks".to_string());
let mut time_gap = 0;

// check value of duration and set time_gap accordingly
if query.duration == "week" {
time_gap = get_timestamp_from_days(7);
} else if query.duration == "month" {
time_gap = get_timestamp_from_days(30);
} else if query.duration == "all" {
time_gap = 0;
} else {
return get_error("Invalid duration".to_string());
}

// get collection
Expand All @@ -265,13 +260,7 @@ pub async fn handler(
let shift = query.shift;

// get user rank and total users
let stats = get_user_rank(
&users_collection,
&address,
&start_timestamp,
&end_timestamp,
)
.await;
let stats = get_user_rank(&users_collection, &address, &time_gap).await;
let total_users = stats.get("total_users").unwrap().as_i32().unwrap() as i64;
let user_rank = stats.get("user_rank").unwrap().as_i32().unwrap() as i64;

Expand Down Expand Up @@ -315,8 +304,7 @@ pub async fn handler(
doc! {
"$match": doc!{
"timestamp": doc!{
"$gte": start_timestamp,
"$lte": end_timestamp
"$gte": time_gap,
}
}
},
Expand Down Expand Up @@ -368,7 +356,7 @@ pub async fn handler(
"first_elt_position".to_string(),
if lower_range == 0 { 1 } else { lower_range },
);

// Set caching response
let expires = Utc::now() + chrono::Duration::minutes(5);
let caching_response = Response::builder()
Expand Down
35 changes: 17 additions & 18 deletions src/endpoints/leaderboard/get_static_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,24 @@ use axum::{
Json,
};

use crate::utils::get_timestamp_from_days;
use axum::http::header;
use axum::response::Response;
use chrono::Utc;
use futures::TryStreamExt;
use mongodb::bson::{doc, Document};
use reqwest::StatusCode;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use axum::http::header;
use axum::response::Response;
use chrono::Utc;

#[derive(Debug, Serialize, Deserialize)]
pub struct GetLeaderboardInfoQuery {
/*
user address
*/
addr: String,
/*
start of the timestamp range
-> How many days back you want to start the leaderboard
*/
start_timestamp: i64,

/*
end of the timestamp range
-> When do you want to end it (ideally the moment the frontend makes the request till that timestamp)
*/
end_timestamp: i64,
duration: String,
}

pub async fn handler(
Expand All @@ -47,9 +39,18 @@ pub async fn handler(
) -> impl IntoResponse {
let addr: String = query.addr.to_string();
let collection = state.db.collection::<Document>("leaderboard_table");
let start_timestamp = query.start_timestamp;
let end_timestamp = query.end_timestamp;
let mut time_gap = 0;

// check value of duration and set time_gap accordingly
if query.duration == "week" {
time_gap = get_timestamp_from_days(7);
} else if query.duration == "month" {
time_gap = get_timestamp_from_days(30);
} else if query.duration == "all" {
time_gap = 0;
} else {
return get_error("Invalid duration".to_string());
}

let leaderboard_pipeline = vec![
doc! {
Expand All @@ -62,8 +63,7 @@ pub async fn handler(
doc! {
"$match": doc! {
"timestamp": doc! {
"$gte": start_timestamp,
"$lte": end_timestamp
"$gte": time_gap,
}
}
},
Expand Down Expand Up @@ -154,7 +154,6 @@ pub async fn handler(
return match collection.aggregate(leaderboard_pipeline, None).await {
Ok(mut cursor) => {
while let Some(result) = cursor.try_next().await.unwrap() {

// Set caching response
let expires = Utc::now() + chrono::Duration::minutes(5);
let caching_response = Response::builder()
Expand Down
13 changes: 12 additions & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use axum::{
http::{Response as HttpResponse, StatusCode, Uri},
response::{IntoResponse, Response},
};
use chrono::Utc;
use futures::TryStreamExt;
use mongodb::{
bson::doc, options::UpdateOptions, results::UpdateResult, Collection, Cursor, Database,
Expand All @@ -25,8 +24,10 @@ use starknet::{
use std::fmt::Write;
use std::result::Result;
use std::str::FromStr;
use chrono::{Duration as dur, Utc};
use tokio::time::{sleep, Duration};


#[macro_export]
macro_rules! pub_struct {
($($derive:path),*; $name:ident {$($field:ident: $t:ty),* $(,)?}) => {
Expand Down Expand Up @@ -349,6 +350,16 @@ pub trait DeployedTimesTrait {
) -> Result<UpdateResult, mongodb::error::Error>;
}

pub fn get_timestamp_from_days(days: i64) -> i64 {
// take input as week , month and all time and return the timestamp range
let time_gap = if days > 0 {
(Utc::now() - dur::days(days)).timestamp_millis()
} else {
0
};
time_gap
}

#[async_trait]
impl DeployedTimesTrait for AppState {
async fn upsert_deployed_timestamp(
Expand Down

0 comments on commit fbd6ff8

Please sign in to comment.