Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update models and add unique viewers endpoint #194

Merged
merged 16 commits into from
Mar 8, 2024
Merged
1 change: 1 addition & 0 deletions src/endpoints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ pub mod leaderboard;
pub mod quest_boost;
pub mod quests;
pub mod get_boosted_quests;
pub mod unique_page_visit;
46 changes: 46 additions & 0 deletions src/endpoints/unique_page_visit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use std::net::SocketAddr;
use crate::{
models::{AppState},
utils::get_error,
};
use axum::{
extract::{Query, State, ConnectInfo},
http::StatusCode,
response::IntoResponse,
Json,
};
use axum_auto_routes::route;
use mongodb::bson::doc;
use serde::Deserialize;
use std::sync::Arc;
use chrono::Utc;
use mongodb::Collection;
use mongodb::options::UpdateOptions;
use serde_json::json;
use crate::models::UniquePageVisit;

#[derive(Deserialize)]
pub struct GetQuestsQuery {
page_id: String,
}

#[route(get, "/unique_page_visit", crate::endpoints::unique_page_visit)]
pub async fn handler(
State(state): State<Arc<AppState>>,
Query(query): Query<GetQuestsQuery>,
ConnectInfo(addr): ConnectInfo<SocketAddr>,
) -> impl IntoResponse {
let id = query.page_id;
let unique_viewers_collection: Collection<UniquePageVisit> =
state.db.collection("unique_viewers");
let created_at = Utc::now().timestamp_millis();
let filter = doc! { "viewer_ip": addr.to_string(), "viewed_page_id": &id };
let update = doc! { "$setOnInsert": { "viewer_ip": addr.to_string(), "viewed_page_id": &id,"timestamp":created_at } };
let options = UpdateOptions::builder().upsert(true).build();

match unique_viewers_collection.update_one(filter, update, options)
.await {
Ok(_) => (StatusCode::OK, Json(json!({"res": true}))).into_response(),
Err(_) => get_error("unable to detect page visit status".to_string()),
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ async fn main() {
acc.merge(r.to_router(shared_state.clone()))
})
.layer(cors);

let addr = SocketAddr::from(([0, 0, 0, 0], conf.server.port));
println!("server: listening on http://0.0.0.0:{}", conf.server.port);
axum::Server::bind(&addr)
Expand Down
9 changes: 9 additions & 0 deletions src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ pub_struct!(Debug, Serialize, Deserialize; QuestDocument {
pub_struct!(Deserialize; CompletedTasks {
address: String,
task_id: u32,
timestamp: i64,
});

#[derive(Debug, Serialize, Deserialize)]
pub struct CompletedTaskDocument {
address: String,
task_id: u32,
timestamp: i64,
}

pub_struct!(Serialize; Reward {
Expand Down Expand Up @@ -80,6 +82,12 @@ pub_struct!(Deserialize; VerifyQuizQuery {
user_answers_list: Vec<Vec<String>>,
});

pub_struct!(Deserialize; UniquePageVisit {
viewer_ip: String,
viewed_page_id: String,
timestamp: i64,
});

pub_struct!(Deserialize; AchievementQuery {
addr: FieldElement,
});
Expand All @@ -92,6 +100,7 @@ pub_struct!(Deserialize; VerifyAchievementQuery {
pub_struct!(Debug, Serialize, Deserialize; AchievedDocument {
addr: String,
achievement_id: u32,
timestamp:i64,
});

pub_struct!(Debug, Serialize, Deserialize; AchievementDocument {
Expand Down
10 changes: 6 additions & 4 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,9 @@ impl CompletedTasksTrait for AppState {
) -> Result<UpdateResult, mongodb::error::Error> {
let completed_tasks_collection: Collection<CompletedTasks> =
self.db.collection("completed_tasks");
let created_at = Utc::now().timestamp_millis();
let filter = doc! { "address": addr.to_string(), "task_id": task_id };
let update = doc! { "$setOnInsert": { "address": addr.to_string(), "task_id": task_id } };
let update = doc! { "$setOnInsert": { "address": addr.to_string(), "task_id": task_id , "timestamp":created_at} };
let options = UpdateOptions::builder().upsert(true).build();

let result = completed_tasks_collection
Expand Down Expand Up @@ -240,7 +241,7 @@ impl CompletedTasksTrait for AppState {
experience.into(),
timestamp,
)
.await;
.await;
}
Err(_e) => {
get_error("Error querying quests".to_string());
Expand Down Expand Up @@ -292,9 +293,10 @@ impl AchievementsTrait for AppState {
achievement_id: u32,
) -> Result<UpdateResult, mongodb::error::Error> {
let achieved_collection: Collection<CompletedTasks> = self.db.collection("achieved");
let created_at = Utc::now().timestamp_millis();
let filter = doc! { "addr": addr.to_string(), "achievement_id": achievement_id };
let update =
doc! { "$setOnInsert": { "addr": addr.to_string(), "achievement_id": achievement_id } };
doc! { "$setOnInsert": { "addr": addr.to_string(), "achievement_id": achievement_id , "timestamp":created_at } };
let options = UpdateOptions::builder().upsert(true).build();

let result = achieved_collection
Expand Down Expand Up @@ -329,7 +331,7 @@ impl AchievementsTrait for AppState {
experience.into(),
timestamp,
)
.await;
.await;
}
None => {}
}
Expand Down
Loading