diff --git a/src/poll.rs b/src/poll.rs index 6fae87a..98af866 100644 --- a/src/poll.rs +++ b/src/poll.rs @@ -1,14 +1,21 @@ -use crate::toggl_api::TogglApiClient; +use crate::entity::prelude::TimeEntry; use crate::entity::{client, project}; -use crate::toggl_api::types::{Project, Client, TogglReportQuery}; -use sea_orm::{DatabaseConnection, EntityTrait, QuerySelect}; -use tracing::instrument; +use crate::toggl_api::types::{Client, Project, TogglReportQuery}; +use crate::toggl_api::TogglApiClient; use crate::utils; use crate::utils::day_exclusivity_condition; +use chrono::{DateTime, FixedOffset}; +use sea_orm::DatabaseBackend::Postgres; +use sea_orm::{ + ConnectionTrait, DatabaseConnection, EntityOrSelect, EntityTrait, QueryOrder, QuerySelect, + Statement, +}; +use std::ops::Sub; +use tracing::instrument; #[tracing::instrument(skip(client, db))] pub async fn poll_job(client: TogglApiClient, db: DatabaseConnection, poll_period: u64) { - // Every 2h, poll the Toggl API for new time entries for today to cache them in the database + // Periodically poll the Toggl API for new time entries for today to cache them in the database let period = tokio::time::Duration::from_secs(poll_period); loop { @@ -35,18 +42,22 @@ pub async fn perform_poll( client: &TogglApiClient, db: &DatabaseConnection, ) -> utils::Result { - let now = chrono::Utc::now(); - let today_string = now - .date_naive() - .format("%Y-%m-%d") - .to_string(); + let since = db + .query_one(Statement::from_string( + Postgres, + r#"select server_updated_at from time_entry order by server_updated_at desc limit 1"#, + )) + .await? + .map(|row| row.try_get_by::, _>("server_updated_at")) + .transpose()? + .unwrap_or( + chrono::Utc::now() + .sub(chrono::Duration::days(1)) + .fixed_offset(), + ); - let report = client - .full_report(&TogglReportQuery { - start_date: Some(today_string.clone()), - end_date: Some(today_string.clone()), - ..Default::default() - }) + let time_entries = client + .fetch_time_entries_modified_since(since.to_utc()) .await?; let existing_project_ids = project::Entity::find() @@ -56,7 +67,7 @@ pub async fn perform_poll( .all(db) .await?; - let new_projects = report + let new_projects = time_entries .iter() .filter_map(|entry| entry.project_id) .any(|project_id| !existing_project_ids.contains(&(project_id as i64))); @@ -77,12 +88,13 @@ pub async fn perform_poll( .await?; } - crate::routes::cache_report( + crate::sync_service::cache_report( &db, &report, - Some( - day_exclusivity_condition(now.date_naive(), now.date_naive()), - ), + Some(day_exclusivity_condition( + now.date_naive(), + now.date_naive(), + )), ) .await?; Ok(report.len())