From ebab610a50d0d57060df26b168d26ef6824711c3 Mon Sep 17 00:00:00 2001 From: Joshua Coles Date: Thu, 4 Jul 2024 08:54:33 +0100 Subject: [PATCH] Fix polling issue and possible change in schema --- Cargo.lock | 12 ++++++++++++ Cargo.toml | 1 + src/db.rs | 4 ++-- src/poll.rs | 20 ++++++++++++++++++-- src/toggl_api/api_client.rs | 15 +++++++++------ src/toggl_api/types.rs | 2 +- 6 files changed, 43 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 51c2b4d..0970075 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2740,6 +2740,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_json_path_to_error" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7f2c2432eb04d880635fbf5d45cd5e619aeca7d4aff62cc1699671512db7d53" +dependencies = [ + "serde", + "serde_json", + "serde_path_to_error", +] + [[package]] name = "serde_path_to_error" version = "0.1.15" @@ -3362,6 +3373,7 @@ dependencies = [ "sea-orm", "serde", "serde_json", + "serde_json_path_to_error", "serde_with", "tokio", "tower-http", diff --git a/Cargo.toml b/Cargo.toml index d405cf8..cfa2604 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,4 +35,5 @@ chrono = { version = "0.4.31", features = ["serde"] } futures = "0.3.29" rucron = "0.1.5" csv = "1.3.0" +serde_json_path_to_error = "0.1.4" #tokio-cron-scheduler = "0.9.4" diff --git a/src/db.rs b/src/db.rs index 178758b..df76671 100644 --- a/src/db.rs +++ b/src/db.rs @@ -9,7 +9,7 @@ impl ReportRow { .iter() .map(|inner| TimeEntry { id: inner.id as i64, - description: self.description.clone(), + description: Some(self.description.clone()), project_id: self.project_id.map(|id| id as i64), task_id: self.task_id.map(|id| id as i64), billable: self.billable, @@ -32,7 +32,7 @@ impl TimeEntry { time_entry::ActiveModel { id: NotSet, toggl_id: Set(self.id), - description: Set(self.description.clone()), + description: Set(self.description.clone().unwrap_or(String::new())), project_id: Set(self.project_id), start: Set(self.start.fixed_offset()), stop: Set(self.stop.unwrap().fixed_offset()), diff --git a/src/poll.rs b/src/poll.rs index 050725f..7e21471 100644 --- a/src/poll.rs +++ b/src/poll.rs @@ -2,7 +2,7 @@ use crate::entity::time_entry; use crate::sync_service::{update_database, UpdateStats}; use crate::toggl_api::TogglApiClient; use crate::utils; -use chrono::{DateTime, FixedOffset}; +use chrono::{DateTime, Days, FixedOffset, Months}; use migration::Order; use sea_orm::{DatabaseConnection, EntityTrait, QueryOrder, QuerySelect}; use std::ops::Sub; @@ -44,12 +44,28 @@ pub async fn perform_poll( debug!("Performing poll, last_update_at: {:?}", since); + // We cannot poll more than 3 months back + let limit_date = chrono::Utc::now() + .checked_sub_months(Months::new(3)) + .expect("Failed to subtract 3 months from current date") + .checked_add_days(Days::new(1)) + .expect("Failed to add 1 day to the date") + .fixed_offset(); + + let since = since + .map(|date| std::cmp::max( + date, + limit_date, + )); + let since = since.unwrap_or( chrono::Utc::now() - .sub(chrono::Duration::days(1)) + .sub(chrono::Duration::weeks(2)) .fixed_offset(), ); + debug!("Performing poll, since: {:?}", since); + let time_entries = toggl_client .fetch_time_entries_modified_since(since.to_utc()) .await?; diff --git a/src/toggl_api/api_client.rs b/src/toggl_api/api_client.rs index bbb1334..766f0ac 100644 --- a/src/toggl_api/api_client.rs +++ b/src/toggl_api/api_client.rs @@ -9,11 +9,11 @@ use chrono::{DateTime, Utc}; use hyper::HeaderMap; use reqwest::header::HeaderValue; use reqwest::{Client, RequestBuilder, Response}; -use serde_json::Value; +use serde_json::{Error, Value}; use std::collections::HashMap; use std::time::Duration; use tracing::instrument; -use tracing::log::debug; +use tracing::log::{debug, error}; #[derive(Debug, Clone)] pub struct TogglApiClient { @@ -120,15 +120,18 @@ impl TogglApiClient { ) -> crate::Result> { let url = format!("{base_url}/me/time_entries", base_url = self.base_url); - Ok(self + let response = self .make_request( self.client .get(url) .query(&[("since", date_time.timestamp())]), ) - .await? - .json::>() - .await?) + .await?; + + let json = response.json::().await?; + serde_json_path_to_error::from_value(json.clone()).map_err(|error| { + error.into() + }) } pub async fn fetch_time_entries_in_range( diff --git a/src/toggl_api/types.rs b/src/toggl_api/types.rs index 7ed3a8c..8bea55f 100644 --- a/src/toggl_api/types.rs +++ b/src/toggl_api/types.rs @@ -40,7 +40,7 @@ pub struct TimeEntry { pub start: DateTime, pub stop: Option>, pub duration: i64, - pub description: String, + pub description: Option, pub tags: Vec, pub tag_ids: Vec, pub at: DateTime,