Run rustfmt and move cache_report into sync_service.rs
This commit is contained in:
+56
-63
@@ -1,17 +1,19 @@
|
||||
use crate::toggl_api::types::{
|
||||
Client as ProjectClient, Project, ReportRow, TimeEntry, TogglReportQuery,
|
||||
};
|
||||
use anyhow::anyhow;
|
||||
use axum::http::StatusCode;
|
||||
use base64::engine::general_purpose::STANDARD;
|
||||
use base64::Engine;
|
||||
use chrono::{DateTime, Utc};
|
||||
use hyper::HeaderMap;
|
||||
use reqwest::header::HeaderValue;
|
||||
use reqwest::{Client, RequestBuilder, Response};
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
use anyhow::anyhow;
|
||||
use axum::http::StatusCode;
|
||||
use base64::Engine;
|
||||
use base64::engine::general_purpose::STANDARD;
|
||||
use chrono::{DateTime, Utc};
|
||||
use hyper::HeaderMap;
|
||||
use reqwest::header::HeaderValue;
|
||||
use tracing::instrument;
|
||||
use tracing::log::debug;
|
||||
use crate::toggl_api::types::{TimeEntry, Project, Client as ProjectClient, ReportRow, TogglReportQuery};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TogglApiClient {
|
||||
@@ -24,7 +26,9 @@ pub struct TogglApiClient {
|
||||
impl TogglApiClient {
|
||||
async fn make_request(&self, request_builder: RequestBuilder) -> crate::Result<Response> {
|
||||
loop {
|
||||
let builder = request_builder.try_clone().ok_or(anyhow!("Failed to clone request builder"))?;
|
||||
let builder = request_builder
|
||||
.try_clone()
|
||||
.ok_or(anyhow!("Failed to clone request builder"))?;
|
||||
let response = self.client.execute(builder.build()?).await?;
|
||||
|
||||
// If we are rate limited, wait a bit and try again
|
||||
@@ -60,10 +64,7 @@ impl TogglApiClient {
|
||||
let mut headers = HeaderMap::new();
|
||||
let mut value = HeaderValue::from_str(&format!("Basic {}", toggl_auth)).unwrap();
|
||||
value.set_sensitive(true);
|
||||
headers.insert(
|
||||
"Authorization",
|
||||
value,
|
||||
);
|
||||
headers.insert("Authorization", value);
|
||||
headers
|
||||
}
|
||||
|
||||
@@ -74,9 +75,8 @@ impl TogglApiClient {
|
||||
base_url = self.base_url,
|
||||
);
|
||||
|
||||
let projects = self.make_request(self
|
||||
.client
|
||||
.get(&url))
|
||||
let projects = self
|
||||
.make_request(self.client.get(&url))
|
||||
.await?
|
||||
.json::<Vec<Project>>()
|
||||
.await?;
|
||||
@@ -91,9 +91,8 @@ impl TogglApiClient {
|
||||
base_url = self.base_url,
|
||||
);
|
||||
|
||||
let clients = self.make_request(self
|
||||
.client
|
||||
.get(&url))
|
||||
let clients = self
|
||||
.make_request(self.client.get(&url))
|
||||
.await?
|
||||
.json::<Vec<ProjectClient>>()
|
||||
.await?;
|
||||
@@ -101,37 +100,37 @@ impl TogglApiClient {
|
||||
Ok(clients)
|
||||
}
|
||||
|
||||
pub async fn fetch_time_entries_modified_since(&self, date_time: DateTime<Utc>) -> crate::Result<Vec<TimeEntry>> {
|
||||
let url = format!(
|
||||
"{base_url}/me/time_entries",
|
||||
base_url = self.base_url
|
||||
);
|
||||
pub async fn fetch_time_entries_modified_since(
|
||||
&self,
|
||||
date_time: DateTime<Utc>,
|
||||
) -> crate::Result<Vec<TimeEntry>> {
|
||||
let url = format!("{base_url}/me/time_entries", base_url = self.base_url);
|
||||
|
||||
Ok(
|
||||
self.make_request(self.client.get(url)
|
||||
.query(&[("since", date_time.timestamp())]))
|
||||
.await?
|
||||
.json::<Vec<TimeEntry>>()
|
||||
.await?
|
||||
)
|
||||
Ok(self
|
||||
.make_request(
|
||||
self.client
|
||||
.get(url)
|
||||
.query(&[("since", date_time.timestamp())]),
|
||||
)
|
||||
.await?
|
||||
.json::<Vec<TimeEntry>>()
|
||||
.await?)
|
||||
}
|
||||
|
||||
pub async fn fetch_time_entries_in_range(&self, (start, end): (DateTime<Utc>, DateTime<Utc>)) -> crate::Result<Vec<TimeEntry>> {
|
||||
let url = format!(
|
||||
"{base_url}/me/time_entries",
|
||||
base_url = self.base_url
|
||||
);
|
||||
pub async fn fetch_time_entries_in_range(
|
||||
&self,
|
||||
(start, end): (DateTime<Utc>, DateTime<Utc>),
|
||||
) -> crate::Result<Vec<TimeEntry>> {
|
||||
let url = format!("{base_url}/me/time_entries", base_url = self.base_url);
|
||||
|
||||
Ok(
|
||||
self.make_request(self.client.get(url)
|
||||
.query(&[
|
||||
("start_date", start.to_rfc3339()),
|
||||
("end_date", end.to_rfc3339())
|
||||
]))
|
||||
.await?
|
||||
.json::<Vec<TimeEntry>>()
|
||||
.await?
|
||||
)
|
||||
Ok(self
|
||||
.make_request(self.client.get(url).query(&[
|
||||
("start_date", start.to_rfc3339()),
|
||||
("end_date", end.to_rfc3339()),
|
||||
]))
|
||||
.await?
|
||||
.json::<Vec<TimeEntry>>()
|
||||
.await?)
|
||||
}
|
||||
|
||||
pub async fn fetch_current_time_entry(&self) -> crate::Result<Option<TimeEntry>> {
|
||||
@@ -140,9 +139,8 @@ impl TogglApiClient {
|
||||
base_url = self.base_url
|
||||
);
|
||||
|
||||
let res = self.make_request(self
|
||||
.client
|
||||
.get(url))
|
||||
let res = self
|
||||
.make_request(self.client.get(url))
|
||||
.await?
|
||||
.json::<Option<TimeEntry>>()
|
||||
.await?;
|
||||
@@ -162,9 +160,7 @@ impl TogglApiClient {
|
||||
self.workspace_id.parse::<i32>()?.into(),
|
||||
);
|
||||
|
||||
self.make_request(self.client
|
||||
.post(url)
|
||||
.json(&body)).await?;
|
||||
self.make_request(self.client.post(url).json(&body)).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -180,10 +176,7 @@ impl TogglApiClient {
|
||||
}
|
||||
|
||||
#[instrument(skip(self, filters))]
|
||||
pub async fn full_report(
|
||||
&self,
|
||||
filters: &TogglReportQuery,
|
||||
) -> crate::Result<Vec<ReportRow>> {
|
||||
pub async fn full_report(&self, filters: &TogglReportQuery) -> crate::Result<Vec<ReportRow>> {
|
||||
let url = format!(
|
||||
"{base_url}/workspace/{workspace_id}/search/time_entries",
|
||||
base_url = self.reports_base_url,
|
||||
@@ -201,15 +194,15 @@ impl TogglApiClient {
|
||||
}
|
||||
|
||||
// TODO: Implement rate limiting
|
||||
let response = self.make_request(self
|
||||
.client
|
||||
.post(&url)
|
||||
.json(&Self::paginate_filters(&filters, last_row_number_n)))
|
||||
let response = self
|
||||
.make_request(
|
||||
self.client
|
||||
.post(&url)
|
||||
.json(&Self::paginate_filters(&filters, last_row_number_n)),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let data = response
|
||||
.json::<Vec<ReportRow>>()
|
||||
.await?;
|
||||
let data = response.json::<Vec<ReportRow>>().await?;
|
||||
|
||||
last_row_number = data.last().map(|e| e.row_number as u64);
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use serde_with::skip_serializing_none;
|
||||
use std::collections::HashMap;
|
||||
use std::option::Option;
|
||||
use chrono::{DateTime, Utc};
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||
pub struct ReportRow {
|
||||
@@ -46,7 +46,6 @@ pub struct TimeEntry {
|
||||
pub at: DateTime<Utc>,
|
||||
pub server_deleted_at: Option<DateTime<Utc>>,
|
||||
pub user_id: i64,
|
||||
|
||||
// Ignored fields
|
||||
// duronly: bool,
|
||||
// uid: i64,
|
||||
@@ -65,7 +64,6 @@ pub struct Project {
|
||||
pub at: DateTime<Utc>,
|
||||
pub server_deleted_at: Option<DateTime<Utc>>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
|
||||
// cid: Option<serde_json::Value>,
|
||||
// wid: i64,
|
||||
// rate: Option<serde_json::Value>,
|
||||
|
||||
Reference in New Issue
Block a user