Fix polling issue and possible change in schema
All checks were successful
Build and Publish Docker Container / build (push) Successful in 6m14s
All checks were successful
Build and Publish Docker Container / build (push) Successful in 6m14s
This commit is contained in:
parent
4761428f33
commit
ebab610a50
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -2740,6 +2740,17 @@ dependencies = [
|
|||||||
"serde",
|
"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]]
|
[[package]]
|
||||||
name = "serde_path_to_error"
|
name = "serde_path_to_error"
|
||||||
version = "0.1.15"
|
version = "0.1.15"
|
||||||
@ -3362,6 +3373,7 @@ dependencies = [
|
|||||||
"sea-orm",
|
"sea-orm",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"serde_json_path_to_error",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
|
|||||||
@ -35,4 +35,5 @@ chrono = { version = "0.4.31", features = ["serde"] }
|
|||||||
futures = "0.3.29"
|
futures = "0.3.29"
|
||||||
rucron = "0.1.5"
|
rucron = "0.1.5"
|
||||||
csv = "1.3.0"
|
csv = "1.3.0"
|
||||||
|
serde_json_path_to_error = "0.1.4"
|
||||||
#tokio-cron-scheduler = "0.9.4"
|
#tokio-cron-scheduler = "0.9.4"
|
||||||
|
|||||||
@ -9,7 +9,7 @@ impl ReportRow {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|inner| TimeEntry {
|
.map(|inner| TimeEntry {
|
||||||
id: inner.id as i64,
|
id: inner.id as i64,
|
||||||
description: self.description.clone(),
|
description: Some(self.description.clone()),
|
||||||
project_id: self.project_id.map(|id| id as i64),
|
project_id: self.project_id.map(|id| id as i64),
|
||||||
task_id: self.task_id.map(|id| id as i64),
|
task_id: self.task_id.map(|id| id as i64),
|
||||||
billable: self.billable,
|
billable: self.billable,
|
||||||
@ -32,7 +32,7 @@ impl TimeEntry {
|
|||||||
time_entry::ActiveModel {
|
time_entry::ActiveModel {
|
||||||
id: NotSet,
|
id: NotSet,
|
||||||
toggl_id: Set(self.id),
|
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),
|
project_id: Set(self.project_id),
|
||||||
start: Set(self.start.fixed_offset()),
|
start: Set(self.start.fixed_offset()),
|
||||||
stop: Set(self.stop.unwrap().fixed_offset()),
|
stop: Set(self.stop.unwrap().fixed_offset()),
|
||||||
|
|||||||
20
src/poll.rs
20
src/poll.rs
@ -2,7 +2,7 @@ use crate::entity::time_entry;
|
|||||||
use crate::sync_service::{update_database, UpdateStats};
|
use crate::sync_service::{update_database, UpdateStats};
|
||||||
use crate::toggl_api::TogglApiClient;
|
use crate::toggl_api::TogglApiClient;
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
use chrono::{DateTime, FixedOffset};
|
use chrono::{DateTime, Days, FixedOffset, Months};
|
||||||
use migration::Order;
|
use migration::Order;
|
||||||
use sea_orm::{DatabaseConnection, EntityTrait, QueryOrder, QuerySelect};
|
use sea_orm::{DatabaseConnection, EntityTrait, QueryOrder, QuerySelect};
|
||||||
use std::ops::Sub;
|
use std::ops::Sub;
|
||||||
@ -44,12 +44,28 @@ pub async fn perform_poll(
|
|||||||
|
|
||||||
debug!("Performing poll, last_update_at: {:?}", since);
|
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(
|
let since = since.unwrap_or(
|
||||||
chrono::Utc::now()
|
chrono::Utc::now()
|
||||||
.sub(chrono::Duration::days(1))
|
.sub(chrono::Duration::weeks(2))
|
||||||
.fixed_offset(),
|
.fixed_offset(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
debug!("Performing poll, since: {:?}", since);
|
||||||
|
|
||||||
let time_entries = toggl_client
|
let time_entries = toggl_client
|
||||||
.fetch_time_entries_modified_since(since.to_utc())
|
.fetch_time_entries_modified_since(since.to_utc())
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@ -9,11 +9,11 @@ use chrono::{DateTime, Utc};
|
|||||||
use hyper::HeaderMap;
|
use hyper::HeaderMap;
|
||||||
use reqwest::header::HeaderValue;
|
use reqwest::header::HeaderValue;
|
||||||
use reqwest::{Client, RequestBuilder, Response};
|
use reqwest::{Client, RequestBuilder, Response};
|
||||||
use serde_json::Value;
|
use serde_json::{Error, Value};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
use tracing::log::debug;
|
use tracing::log::{debug, error};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TogglApiClient {
|
pub struct TogglApiClient {
|
||||||
@ -120,15 +120,18 @@ impl TogglApiClient {
|
|||||||
) -> crate::Result<Vec<TimeEntry>> {
|
) -> crate::Result<Vec<TimeEntry>> {
|
||||||
let url = format!("{base_url}/me/time_entries", base_url = self.base_url);
|
let url = format!("{base_url}/me/time_entries", base_url = self.base_url);
|
||||||
|
|
||||||
Ok(self
|
let response = self
|
||||||
.make_request(
|
.make_request(
|
||||||
self.client
|
self.client
|
||||||
.get(url)
|
.get(url)
|
||||||
.query(&[("since", date_time.timestamp())]),
|
.query(&[("since", date_time.timestamp())]),
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
.json::<Vec<TimeEntry>>()
|
|
||||||
.await?)
|
let json = response.json::<Value>().await?;
|
||||||
|
serde_json_path_to_error::from_value(json.clone()).map_err(|error| {
|
||||||
|
error.into()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fetch_time_entries_in_range(
|
pub async fn fetch_time_entries_in_range(
|
||||||
|
|||||||
@ -40,7 +40,7 @@ pub struct TimeEntry {
|
|||||||
pub start: DateTime<Utc>,
|
pub start: DateTime<Utc>,
|
||||||
pub stop: Option<DateTime<Utc>>,
|
pub stop: Option<DateTime<Utc>>,
|
||||||
pub duration: i64,
|
pub duration: i64,
|
||||||
pub description: String,
|
pub description: Option<String>,
|
||||||
pub tags: Vec<String>,
|
pub tags: Vec<String>,
|
||||||
pub tag_ids: Vec<i64>,
|
pub tag_ids: Vec<i64>,
|
||||||
pub at: DateTime<Utc>,
|
pub at: DateTime<Utc>,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user