use crate::client::TogglClient; use crate::entity::{client, project, time_entry}; use crate::types::{Project, ProjectClient, TogglQuery}; use sea_orm::{DatabaseConnection, EntityTrait, QuerySelect}; use tracing::instrument; use crate::day_exclusivity_condition; #[tracing::instrument(skip(client, db))] pub async fn poll_job(client: TogglClient, db: DatabaseConnection, poll_period: u64) { // Every 2h, 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 { tracing::info!("Polling Toggl API"); match perform_poll(&client, &db).await { Ok(report_entries_count) => { tracing::info!( "Successfully polled Toggl API: {:?} entries retrieved", report_entries_count ); } Err(error) => { tracing::error!("Failed to poll Toggl API: {:?}", error); } } tokio::time::sleep(period).await; } } #[instrument(skip(client, db))] pub async fn perform_poll( client: &TogglClient, db: &DatabaseConnection, ) -> beachhead::Result { let now = chrono::Utc::now(); let today_string = now .date_naive() .format("%Y-%m-%d") .to_string(); let report = client .full_report(&TogglQuery { start_date: Some(today_string.clone()), end_date: Some(today_string.clone()), ..Default::default() }) .await?; let existing_project_ids = project::Entity::find() .select_only() .column(project::Column::TogglId) .into_tuple::() .all(db) .await?; let new_projects = report .iter() .filter_map(|entry| entry.project_id) .any(|project_id| !existing_project_ids.contains(&(project_id as i64))); if new_projects { let clients = client.fetch_clients().await?; client::Entity::insert_many(clients.iter().map(ProjectClient::as_model)) .on_conflict(ProjectClient::grafting_conflict_statement()) .exec(db) .await?; let projects = client.fetch_projects().await?; project::Entity::insert_many(projects.iter().map(Project::as_model)) .on_conflict(Project::grafting_conflict_statement()) .exec(db) .await?; } crate::cache_report( &db, &report, Some( day_exclusivity_condition(now.date_naive(), now.date_naive()), ), ) .await?; Ok(report.len()) }