-
Notifications
You must be signed in to change notification settings - Fork 21
Added cp leaderboard queries and mutations #97
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
base: develop
Are you sure you want to change the base?
Changes from all commits
d9a99a9
cd1d4f4
6fdecfa
510ec51
b2ca749
5ab6a16
6b26312
f9a7c1c
1fa7ddf
eee5622
967cbd9
9e5fb66
43f7cea
bc8a7ea
6bf7b72
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,3 +5,4 @@ Secrets*.toml | |
| backups/ | ||
| .env | ||
| *.log | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| -- Add migration script here | ||
|
|
||
| CREATE TABLE IF NOT EXISTS leaderboard ( | ||
| id SERIAL PRIMARY KEY, | ||
| member_id INT UNIQUE NOT NULL, | ||
| leetcode_score INT, | ||
| codeforces_score INT, | ||
| unified_score INT NOT NULL, | ||
| last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | ||
| FOREIGN KEY (member_id) REFERENCES member(member_id) | ||
| ); | ||
|
|
||
| CREATE TABLE IF NOT EXISTS leetcode_stats ( | ||
| id SERIAL PRIMARY KEY, | ||
| member_id INT UNIQUE NOT NULL, | ||
| leetcode_username VARCHAR(255) NOT NULL, | ||
| problems_solved INT NOT NULL, | ||
| easy_solved INT NOT NULL, | ||
| medium_solved INT NOT NULL, | ||
| hard_solved INT NOT NULL, | ||
| contests_participated INT NOT NULL, | ||
| best_rank INT NOT NULL, | ||
| total_contests INT NOT NULL, | ||
| FOREIGN KEY (member_id) REFERENCES member(member_id) | ||
| ); | ||
|
|
||
| CREATE TABLE IF NOT EXISTS codeforces_stats ( | ||
| id SERIAL PRIMARY KEY, | ||
| member_id INT UNIQUE NOT NULL, | ||
| codeforces_handle VARCHAR(255) NOT NULL, | ||
| codeforces_rating INT NOT NULL, | ||
| max_rating INT NOT NULL, | ||
| contests_participated INT NOT NULL, | ||
| FOREIGN KEY (member_id) REFERENCES member(member_id) | ||
| ); | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "dependencies": { | ||
| "@apollo/client": "^3.13.4", | ||
| "graphiql": "^3.8.3", | ||
| "graphql": "^16.10.0" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,17 @@ | ||
| use crate::graphql::api::{ | ||
| fetch_and_update_codeforces_stats, fetch_and_update_leetcode, update_leaderboard_scores, | ||
| }; | ||
| use chrono::NaiveTime; | ||
| use chrono_tz::Asia::Kolkata; | ||
| use sqlx::PgPool; | ||
| use std::sync::Arc; | ||
| use tokio::time::sleep_until; | ||
| use tracing::{debug, error, info}; | ||
|
|
||
| use crate::models::member::Member; | ||
| use crate::models::{ | ||
| leaderboard::{CodeforcesStats, LeetCodeStats}, | ||
| member::Member, | ||
| }; | ||
|
|
||
| pub async fn run_daily_task_at_midnight(pool: Arc<PgPool>) { | ||
| loop { | ||
|
|
@@ -47,12 +53,68 @@ async fn execute_daily_task(pool: Arc<PgPool>) { | |
| Ok(members) => { | ||
| update_attendance(&members, &pool).await; | ||
| update_status_history(&members, &pool).await; | ||
| update_leaderboard_task(pool.clone()).await; | ||
| } | ||
| // TODO: Handle this | ||
| Err(e) => error!("Failed to fetch members: {:?}", e), | ||
| }; | ||
| } | ||
|
|
||
| pub async fn update_leaderboard_task(pool: Arc<PgPool>) { | ||
| #[allow(deprecated)] | ||
| let today = chrono::Utc::now() | ||
| .with_timezone(&Kolkata) | ||
| .date() | ||
| .naive_local(); | ||
| debug!("Updating leaderboard on {}", today); | ||
|
|
||
| let members: Result<Vec<Member>, sqlx::Error> = | ||
| sqlx::query_as::<_, Member>("SELECT * FROM Member") | ||
| .fetch_all(pool.as_ref()) | ||
| .await; | ||
|
|
||
| match members { | ||
| Ok(members) => { | ||
| for member in &members { | ||
| // Update LeetCode stats | ||
| if let Ok(Some(leetcode_stats)) = sqlx::query_as::<_, LeetCodeStats>( | ||
| "SELECT leetcode_username FROM leetcode_stats WHERE member_id = $1 AND leetcode_username IS NOT NULL AND leetcode_username != ''", | ||
| ) | ||
| .bind(member.member_id) | ||
| .fetch_optional(pool.as_ref()) | ||
| .await { | ||
|
Comment on lines
+80
to
+85
|
||
| let username = leetcode_stats.leetcode_username.clone(); | ||
|
|
||
| match fetch_and_update_leetcode(pool.clone(), member.member_id, &username).await { | ||
| Ok(_) => debug!("LeetCode stats updated for member ID: {}", member.member_id), | ||
| Err(e) => error!("Failed to update LeetCode stats for member ID {}: {:?}", member.member_id, e), | ||
| } | ||
| } | ||
|
|
||
| if let Ok(Some(codeforces_stats)) = sqlx::query_as::<_, CodeforcesStats>( | ||
| "SELECT codeforces_handle FROM codeforces_stats WHERE member_id = $1 AND codeforces_handle IS NOT NULL AND codeforces_handle != ''", | ||
| ) | ||
| .bind(member.member_id) | ||
| .fetch_optional(pool.as_ref()) | ||
| .await { | ||
|
Comment on lines
+94
to
+99
|
||
| let username = codeforces_stats.codeforces_handle.clone(); | ||
|
|
||
| match fetch_and_update_codeforces_stats(pool.clone(), member.member_id, &username).await { | ||
| Ok(_) => debug!("Codeforces stats updated for member ID: {}", member.member_id), | ||
| Err(e) => error!("Failed to update Codeforces stats for member ID {}: {:?}", member.member_id, e), | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+78
to
+107
|
||
|
|
||
| match update_leaderboard_scores(pool.clone()).await { | ||
| Ok(_) => debug!("Leaderboard updated successfully."), | ||
| Err(e) => error!("Failed to update leaderboard: {e:?}"), | ||
| } | ||
| } | ||
| Err(e) => error!("Failed to fetch members: {e:?}"), | ||
| } | ||
| } | ||
|
|
||
| async fn update_attendance(members: &Vec<Member>, pool: &PgPool) { | ||
| #[allow(deprecated)] | ||
| let today = chrono::Utc::now() | ||
|
|
@@ -104,7 +166,7 @@ async fn update_status_history(members: &Vec<Member>, pool: &PgPool) { | |
|
|
||
| for member in members { | ||
| let status_update = sqlx::query( | ||
| "INSERT INTO StatusUpdateHistory (member_id, date, is_updated) | ||
| "INSERT INTO StatusUpdateHistory (member_id, date, is_updated) | ||
| VALUES ($1, $2, $3) | ||
| ON CONFLICT (member_id, date) DO NOTHING", | ||
| ) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.