@@ -4,10 +4,18 @@ use sqlx::PgPool;
4
4
use std:: sync:: Arc ;
5
5
use tokio:: time:: sleep_until;
6
6
use tracing:: { debug, error, info} ;
7
+ use async_graphql:: Context ;
8
+ use crate :: {
9
+ models:: {
10
+ leaderboard:: { CodeforcesStats , LeetCodeStats } ,
11
+ member:: Member ,
12
+ } ,
13
+ graphql:: mutations:: {
14
+ LeaderboardMutation , FetchCodeForces , FetchLeetCode ,
15
+ } ,
16
+ } ;
7
17
8
- use crate :: models:: member:: Member ;
9
-
10
- pub async fn run_daily_task_at_midnight ( pool : Arc < PgPool > ) {
18
+ pub async fn run_daily_task_at_midnight ( pool : Arc < PgPool > , ctx : & Context < ' _ > ) {
11
19
loop {
12
20
let now = chrono:: Utc :: now ( ) . with_timezone ( & Kolkata ) ;
13
21
let naive_midnight =
@@ -30,14 +38,14 @@ pub async fn run_daily_task_at_midnight(pool: Arc<PgPool>) {
30
38
tokio:: time:: Duration :: from_secs ( duration_until_midnight. num_seconds ( ) as u64 ) ;
31
39
32
40
sleep_until ( tokio:: time:: Instant :: now ( ) + sleep_duration) . await ;
33
- execute_daily_task ( pool. clone ( ) ) . await ;
41
+ execute_daily_task ( pool. clone ( ) , ctx ) . await ;
34
42
}
35
43
}
36
44
37
45
/// This function does a number of things, including:
38
46
/// * Insert new attendance records everyday for [`presense`](https://www.github.com/amfoss/presense) to update them later in the day.
39
47
/// * Update the AttendanceSummary table
40
- async fn execute_daily_task ( pool : Arc < PgPool > ) {
48
+ async fn execute_daily_task ( pool : Arc < PgPool > , ctx : & Context < ' _ > ) {
41
49
// Members is queried outside of each function to avoid repetition
42
50
let members = sqlx:: query_as :: < _ , Member > ( "SELECT * FROM Member" )
43
51
. fetch_all ( & * pool)
@@ -47,13 +55,78 @@ async fn execute_daily_task(pool: Arc<PgPool>) {
47
55
Ok ( members) => {
48
56
update_attendance ( & members, & pool) . await ;
49
57
update_status_history ( & members, & pool) . await ;
58
+ update_leaderboard_task ( pool. clone ( ) , ctx) . await ;
50
59
}
51
60
// TODO: Handle this
52
61
Err ( e) => error ! ( "Failed to fetch members: {:?}" , e) ,
53
62
} ;
54
63
}
55
64
56
- async fn update_attendance ( members : & Vec < Member > , pool : & PgPool ) {
65
+ pub async fn update_leaderboard_task ( pool : Arc < PgPool > , ctx : & Context < ' _ > ) {
66
+ let members: Result < Vec < Member > , sqlx:: Error > =
67
+ sqlx:: query_as :: < _ , Member > ( "SELECT id FROM Member" )
68
+ . fetch_all ( pool. as_ref ( ) )
69
+ . await ;
70
+
71
+ match members {
72
+ Ok ( members) => {
73
+ for member in members {
74
+ // Fetch LeetCode username
75
+ let leetcode_username = sqlx:: query_as :: < _ , LeetCodeStats > (
76
+ "SELECT leetcode_username FROM leetcode_stats WHERE member_id = $1" ,
77
+ )
78
+ . bind ( member. member_id )
79
+ . fetch_optional ( pool. as_ref ( ) )
80
+ . await ;
81
+
82
+ if let Ok ( Some ( leetcode_stats) ) = leetcode_username {
83
+ let username = leetcode_stats. leetcode_username . clone ( ) ;
84
+
85
+ // Fetch and update LeetCode stats
86
+ match FetchLeetCode :: fetch_leetcode_stats ( & FetchLeetCode , ctx, member. member_id , username) . await {
87
+ Ok ( _) => println ! ( "LeetCode stats updated for member ID: {}" , member. member_id) ,
88
+ Err ( e) => eprintln ! (
89
+ "Failed to update LeetCode stats for member ID {}: {:?}" ,
90
+ member. member_id, e
91
+ ) ,
92
+ }
93
+ }
94
+
95
+ // Fetch Codeforces username
96
+ let codeforces_username = sqlx:: query_as :: < _ , CodeforcesStats > (
97
+ "SELECT codeforces_handle FROM codeforces_stats WHERE member_id = $1" ,
98
+ )
99
+ . bind ( member. member_id )
100
+ . fetch_optional ( pool. as_ref ( ) )
101
+ . await ;
102
+
103
+ if let Ok ( Some ( codeforces_stats) ) = codeforces_username {
104
+ let username = codeforces_stats. codeforces_handle . clone ( ) ;
105
+
106
+ // Fetch and update Codeforces stats
107
+ match FetchCodeForces :: fetch_codeforces_stats ( & FetchCodeForces , ctx, member. member_id , username) . await {
108
+ Ok ( _) => println ! ( "Codeforces stats updated for member ID: {}" , member. member_id) ,
109
+ Err ( e) => eprintln ! (
110
+ "Failed to update Codeforces stats for member ID {}: {:?}" ,
111
+ member. member_id, e
112
+ ) ,
113
+ }
114
+ }
115
+
116
+ // Update leaderboard
117
+ match LeaderboardMutation . update_leaderboard ( ctx) . await {
118
+ Ok ( _) => println ! ( "Leaderboard updated." ) ,
119
+ Err ( e) => eprintln ! ( "Failed to update leaderboard: {:?}" , e) ,
120
+ }
121
+ }
122
+ }
123
+ Err ( e) => eprintln ! ( "Failed to fetch members: {:?}" , e) ,
124
+ }
125
+ }
126
+
127
+
128
+
129
+ async fn update_attendance ( members : Vec < Member > , pool : & PgPool ) {
57
130
#[ allow( deprecated) ]
58
131
let today = chrono:: Utc :: now ( )
59
132
. with_timezone ( & Kolkata )
@@ -129,4 +202,4 @@ async fn update_status_history(members: &Vec<Member>, pool: &PgPool) {
129
202
}
130
203
}
131
204
}
132
- }
205
+ }
0 commit comments