|
1 |
| -use chrono::{Datelike, Local, NaiveDate, NaiveTime}; |
| 1 | +use chrono::{Datelike, NaiveDate, NaiveTime}; |
2 | 2 | use chrono_tz::Asia::Kolkata;
|
3 | 3 | use sqlx::PgPool;
|
4 | 4 | use std::sync::Arc;
|
5 | 5 | use tokio::time::sleep_until;
|
6 |
| -use tracing::{debug, error}; |
| 6 | +use tracing::{debug, error, info}; |
7 | 7 |
|
8 | 8 | use crate::models::member::Member;
|
9 | 9 |
|
10 | 10 | /// Continuously sleep till midnight, then run the 'execute_daily_task' function.
|
11 | 11 | pub async fn run_daily_task_at_midnight(pool: Arc<PgPool>) {
|
12 | 12 | loop {
|
13 |
| - let now = chrono::Local::now().with_timezone(&Kolkata); |
14 |
| - let next_midnight = (now + chrono::Duration::days(1)) |
15 |
| - .date_naive() |
16 |
| - .and_hms_opt(0, 30, 0) |
17 |
| - .unwrap(); |
18 |
| - |
19 |
| - let duration_until_midnight = next_midnight.signed_duration_since(now.naive_local()); |
| 13 | + let now = chrono::Utc::now().with_timezone(&Kolkata); |
| 14 | + let naive_midnight = |
| 15 | + NaiveTime::from_hms_opt(00, 30, 00).expect("Hardcoded time must be valid"); |
| 16 | + let today_midnight = now |
| 17 | + .with_time(naive_midnight) |
| 18 | + .single() |
| 19 | + .expect("Hardcoded time must be valid"); |
| 20 | + |
| 21 | + let next_midnight = if now >= today_midnight { |
| 22 | + today_midnight + chrono::Duration::days(1) |
| 23 | + } else { |
| 24 | + today_midnight |
| 25 | + }; |
| 26 | + debug!("next_midnight: {}", next_midnight); |
| 27 | + |
| 28 | + let duration_until_midnight = next_midnight.signed_duration_since(now); |
| 29 | + info!("Sleeping for {}", duration_until_midnight.num_seconds()); |
20 | 30 | let sleep_duration =
|
21 | 31 | tokio::time::Duration::from_secs(duration_until_midnight.num_seconds() as u64);
|
22 | 32 |
|
@@ -45,8 +55,8 @@ async fn execute_daily_task(pool: Arc<PgPool>) {
|
45 | 55 | // We need to add a record for every member because otherwise [`Presense`](https://www.github.com/presense) will only add present members to the DB, and we will have to JOIN Members and Attendance records for the day to get the absent members. In exchange for increased storage use, we get simpler queries for Home which needs the data for every member for every day so far. But as of Jan 2025, there are less than 50 members in the club and thus storage really shouldn't be an issue.
|
46 | 56 | /// Inserts new attendance records everyday for [`presense`](https://www.github.com/amfoss/presense) to update them later in the day and updates the AttendanceSummary table to keep track of monthly streaks.
|
47 | 57 | async fn update_attendance(members: Vec<Member>, pool: &PgPool) {
|
48 |
| - debug!("Updating attendance..."); |
49 |
| - let today = Local::now().with_timezone(&Kolkata).date_naive(); |
| 58 | + let today = chrono::Utc::now().with_timezone(&Kolkata).date_naive(); |
| 59 | + debug!("Updating attendance on {}", today); |
50 | 60 |
|
51 | 61 | for member in members {
|
52 | 62 | // Insert blank rows for each member
|
@@ -86,8 +96,8 @@ async fn update_attendance(members: Vec<Member>, pool: &PgPool) {
|
86 | 96 | /// Checks if the member was present yesterday, and if so, increments the `days_attended` value. Otherwise, do nothing.
|
87 | 97 | async fn update_attendance_summary(member_id: i32, pool: &PgPool) {
|
88 | 98 | debug!("Updating summary for member #{}", member_id);
|
89 |
| - let today = chrono::Local::now().with_timezone(&Kolkata).date_naive(); |
90 |
| - let yesterday = today.checked_sub_signed(chrono::Duration::days(1)).unwrap(); // Get yesterday's date |
| 99 | + let today = chrono::Utc::now().with_timezone(&Kolkata).date_naive(); |
| 100 | + let yesterday = today.pred_opt().expect("Time must be valid"); |
91 | 101 |
|
92 | 102 | // Check if the member was present yesterday
|
93 | 103 | let was_present_yesterday = sqlx::query_scalar::<_, bool>(
|
@@ -126,7 +136,7 @@ async fn update_days_attended(member_id: i32, today: NaiveDate, pool: &PgPool) {
|
126 | 136 | let month: i32 = (today.month0() + 1) as i32;
|
127 | 137 | let year: i32 = today.year_ce().1 as i32;
|
128 | 138 |
|
129 |
| - // Check if there’s an existing summary for the current month |
| 139 | + // Check if there's an existing summary for the current month |
130 | 140 | let existing_days_attended = sqlx::query_scalar::<_, i32>(
|
131 | 141 | r#"
|
132 | 142 | SELECT days_attended
|
|
0 commit comments