Stash sync logic
This commit is contained in:
+127
-5
@@ -1,4 +1,4 @@
|
||||
use chrono::{NaiveDate, TimeDelta, Utc};
|
||||
use chrono::{TimeDelta, Utc};
|
||||
use sqlx::{Connection, PgConnection};
|
||||
use toggl::TogglApi;
|
||||
|
||||
@@ -65,21 +65,75 @@ impl Worker {
|
||||
let time_entries = self.toggl_api
|
||||
.get_time_entries_for_user_modified_since(fetch_since).await?;
|
||||
|
||||
let refetch_projects = time_entries.iter()
|
||||
let fetch_workspaces = time_entries.iter()
|
||||
.map(|entry| entry.workspace_id)
|
||||
.filter(|workspace_id| !existing_ids.workspace_ids.contains(&workspace_id))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let fetch_projects = time_entries.iter()
|
||||
.map(|entry| entry.project_id)
|
||||
.filter_map(|project_id| project_id)
|
||||
.any(|project_id| !existing_ids.project_ids.contains(&project_id));
|
||||
|
||||
let refetch_tags = time_entries.iter()
|
||||
let fetch_tags = time_entries.iter()
|
||||
.flat_map(|entry| entry.tag_ids.iter())
|
||||
.any(|tag| !existing_ids.tag_ids.contains(&tag));
|
||||
|
||||
if !fetch_workspaces.is_empty() {
|
||||
self.update_workspaces(&fetch_workspaces).await?;
|
||||
}
|
||||
|
||||
if fetch_projects {
|
||||
self.update_projects(&existing_ids).await?;
|
||||
}
|
||||
|
||||
if fetch_tags {
|
||||
self.update_tags().await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_projects(&mut self) -> Result<(), AppError> {
|
||||
async fn update_workspaces(&mut self, workspace_ids: &[u64]) -> Result<(), AppError> {
|
||||
let workspaces = workspace_ids.iter()
|
||||
.map(|id| self.toggl_api.get_workspace(*id));
|
||||
|
||||
let workspaces = futures::future::join_all(workspaces).await
|
||||
.into_iter()
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
for workspace in workspaces {
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO workspaces (id, organization_id, name)
|
||||
VALUES ($1, $2, $3)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
organization_id = excluded.organization_id,
|
||||
name = excluded.name
|
||||
"#,
|
||||
workspace.id as i64,
|
||||
workspace.organization_id as i64,
|
||||
workspace.name,
|
||||
)
|
||||
.execute(&mut self.db)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_projects(&mut self, existing_ids: &TableSummary) -> Result<(), AppError> {
|
||||
let projects = self.toggl_api.get_projects().await?;
|
||||
|
||||
let fetch_clients = projects.iter()
|
||||
.map(|project| project.client_id)
|
||||
.filter_map(|client_id| client_id)
|
||||
.any(|client_id| !existing_ids.client_ids.contains(&(client_id as u64)));
|
||||
|
||||
if fetch_clients {
|
||||
self.update_clients().await?;
|
||||
}
|
||||
|
||||
for project in projects {
|
||||
sqlx::query!(
|
||||
r#"
|
||||
@@ -123,6 +177,74 @@ impl Worker {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_tags(&mut self) -> Result<(), AppError> {
|
||||
let tags = self.toggl_api.get_tags().await?;
|
||||
|
||||
for tag in tags {
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO tags (id, name, workspace_id, creator_id, updated_at, deleted_at, permissions)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
name = excluded.name,
|
||||
workspace_id = excluded.workspace_id,
|
||||
creator_id = excluded.creator_id,
|
||||
updated_at = excluded.updated_at,
|
||||
deleted_at = excluded.deleted_at,
|
||||
permissions = excluded.permissions
|
||||
"#,
|
||||
tag.id as i64,
|
||||
tag.name,
|
||||
tag.workspace_id as i64,
|
||||
tag.creator_id as i64,
|
||||
tag.updated_at,
|
||||
tag.deleted_at,
|
||||
tag.permissions,
|
||||
)
|
||||
.execute(&mut self.db)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_clients(&mut self) -> Result<(), AppError> {
|
||||
let clients = self.toggl_api.get_clients().await?;
|
||||
|
||||
for client in clients {
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO tracking_clients (id, updated_at, archived, creator_id, integration_provider, notes, name, server_deleted_at, workspace_id, permissions)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
updated_at = excluded.updated_at,
|
||||
archived = excluded.archived,
|
||||
creator_id = excluded.creator_id,
|
||||
integration_provider = excluded.integration_provider,
|
||||
notes = excluded.notes,
|
||||
name = excluded.name,
|
||||
server_deleted_at = excluded.server_deleted_at,
|
||||
workspace_id = excluded.workspace_id,
|
||||
permissions = excluded.permissions
|
||||
"#,
|
||||
client.id,
|
||||
client.updated_at,
|
||||
client.archived,
|
||||
client.creator_id,
|
||||
client.integration_provider,
|
||||
client.notes,
|
||||
client.name,
|
||||
client.server_deleted_at,
|
||||
client.workspace_id,
|
||||
client.permissions,
|
||||
)
|
||||
.execute(&mut self.db)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
@@ -143,7 +265,7 @@ async fn main() {
|
||||
toggl_api: api,
|
||||
};
|
||||
|
||||
worker.update_projects()
|
||||
worker.update(TimeDelta::days(7))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user