Refactor API and add 'fetch_within' method
Changed `workspace_id` type to `u64` for broader compatibility. Introduced `fetch_within` to allow fetching time entries within a given date range and abstracted database update logic into `update_database`.
This commit is contained in:
parent
7fb0ab06e1
commit
ead22776c3
46
src/main.rs
46
src/main.rs
@ -1,6 +1,7 @@
|
||||
use chrono::{DateTime, TimeDelta, Utc};
|
||||
use chrono::{DateTime, DurationRound, NaiveDate, TimeDelta, Utc};
|
||||
use sqlx::{Connection, PgConnection};
|
||||
use toggl::TogglApi;
|
||||
use crate::toggl::types::{TimeEntry, TogglReportFilters};
|
||||
|
||||
mod toggl;
|
||||
mod sensitive;
|
||||
@ -55,7 +56,21 @@ impl Worker {
|
||||
})
|
||||
}
|
||||
|
||||
async fn fetch_changed_since(&mut self, look_back: TimeDelta) -> Result<(), AppError> {
|
||||
pub async fn fetch_within(&mut self, start: DateTime<Utc>, end: DateTime<Utc>) -> Result<(), AppError> {
|
||||
let results = self.toggl_api.search(self.toggl_api.workspace_id, TogglReportFilters {
|
||||
start_date: Some(start.date_naive()),
|
||||
end_date: Some(end.date_naive()),
|
||||
..Default::default()
|
||||
}).await?;
|
||||
|
||||
let time_entries = results.into_iter()
|
||||
.map(|entry| entry.into_time_entry(self.toggl_api.workspace_id))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.update_database(time_entries).await
|
||||
}
|
||||
|
||||
pub async fn fetch_changed_since(&mut self, look_back: TimeDelta) -> Result<(), AppError> {
|
||||
if look_back > TimeDelta::days(90) {
|
||||
return Err(AppError::LookBackTooLarge)
|
||||
}
|
||||
@ -63,7 +78,7 @@ impl Worker {
|
||||
self.update_time_entries(Utc::now() - look_back).await
|
||||
}
|
||||
|
||||
async fn update(&mut self, default_look_back: TimeDelta) -> Result<(), AppError> {
|
||||
pub async fn update(&mut self, default_look_back: TimeDelta) -> Result<(), AppError> {
|
||||
let result = sqlx::query!("select max(updated_at) as last_updated_at from time_entries")
|
||||
.fetch_optional(&mut self.db)
|
||||
.await
|
||||
@ -77,11 +92,15 @@ impl Worker {
|
||||
}
|
||||
|
||||
async fn update_time_entries(&mut self, fetch_since: DateTime<Utc>) -> Result<(), AppError> {
|
||||
let existing_ids = self.get_ids().await?;
|
||||
|
||||
let time_entries = self.toggl_api
|
||||
.get_time_entries_for_user_modified_since(fetch_since).await?;
|
||||
|
||||
self.update_database(time_entries).await
|
||||
}
|
||||
|
||||
async fn update_database(&mut self, time_entries: Vec<TimeEntry>) -> Result<(), AppError> {
|
||||
let existing_ids = self.get_ids().await?;
|
||||
|
||||
let fetch_workspaces = time_entries.iter()
|
||||
.map(|entry| entry.workspace_id)
|
||||
.filter(|workspace_id| !existing_ids.workspace_ids.contains(&workspace_id))
|
||||
@ -324,7 +343,18 @@ async fn main() {
|
||||
toggl_api: api,
|
||||
};
|
||||
|
||||
worker.fetch_changed_since(TimeDelta::days(90))
|
||||
.await
|
||||
.unwrap();
|
||||
let start = NaiveDate::from_ymd_opt(2024, 2, 1)
|
||||
.expect("Invalid date")
|
||||
.and_hms_opt(0, 0, 0)
|
||||
.expect("Invalid time")
|
||||
.and_utc();
|
||||
|
||||
let end = NaiveDate::from_ymd_opt(2024, 5, 1)
|
||||
.expect("Invalid date")
|
||||
.and_hms_opt(0, 0, 0)
|
||||
.expect("Invalid time")
|
||||
.and_utc();
|
||||
|
||||
worker.fetch_within(start, end).await
|
||||
.expect("Failed to fetch time entries");
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ impl reqwest_ratelimit::RateLimiter for ReqwestRateLimiter {
|
||||
#[derive(Clone)]
|
||||
pub struct TogglApi {
|
||||
client: ClientWithMiddleware,
|
||||
workspace_id: u32,
|
||||
pub workspace_id: u64,
|
||||
headers: HeaderMap,
|
||||
}
|
||||
|
||||
@ -212,11 +212,11 @@ impl TogglApi {
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub async fn search(&self, filters: types::TogglReportFilters) -> Result<Vec<types::ReportEntry>, TogglError> {
|
||||
pub async fn search(&self, workspace_id: u64, filters: types::TogglReportFilters) -> Result<Vec<types::ReportEntry>, TogglError> {
|
||||
let url = format!(
|
||||
"{base_url}/workspace/{workspace_id}/search/time_entries",
|
||||
base_url = &REPORTS_BASE_URL,
|
||||
workspace_id = self.workspace_id,
|
||||
workspace_id = workspace_id,
|
||||
);
|
||||
|
||||
let mut last_row_number = Some(0);
|
||||
@ -432,7 +432,7 @@ pub mod types {
|
||||
}
|
||||
|
||||
impl ReportEntry {
|
||||
fn into_time_entry(self, workspace_id: u64) -> TimeEntry {
|
||||
pub fn into_time_entry(self, workspace_id: u64) -> TimeEntry {
|
||||
TimeEntry {
|
||||
id: self.time_entries[0].id,
|
||||
workspace_id,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user