BBPAYKPE33IZM6BWHHQL3AL24ZXIGAGIZSUBVIZZ4TCFA5LQK46AC
use chrono::NaiveDateTime;
use crate::schema::time_entries;
#[derive(Debug, Queryable)]
pub(crate) struct TimeEntry {
pub(crate) id: i32,
pub(crate) server_id: Option<i64>,
pub(crate) description: String,
pub(crate) start: NaiveDateTime,
pub(crate) stop: Option<NaiveDateTime>,
}
#[derive(Insertable, AsChangeset)]
#[table_name = "time_entries"]
pub(crate) struct ServerTimeEntry {
pub(crate) server_id: Option<i64>,
pub(crate) description: String,
pub(crate) start: NaiveDateTime,
pub(crate) stop: Option<NaiveDateTime>,
}
impl From<toggl_api::TimeEntry> for ServerTimeEntry {
fn from(entry: toggl_api::TimeEntry) -> Self {
Self {
server_id: Some(entry.id.into()),
description: entry.description,
start: entry.start.naive_utc(),
stop: entry.stop.map(|m| m.naive_utc()),
}
}
}
let (user_info, _) = toggl.user_info(None).await.unwrap();
println!("User info\n---------\n{:?}", &user_info);
let projects = toggl
.projects_of_workspace(&user_info.workspaces[0])
.await
.unwrap();
println!("Projects: {:?}", projects);
let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let db = Arc::new(Mutex::new(
diesel::SqliteConnection::establish(&database_url).unwrap(),
));
let all_entries = {
use crate::schema::time_entries::dsl::*;
time_entries
.load::<TimeEntry>(&mut *db.lock().unwrap())
.unwrap()
};
println!("----------------");
for entry in &all_entries {
println!(
"{} ({} - {})",
entry.description,
entry.start,
entry
.stop
.map_or_else(|| "...".to_string(), |t| t.to_string())
);
}
use std::sync::{Arc, Mutex};
use diesel::{RunQueryDsl, SqliteConnection};
use toggl_api::{Timestamp, Toggl};
use crate::model::ServerTimeEntry;
pub(crate) struct Daemon {
api: Toggl,
last_sync: Option<Timestamp>,
db: Arc<Mutex<SqliteConnection>>,
}
impl Daemon {
pub(crate) fn new(api: Toggl, db: Arc<Mutex<SqliteConnection>>) -> Self {
Self {
api,
last_sync: None,
db,
}
}
pub(crate) async fn sync(&mut self) -> Result<(), ()> {
let (data, new_last_sync) = self.api.all_data(self.last_sync).await?;
let mut db = self.db.lock().unwrap();
let entries_cnt = data.time_entries.len();
if entries_cnt > 0 {
println!("Downloading {} time entries...", entries_cnt);
}
for time_entry in data.time_entries {
let time_entry: ServerTimeEntry = time_entry.into();
{
use crate::schema::time_entries::dsl::*;
diesel::insert_into(time_entries)
.values(&time_entry)
.on_conflict(server_id)
.do_update()
.set(&time_entry)
.execute(&mut *db)
.unwrap();
}
}
self.last_sync = Some(new_last_sync);
Ok(())
}
}