From ec69ce5e1ded007d596c0762bb507dff1513f04d Mon Sep 17 00:00:00 2001 From: brayo Date: Tue, 26 Mar 2024 09:10:39 +0300 Subject: [PATCH 01/20] minor updates --- aw-sync/src/dirs.rs | 1 + aw-sync/src/sync.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/aw-sync/src/dirs.rs b/aw-sync/src/dirs.rs index 9c7ecf68..b826bd42 100644 --- a/aw-sync/src/dirs.rs +++ b/aw-sync/src/dirs.rs @@ -14,6 +14,7 @@ pub fn get_config_dir() -> Result> { Ok(dir) } +#[allow(dead_code)] pub fn get_server_config_path(testing: bool) -> Result { let dir = aw_server::dirs::get_config_dir()?; Ok(dir.join(if testing { diff --git a/aw-sync/src/sync.rs b/aw-sync/src/sync.rs index 405118a9..f81f94ad 100644 --- a/aw-sync/src/sync.rs +++ b/aw-sync/src/sync.rs @@ -64,7 +64,7 @@ pub fn sync_run( let info = client.get_info()?; // FIXME: Here it is assumed that the device_id for the local server is the one used by - // aw-server-rust, which is not necessarily true (aw-server-python has seperate device_id). + // aw-server-rust, which is not necessarily true (aw-server-python has separate device_id). // Therefore, this may sometimes fail to pick up the correct local datastore. let device_id = info.device_id.as_str(); From def9cf9fcaad72559065768b8e0c33ba9a6f07f7 Mon Sep 17 00:00:00 2001 From: brayo Date: Wed, 27 Mar 2024 17:16:32 +0300 Subject: [PATCH 02/20] initial commit for firebase sync --- Cargo.lock | 21 ++++++++++++++++----- Cargo.toml | 1 + aw-firebase-sync/Cargo.toml | 12 ++++++++++++ aw-firebase-sync/src/main.rs | 31 +++++++++++++++++++++++++++++++ aw-firebase-sync/test-sync.sh | 0 5 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 aw-firebase-sync/Cargo.toml create mode 100644 aw-firebase-sync/src/main.rs create mode 100644 aw-firebase-sync/test-sync.sh diff --git a/Cargo.lock b/Cargo.lock index 0741a12e..e1a1077c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -228,6 +228,16 @@ dependencies = [ "serde_json", ] +[[package]] +name = "aw-firebase-sync" +version = "0.1.0" +dependencies = [ + "aw-client-rust", + "aw-models", + "chrono", + "tokio", +] + [[package]] name = "aw-models" version = "0.1.0" @@ -461,9 +471,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" dependencies = [ "android-tzdata", "iana-time-zone", @@ -471,7 +481,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] @@ -2574,15 +2584,16 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.34.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", "libc", "mio", "num_cpus", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2 0.5.5", diff --git a/Cargo.toml b/Cargo.toml index 28d8a7c7..ea7b2cc7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,5 +7,6 @@ members = [ "aw-server", "aw-sync", "aw-query", + "aw-firebase-sync", ] resolver = "2" diff --git a/aw-firebase-sync/Cargo.toml b/aw-firebase-sync/Cargo.toml new file mode 100644 index 00000000..47bebf4b --- /dev/null +++ b/aw-firebase-sync/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "aw-firebase-sync" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +chrono = "0.4.35" +tokio = { version = "1", features = ["full"] } +aw-client-rust = { path = "../aw-client-rust" } +aw-models = { path = "../aw-models" } diff --git a/aw-firebase-sync/src/main.rs b/aw-firebase-sync/src/main.rs new file mode 100644 index 00000000..fb28c54a --- /dev/null +++ b/aw-firebase-sync/src/main.rs @@ -0,0 +1,31 @@ +use tokio; +use aw_client_rust::AwClient; +use chrono::prelude::*; +pub struct TimeInterval { + pub start: DateTime, + pub end: DateTime, +} +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create a new client + let client = AwClient::new("localhost", 5600, "my-client").unwrap(); + + // Define the query + let _query = vec![ + "events = query_bucket(\"aw-watcher-window_my-hostname\");".to_string(), + "events = merge_events_by_keys(events, [\"app\"]);".to_string(), + "RETURN = sort_by_duration(events);".to_string(), + ]; + + let start = Utc.with_ymd_and_hms(2024, 3, 20, 0, 0, 0).unwrap(); + let end = Utc.with_ymd_and_hms(2024, 3, 28, 0, 0, 0).unwrap(); + let _timeperiod = TimeInterval{start, end}; + + // let buckets = client.get_buckets().await?; + // println!("{:?}", buckets); + let data = client.get_events("aw-watcher-window_brayo", Some(start), Some(end), Some(50)).await.unwrap(); + // Print the result + println!("{:?}", data); + + Ok(()) +} \ No newline at end of file diff --git a/aw-firebase-sync/test-sync.sh b/aw-firebase-sync/test-sync.sh new file mode 100644 index 00000000..e69de29b From 0a1a641d9ed700d670322ebd11ff0ce3a33cf514 Mon Sep 17 00:00:00 2001 From: brayo Date: Fri, 29 Mar 2024 19:21:17 +0300 Subject: [PATCH 03/20] dropping deprecated functions --- aw-client-rust/tests/test.rs | 12 +++-- aw-datastore/src/worker.rs | 2 +- aw-datastore/tests/datastore.rs | 32 +++++++------- aw-models/src/event.rs | 6 +-- aw-query/benches/benchmark.rs | 4 +- aw-query/src/functions.rs | 2 +- aw-query/tests/query.rs | 4 +- aw-sync/tests/sync.rs | 2 +- aw-transform/benches/bench.rs | 4 +- aw-transform/src/chunk.rs | 6 +-- aw-transform/src/filter_keyvals.rs | 8 ++-- aw-transform/src/filter_period.rs | 30 ++++++------- aw-transform/src/flood.rs | 66 ++++++++++++++-------------- aw-transform/src/heartbeat.rs | 30 ++++++------- aw-transform/src/merge.rs | 12 ++--- aw-transform/src/period_union.rs | 10 ++--- aw-transform/src/sort.rs | 8 ++-- aw-transform/src/split_url.rs | 2 +- aw-transform/src/union_no_overlap.rs | 14 +++--- 19 files changed, 126 insertions(+), 128 deletions(-) diff --git a/aw-client-rust/tests/test.rs b/aw-client-rust/tests/test.rs index cce54a5f..6f465f04 100644 --- a/aw-client-rust/tests/test.rs +++ b/aw-client-rust/tests/test.rs @@ -86,19 +86,17 @@ mod test { println!("Buckets: {buckets:?}"); let mut event = Event { id: None, - timestamp: DateTime::from_utc( + timestamp: DateTime::from_naive_utc_and_offset( DateTime::parse_from_rfc3339("2017-12-30T01:00:00+00:00") .unwrap() - .naive_utc(), - Utc, - ), - duration: Duration::seconds(0), + .naive_utc(), Utc), + duration: Duration::try_seconds(0).unwrap(), data: Map::new(), }; println!("{event:?}"); client.insert_event(&bucketname, &event).unwrap(); // Ugly way to create a UTC from timestamp, see https://github.com/chronotope/chrono/issues/263 - event.timestamp = DateTime::from_utc( + event.timestamp = DateTime::from_naive_utc_and_offset( DateTime::parse_from_rfc3339("2017-12-30T01:00:01+00:00") .unwrap() .naive_utc(), @@ -108,7 +106,7 @@ mod test { let events = client.get_events(&bucketname, None, None, None).unwrap(); println!("Events: {events:?}"); - assert!(events[0].duration == Duration::seconds(1)); + assert!(events[0].duration == Duration::try_seconds(1).unwrap()); client .delete_event(&bucketname, events[0].id.unwrap()) diff --git a/aw-datastore/src/worker.rs b/aw-datastore/src/worker.rs index 18eaf665..46a09537 100644 --- a/aw-datastore/src/worker.rs +++ b/aw-datastore/src/worker.rs @@ -177,7 +177,7 @@ impl DatastoreWorker { response_sender.respond(response); let now: DateTime = Utc::now(); - let commit_interval_passed: bool = (now - last_commit_time) > Duration::seconds(15); + let commit_interval_passed: bool = (now - last_commit_time) > Duration::try_seconds(15).unwrap(); if self.commit || commit_interval_passed || self.uncommitted_events > 100 diff --git a/aw-datastore/tests/datastore.rs b/aw-datastore/tests/datastore.rs index 1290d697..f8555337 100644 --- a/aw-datastore/tests/datastore.rs +++ b/aw-datastore/tests/datastore.rs @@ -77,7 +77,7 @@ mod datastore_tests { Some(created) => { let now = Utc::now(); assert!(created <= now); - assert!(created > now - Duration::seconds(10)); + assert!(created > now - Duration::try_seconds(10).unwrap()); } }; @@ -102,7 +102,7 @@ mod datastore_tests { Some(created) => { let now = Utc::now(); assert!(created <= now); - assert!(created > now - Duration::seconds(10)); + assert!(created > now - Duration::try_seconds(10).unwrap()); } }; @@ -129,7 +129,7 @@ mod datastore_tests { let e1 = Event { id: None, timestamp: Utc::now(), - duration: Duration::seconds(0), + duration: Duration::try_seconds(0).unwrap(), data: json_map! {"key": json!("value")}, }; let mut e2 = e1.clone(); @@ -157,7 +157,7 @@ mod datastore_tests { let e1 = Event { id: None, timestamp: Utc::now(), - duration: Duration::seconds(0), + duration: Duration::try_seconds(0).unwrap(), data: json_map! {"key": json!("value")}, }; let mut e2 = e1.clone(); @@ -224,7 +224,7 @@ mod datastore_tests { let e1 = Event { id: None, timestamp: Utc::now(), - duration: Duration::seconds(100), + duration: Duration::try_seconds(100).unwrap(), data: json_map! {"key": json!("value")}, }; @@ -232,8 +232,8 @@ mod datastore_tests { ds.insert_events(&bucket.id, &event_list).unwrap(); info!("Get event that covers queried timeperiod"); - let query_start = now + Duration::seconds(1); - let query_end = query_start + Duration::seconds(1); + let query_start = now + Duration::try_seconds(1).unwrap(); + let query_end = query_start + Duration::try_seconds(1).unwrap(); let fetched_events_limit = ds .get_events(&bucket.id, Some(query_start), Some(query_end), Some(1)) .unwrap(); @@ -256,11 +256,11 @@ mod datastore_tests { let e1 = Event { id: None, timestamp: Utc::now(), - duration: Duration::seconds(0), + duration: Duration::try_seconds(0).unwrap(), data: json_map! {"key": json!("value")}, }; let mut e2 = e1.clone(); - e2.timestamp += Duration::seconds(1); + e2.timestamp += Duration::try_seconds(1).unwrap(); let event_list = [e1.clone(), e2.clone()]; @@ -308,7 +308,7 @@ mod datastore_tests { let e1 = Event { id: None, timestamp: Utc::now(), - duration: Duration::seconds(0), + duration: Duration::try_seconds(0).unwrap(), data: json_map! {"key": json!("value")}, }; let mut e2 = e1.clone(); @@ -334,14 +334,14 @@ mod datastore_tests { let e1 = Event { id: None, timestamp: Utc::now(), - duration: Duration::seconds(0), + duration: Duration::try_seconds(0).unwrap(), data: json_map! {"key": json!("value")}, }; let mut e2 = e1.clone(); - e2.timestamp += Duration::seconds(1); + e2.timestamp += Duration::try_seconds(1).unwrap(); let mut e_diff_data = e2.clone(); - e_diff_data.timestamp += Duration::seconds(1); + e_diff_data.timestamp += Duration::try_seconds(1).unwrap(); e_diff_data.data = json_map! {"key": json!("other value")}; // First event @@ -358,7 +358,7 @@ mod datastore_tests { let fetched_events = ds.get_events(&bucket.id, None, None, None).unwrap(); assert_eq!(fetched_events.len(), 1); assert_eq!(fetched_events[0].timestamp, e1.timestamp); - assert_eq!(fetched_events[0].duration, Duration::seconds(1)); + assert_eq!(fetched_events[0].duration, Duration::try_seconds(1).unwrap()); assert_eq!(fetched_events[0].data, e1.data); assert_eq!(fetched_events[0].id, e1.id); let e2 = &fetched_events[0]; @@ -383,7 +383,7 @@ mod datastore_tests { let e = Event { id: None, timestamp: Utc::now(), - duration: Duration::seconds(0), + duration: Duration::try_seconds(0).unwrap(), data: json_map! {"key": json!("value")}, }; let mut e1 = e.clone(); @@ -451,7 +451,7 @@ mod datastore_tests { let e1 = Event { id: None, timestamp: Utc::now(), - duration: Duration::seconds(0), + duration: Duration::try_seconds(0).unwrap(), data: json_map! {"key": json!("value")}, }; { diff --git a/aw-models/src/event.rs b/aw-models/src/event.rs index 3b62b28b..7b7fe4fb 100644 --- a/aw-models/src/event.rs +++ b/aw-models/src/event.rs @@ -60,14 +60,14 @@ impl Default for Event { Event { id: None, timestamp: Utc::now(), - duration: Duration::seconds(0), + duration: Duration::try_seconds(0).unwrap(), data: serde_json::Map::new(), } } } fn default_duration() -> Duration { - Duration::seconds(0) + Duration::try_seconds(0).unwrap() } #[test] @@ -77,7 +77,7 @@ fn test_event() { let e = Event { id: None, timestamp: Utc::now(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(0).unwrap(), data: json_map! {"test": json!(1)}, }; debug!("event: {:?}", e); diff --git a/aw-query/benches/benchmark.rs b/aw-query/benches/benchmark.rs index 41a2bea1..38f0e23b 100644 --- a/aw-query/benches/benchmark.rs +++ b/aw-query/benches/benchmark.rs @@ -61,8 +61,8 @@ mod query_benchmarks { for i in 0..num_events { let e = Event { id: None, - timestamp: chrono::Utc::now() + Duration::seconds(i), - duration: Duration::seconds(10), + timestamp: chrono::Utc::now() + Duration::try_seconds(i).unwrap(), + duration: Duration::try_seconds(10).unwrap(), data: possible_data[i as usize % 20].clone(), }; event_list.push(e); diff --git a/aw-query/src/functions.rs b/aw-query/src/functions.rs index c060b9a6..240b6afe 100644 --- a/aw-query/src/functions.rs +++ b/aw-query/src/functions.rs @@ -269,7 +269,7 @@ mod qfunctions { validate::args_length(&args, 1)?; let events: Vec = (&args[0]).try_into()?; // Run flood - let mut flooded_events = aw_transform::flood(events, chrono::Duration::seconds(5)); + let mut flooded_events = aw_transform::flood(events, chrono::Duration::try_seconds(5).unwrap()); // Put events back into DataType::Event container let mut tagged_flooded_events = Vec::new(); for event in flooded_events.drain(..) { diff --git a/aw-query/tests/query.rs b/aw-query/tests/query.rs index 2bb551c1..2d22f64e 100644 --- a/aw-query/tests/query.rs +++ b/aw-query/tests/query.rs @@ -67,14 +67,14 @@ mod query_tests { let e1 = Event { id: None, timestamp: chrono::Utc::now(), - duration: Duration::seconds(0), + duration: Duration::try_seconds(0).unwrap(), data: json_map! {"key": json!("value")}, }; let mut e2 = e1.clone(); e2.timestamp = chrono::Utc::now(); let mut e_replace = e2.clone(); e_replace.data = json_map! {"key": json!("value2")}; - e_replace.duration = Duration::seconds(2); + e_replace.duration = Duration::try_seconds(2).unwrap(); let mut event_list = Vec::new(); event_list.push(e1); diff --git a/aw-sync/tests/sync.rs b/aw-sync/tests/sync.rs index 7de35c97..d6a8f532 100644 --- a/aw-sync/tests/sync.rs +++ b/aw-sync/tests/sync.rs @@ -241,7 +241,7 @@ mod sync_tests { // Insert some testing events into the bucket let events: Vec = (0..3) .map(|i| { - let timestamp: DateTime = Utc::now() + Duration::milliseconds(i * 10); + let timestamp: DateTime = Utc::now() + Duration::try_milliseconds(i * 10).unwrap(); let event_jsonstr = format!( r#"{{ "timestamp": "{}", diff --git a/aw-transform/benches/bench.rs b/aw-transform/benches/bench.rs index 0631e67c..5fab4c3a 100644 --- a/aw-transform/benches/bench.rs +++ b/aw-transform/benches/bench.rs @@ -31,8 +31,8 @@ fn create_events(num_events: i64) -> Vec { for i in 0..num_events { let e = Event { id: None, - timestamp: chrono::Utc::now() + Duration::seconds(i), - duration: Duration::seconds(10), + timestamp: chrono::Utc::now() + Duration::try_seconds(i).unwrap(), + duration: Duration::try_seconds(10).unwrap(), data: possible_data[i as usize % 20].clone(), }; event_list.push(e); diff --git a/aw-transform/src/chunk.rs b/aw-transform/src/chunk.rs index 51c9f735..c1378afc 100644 --- a/aw-transform/src/chunk.rs +++ b/aw-transform/src/chunk.rs @@ -63,7 +63,7 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let mut e2 = e1.clone(); @@ -74,7 +74,7 @@ mod tests { let res = chunk_events_by_key(vec![e1, e2, e3, e4], "test"); assert_eq!(res.len(), 2); - assert_eq!(res[0].duration, Duration::seconds(2)); - assert_eq!(res[1].duration, Duration::seconds(1)); + assert_eq!(res[0].duration, Duration::try_seconds(2).unwrap()); + assert_eq!(res[1].duration, Duration::try_seconds(1).unwrap()); } } diff --git a/aw-transform/src/filter_keyvals.rs b/aw-transform/src/filter_keyvals.rs index 3d5d44d1..dfe5e58b 100644 --- a/aw-transform/src/filter_keyvals.rs +++ b/aw-transform/src/filter_keyvals.rs @@ -93,7 +93,7 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let mut e2 = e1.clone(); @@ -109,7 +109,7 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"key1": json!("value1")}, }; let mut e2 = e1.clone(); @@ -139,7 +139,7 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"key1": json!(100)}, }; let events = vec![e1.clone()]; @@ -153,7 +153,7 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let mut e2 = e1.clone(); diff --git a/aw-transform/src/filter_period.rs b/aw-transform/src/filter_period.rs index 6af8d5c2..66aeb218 100644 --- a/aw-transform/src/filter_period.rs +++ b/aw-transform/src/filter_period.rs @@ -34,7 +34,7 @@ pub fn filter_period_intersect(events: Vec, filter_events: Vec) -> loop { let event_endtime = cur_event.calculate_endtime(); let filter_endtime = cur_filter_event.calculate_endtime(); - if cur_event.duration == Duration::seconds(0) || event_endtime <= cur_filter_event.timestamp + if cur_event.duration == Duration::try_seconds(0).unwrap() || event_endtime <= cur_filter_event.timestamp { match events_iter.next() { Some(e) => { @@ -86,7 +86,7 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let mut e2 = e1.clone(); @@ -101,16 +101,16 @@ mod tests { let filter_event = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:02.5Z").unwrap(), - duration: Duration::seconds(2), + duration: Duration::try_seconds(2).unwrap(), data: json_map! {"test": json!(1)}, }; let filtered_events = filter_period_intersect(vec![e1, e2, e3, e4, e5], vec![filter_event.clone()]); assert_eq!(filtered_events.len(), 3); - assert_eq!(filtered_events[0].duration, Duration::milliseconds(500)); - assert_eq!(filtered_events[1].duration, Duration::milliseconds(1000)); - assert_eq!(filtered_events[2].duration, Duration::milliseconds(500)); + assert_eq!(filtered_events[0].duration, Duration::try_milliseconds(500).unwrap()); + assert_eq!(filtered_events[1].duration, Duration::try_milliseconds(1000).unwrap()); + assert_eq!(filtered_events[2].duration, Duration::try_milliseconds(500).unwrap()); let dt: DateTime = DateTime::from_str("2000-01-01T00:00:02.500Z").unwrap(); assert_eq!(filtered_events[0].timestamp, dt); @@ -123,36 +123,36 @@ mod tests { let e = Event { id: None, timestamp: timestamp_01s, - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let mut f2 = filter_event.clone(); f2.timestamp = DateTime::from_str("2000-01-01T00:00:00Z").unwrap(); - f2.duration = Duration::milliseconds(1500); + f2.duration = Duration::try_milliseconds(1500).unwrap(); let res = filter_period_intersect(vec![e.clone()], vec![f2]); assert_eq!(res[0].timestamp, timestamp_01s); - assert_eq!(res[0].duration, Duration::milliseconds(500)); + assert_eq!(res[0].duration, Duration::try_milliseconds(500).unwrap()); let timestamp_01_5s = DateTime::from_str("2000-01-01T00:00:01.5Z").unwrap(); let mut f3 = filter_event.clone(); f3.timestamp = timestamp_01_5s; - f3.duration = Duration::milliseconds(1000); + f3.duration = Duration::try_milliseconds(1000).unwrap(); let res = filter_period_intersect(vec![e.clone()], vec![f3]); assert_eq!(res[0].timestamp, timestamp_01_5s); - assert_eq!(res[0].duration, Duration::milliseconds(500)); + assert_eq!(res[0].duration,Duration::try_milliseconds(500).unwrap() ); let mut f4 = filter_event.clone(); f4.timestamp = DateTime::from_str("2000-01-01T00:00:01.5Z").unwrap(); - f4.duration = Duration::milliseconds(100); + f4.duration = Duration::try_milliseconds(100).unwrap(); let res = filter_period_intersect(vec![e.clone()], vec![f4]); assert_eq!(res[0].timestamp, timestamp_01_5s); - assert_eq!(res[0].duration, Duration::milliseconds(100)); + assert_eq!(res[0].duration, Duration::try_milliseconds(100).unwrap()); let mut f5 = filter_event.clone(); f5.timestamp = DateTime::from_str("2000-01-01T00:00:00Z").unwrap(); - f5.duration = Duration::seconds(10); + f5.duration = Duration::try_seconds(10).unwrap(); let res = filter_period_intersect(vec![e.clone()], vec![f5]); assert_eq!(res[0].timestamp, timestamp_01s); - assert_eq!(res[0].duration, Duration::milliseconds(1000)); + assert_eq!(res[0].duration, Duration::try_milliseconds(1000).unwrap()); } } diff --git a/aw-transform/src/flood.rs b/aw-transform/src/flood.rs index 8cfeef70..2e494f21 100644 --- a/aw-transform/src/flood.rs +++ b/aw-transform/src/flood.rs @@ -42,7 +42,7 @@ pub fn flood(events: Vec, pulsetime: chrono::Duration) -> Vec { let mut retry_e: Option = None; // If negative gaps are smaller than this, prune them to become zero - let negative_gap_trim_thres = chrono::Duration::milliseconds(100); + let negative_gap_trim_thres = chrono::Duration::try_milliseconds(100).unwrap(); let mut warned_negative_gap_safe = false; let mut warned_negative_gap_unsafe = false; @@ -74,7 +74,7 @@ pub fn flood(events: Vec, pulsetime: chrono::Duration) -> Vec { // We split the program flow into 2 parts: positive and negative gaps // First we check negative gaps (if events overlap) - if gap < chrono::Duration::seconds(0) { + if gap < chrono::Duration::try_seconds(0).unwrap() { // Python implementation: // // if gap < timedelta(0) and e1.data == e2.data: @@ -129,7 +129,7 @@ pub fn flood(events: Vec, pulsetime: chrono::Duration) -> Vec { // warned_about_negative_gap_unsafe = True // Ensure that gap is actually non-negative here, at least in tests - debug_assert!(gap >= chrono::Duration::seconds(0)); + debug_assert!(gap >= chrono::Duration::try_seconds(0).unwrap()); // If data is the same, we should merge them. if e1.data == e2.data { @@ -179,22 +179,22 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let e2 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:03Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let e_expected = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(4), + duration: Duration::try_seconds(4).unwrap(), data: json_map! {"test": json!(1)}, }; - let res = flood(vec![e1, e2], Duration::seconds(5)); + let res = flood(vec![e1, e2], Duration::try_seconds(5).unwrap()); assert_eq!(1, res.len()); assert_eq!(&res[0], &e_expected); } @@ -205,28 +205,28 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let e2 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:03Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(2)}, }; let e1_expected = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(2), + duration: Duration::try_seconds(2).unwrap(), data: json_map! {"test": json!(1)}, }; let e2_expected = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:02Z").unwrap(), - duration: Duration::seconds(2), + duration: Duration::try_seconds(2).unwrap(), data: json_map! {"test": json!(2)}, }; - let res = flood(vec![e1, e2], Duration::seconds(5)); + let res = flood(vec![e1, e2], Duration::try_seconds(5).unwrap()); assert_eq!(2, res.len()); assert_eq!(&res[0], &e1_expected); assert_eq!(&res[1], &e2_expected); @@ -238,22 +238,22 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(10), + duration: Duration::try_seconds(10).unwrap(), data: json_map! {"type": "a"}, }; let e2 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:05Z").unwrap(), - duration: Duration::seconds(10), + duration: Duration::try_seconds(10).unwrap(), data: json_map! {"type": "a"}, }; let e1_expected = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(15), + duration: Duration::try_seconds(15).unwrap(), data: json_map! {"type": "a"}, }; - let res = flood(vec![e1, e2], Duration::seconds(5)); + let res = flood(vec![e1, e2], Duration::try_seconds(5).unwrap()); assert_eq!(1, res.len()); assert_eq!(&res[0], &e1_expected); } @@ -264,16 +264,16 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(10), + duration: Duration::try_seconds(10).unwrap(), data: json_map! {"type": "a"}, }; let e2 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(5), + duration: Duration::try_seconds(5).unwrap(), data: json_map! {"type": "a"}, }; - let res = flood(vec![e1.clone(), e2], Duration::seconds(5)); + let res = flood(vec![e1.clone(), e2], Duration::try_seconds(5).unwrap()); assert_eq!(1, res.len()); assert_eq!(&res[0], &e1); } @@ -285,16 +285,16 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(10), + duration: Duration::try_seconds(10).unwrap(), data: json_map! {"type": "a"}, }; let e2 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(5), + duration: Duration::try_seconds(5).unwrap(), data: json_map! {"type": "b"}, }; - let res = flood(vec![e1.clone(), e2.clone()], Duration::seconds(5)); + let res = flood(vec![e1.clone(), e2.clone()], Duration::try_seconds(5).unwrap()); assert_eq!(2, res.len()); assert_eq!(&res[0], &e1); assert_eq!(&res[1], &e2); @@ -309,30 +309,30 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"status": "afk"}, }; let e2 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(5), + duration: Duration::try_seconds(5).unwrap(), data: json_map! {"status": "not-afk"}, }; let e3 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"status": "not-afk"}, }; let e4 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:06Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"status": "afk"}, }; let res = flood( vec![e1.clone(), e2.clone(), e3, e4.clone()], - Duration::seconds(5), + Duration::try_seconds(5).unwrap(), ); assert_eq!(3, res.len()); assert_eq!(&res[0], &e1); @@ -350,36 +350,36 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"status": "afk"}, }; let e2 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(5), + duration: Duration::try_seconds(5).unwrap(), data: json_map! {"status": "not-afk"}, }; let e3 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"status": "not-afk"}, }; let e4 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(10), + duration: Duration::try_seconds(10).unwrap(), data: json_map! {"status": "not-afk"}, }; let e5 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:11Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"status": "afk"}, }; let res = flood( vec![e1.clone(), e2, e3, e4.clone(), e5.clone()], - Duration::seconds(5), + Duration::try_seconds(5).unwrap(), ); assert_eq!(3, res.len()); assert_eq!(&res[0], &e1); diff --git a/aw-transform/src/heartbeat.rs b/aw-transform/src/heartbeat.rs index c5173833..1df52b8f 100644 --- a/aw-transform/src/heartbeat.rs +++ b/aw-transform/src/heartbeat.rs @@ -74,20 +74,20 @@ mod tests { let event1 = Event { id: None, timestamp: now, - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let heartbeat1 = Event { id: None, - timestamp: now + Duration::seconds(2), - duration: Duration::seconds(1), + timestamp: now + Duration::try_seconds(2).unwrap(), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; // Merge result let res_merge = heartbeat(&event1, &heartbeat1, 2.0).unwrap(); assert_eq!(res_merge.timestamp, now); - assert_eq!(res_merge.duration, Duration::seconds(3)); + assert_eq!(res_merge.duration, Duration::try_seconds(3).unwrap()); assert_eq!(res_merge.data, event1.data); // No merge result @@ -103,14 +103,14 @@ mod tests { let event = Event { id: None, timestamp: now, - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let long_pulse_event = Event { id: None, // note that no duration is sent, which is how aw-client works - duration: Duration::seconds(0), - timestamp: now + Duration::seconds(120), + duration: Duration::try_seconds(0).unwrap(), + timestamp: now + Duration::try_seconds(120).unwrap(), data: json_map! {"test": json!(1)}, }; @@ -118,7 +118,7 @@ mod tests { let res_merge = heartbeat(&event, &long_pulse_event, 120.0).unwrap(); assert_eq!(res_merge.timestamp, now); assert_eq!(res_merge.data, event.data); - assert_eq!(res_merge.duration, Duration::seconds(120)); + assert_eq!(res_merge.duration, Duration::try_seconds(120).unwrap()); // No merge result when pulsetime is less than the timestamp delta between heartbeats let res_no_merge = heartbeat(&event, &long_pulse_event, 60.0); @@ -131,13 +131,13 @@ mod tests { let event = Event { id: None, timestamp: now, - duration: Duration::seconds(0), + duration: Duration::try_seconds(0).unwrap(), data: json_map! {"test": json!(1)}, }; let heartbeat_same_data = Event { id: None, timestamp: now, - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; @@ -148,7 +148,7 @@ mod tests { let heartbeat_different_data = Event { id: None, timestamp: now, - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(2)}, }; // Data is different, should not merge @@ -162,22 +162,22 @@ mod tests { let event = Event { id: None, timestamp: now, - duration: Duration::seconds(0), + duration: Duration::try_seconds(0).unwrap(), data: json_map! {"test": json!(1)}, }; let heartbeat_same_data = Event { id: None, timestamp: now, - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; // Should merge let res_merge = heartbeat(&event, &heartbeat_same_data, 1.0).unwrap(); - assert_eq!(Duration::seconds(1), res_merge.duration); + assert_eq!(Duration::try_seconds(1).unwrap(), res_merge.duration); // Order shouldn't matter, should merge anyway let res_merge = heartbeat(&heartbeat_same_data, &event, 1.0).unwrap(); - assert_eq!(Duration::seconds(1), res_merge.duration); + assert_eq!(Duration::try_seconds(1).unwrap(), res_merge.duration); } } diff --git a/aw-transform/src/merge.rs b/aw-transform/src/merge.rs index 81c81336..b2b72d7e 100644 --- a/aw-transform/src/merge.rs +++ b/aw-transform/src/merge.rs @@ -97,25 +97,25 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let e2 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(3), + duration: Duration::try_seconds(3).unwrap(), data: json_map! {"test2": json!(3)}, }; let e3 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:02Z").unwrap(), - duration: Duration::seconds(7), + duration: Duration::try_seconds(7).unwrap(), data: json_map! {"test": json!(6)}, }; let e4 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:03Z").unwrap(), - duration: Duration::seconds(9), + duration: Duration::try_seconds(9).unwrap(), data: json_map! {"test": json!(1)}, }; let in_events = vec![e1, e2, e3, e4]; @@ -126,13 +126,13 @@ mod tests { Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(10), + duration: Duration::try_seconds(10).unwrap(), data: json_map! {"test": json!(1)}, }, Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:02Z").unwrap(), - duration: Duration::seconds(7), + duration: Duration::try_seconds(7).unwrap(), data: json_map! {"test": json!(6)}, }, ]; diff --git a/aw-transform/src/period_union.rs b/aw-transform/src/period_union.rs index 28cdda66..52558c66 100644 --- a/aw-transform/src/period_union.rs +++ b/aw-transform/src/period_union.rs @@ -79,7 +79,7 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; @@ -91,7 +91,7 @@ mod tests { let dt: DateTime = DateTime::from_str("2000-01-01T00:00:01.000Z").unwrap(); assert_eq!(e_result[0].timestamp, dt); - assert_eq!(e_result[0].duration, Duration::milliseconds(2000)); + assert_eq!(e_result[0].duration, Duration::try_milliseconds(2000).unwrap()); } /// Make sure nothing gets done when nothing to union (gaps present) @@ -100,7 +100,7 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; @@ -116,7 +116,7 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; @@ -129,7 +129,7 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; diff --git a/aw-transform/src/sort.rs b/aw-transform/src/sort.rs index fddcd2ef..0838a8de 100644 --- a/aw-transform/src/sort.rs +++ b/aw-transform/src/sort.rs @@ -29,13 +29,13 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let e2 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:03Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let res = sort_by_timestamp(vec![e2.clone(), e1.clone()]); @@ -47,13 +47,13 @@ mod tests { let e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(), - duration: Duration::seconds(2), + duration: Duration::try_seconds(2).unwrap(), data: json_map! {"test": json!(1)}, }; let e2 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:03Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"test": json!(1)}, }; let res = sort_by_duration(vec![e2.clone(), e1.clone()]); diff --git a/aw-transform/src/split_url.rs b/aw-transform/src/split_url.rs index 27b59ebf..51b07c86 100644 --- a/aw-transform/src/split_url.rs +++ b/aw-transform/src/split_url.rs @@ -81,7 +81,7 @@ mod tests { let mut e1 = Event { id: None, timestamp: DateTime::from_str("2000-01-01T00:00:01Z").unwrap(), - duration: Duration::seconds(1), + duration: Duration::try_seconds(1).unwrap(), data: json_map! {"url": "http://www.google.com/path?query=1"}, }; split_url_event(&mut e1); diff --git a/aw-transform/src/union_no_overlap.rs b/aw-transform/src/union_no_overlap.rs index 8c9ea0c8..cce620d2 100644 --- a/aw-transform/src/union_no_overlap.rs +++ b/aw-transform/src/union_no_overlap.rs @@ -83,11 +83,11 @@ mod tests { #[test] fn test_split_event() { let now = Utc::now(); - let td1h = Duration::hours(1); + let td1h = Duration::try_hours(1).unwrap(); let e = Event { id: None, timestamp: now, - duration: Duration::hours(2), + duration: Duration::try_hours(2).unwrap(), data: serde_json::Map::new(), }; let (e1, e2_opt) = split_event(&e, now + td1h); @@ -101,7 +101,7 @@ mod tests { // Now a test which does not lead to a split let (e1, e2_opt) = split_event(&e, now); assert_eq!(e1.timestamp, now); - assert_eq!(e1.duration, Duration::hours(2)); + assert_eq!(e1.duration, Duration::try_hours(2).unwrap()); assert!(e2_opt.is_none()); } @@ -109,7 +109,7 @@ mod tests { fn test_union_no_overlap() { // A test without any actual overlap let now = Utc::now(); - let td1h = Duration::hours(1); + let td1h = Duration::try_hours(1).unwrap(); let e1 = Event::new(now, td1h, serde_json::Map::new()); let e2 = Event::new(now + td1h, td1h, serde_json::Map::new()); let events1 = vec![e1.clone()]; @@ -139,9 +139,9 @@ mod tests { fn test_union_no_overlap_with_overlap() { // A test where the events overlap let now = Utc::now(); - let td1h = Duration::hours(1); + let td1h = Duration::try_hours(1).unwrap(); let e1 = Event::new(now, td1h, serde_json::Map::new()); - let e2 = Event::new(now, Duration::hours(2), serde_json::Map::new()); + let e2 = Event::new(now, Duration::try_hours(1).unwrap(), serde_json::Map::new()); let events1 = vec![e1]; let events2 = vec![e2]; let events_union = union_no_overlap(events1, events2); @@ -154,7 +154,7 @@ mod tests { // Now test the case where e2 starts before e1 let e1 = Event::new(now + td1h, td1h, serde_json::Map::new()); - let e2 = Event::new(now, Duration::hours(2), serde_json::Map::new()); + let e2 = Event::new(now, Duration::try_hours(2).unwrap(), serde_json::Map::new()); let events1 = vec![e1]; let events2 = vec![e2]; let events_union = union_no_overlap(events1, events2); From b9eae079b92375997c3f31cde72524177d4b834d Mon Sep 17 00:00:00 2001 From: brayo Date: Wed, 3 Apr 2024 12:31:26 +0300 Subject: [PATCH 04/20] working code for testing --- Cargo.lock | 3 ++ aw-firebase-sync/Cargo.toml | 3 ++ aw-firebase-sync/src/main.rs | 55 +++++++++++++++++++++--------------- 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5cd426c7..4365d4b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -235,6 +235,9 @@ dependencies = [ "aw-client-rust", "aw-models", "chrono", + "reqwest", + "serde", + "serde_json", "tokio", ] diff --git a/aw-firebase-sync/Cargo.toml b/aw-firebase-sync/Cargo.toml index 47bebf4b..972f852e 100644 --- a/aw-firebase-sync/Cargo.toml +++ b/aw-firebase-sync/Cargo.toml @@ -10,3 +10,6 @@ chrono = "0.4.35" tokio = { version = "1", features = ["full"] } aw-client-rust = { path = "../aw-client-rust" } aw-models = { path = "../aw-models" } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0.70" +reqwest = "0.11.4" \ No newline at end of file diff --git a/aw-firebase-sync/src/main.rs b/aw-firebase-sync/src/main.rs index fb28c54a..19e34ac0 100644 --- a/aw-firebase-sync/src/main.rs +++ b/aw-firebase-sync/src/main.rs @@ -1,31 +1,42 @@ -use tokio; +// use aw_models::{Query, TimeInterval}; +use reqwest; +use chrono::{DateTime, TimeZone, Utc}; +use serde_json::{json, Value}; use aw_client_rust::AwClient; -use chrono::prelude::*; -pub struct TimeInterval { - pub start: DateTime, - pub end: DateTime, -} + #[tokio::main] async fn main() -> Result<(), Box> { // Create a new client - let client = AwClient::new("localhost", 5600, "my-client").unwrap(); + let aw_client = AwClient::new("localhost", 5600, "test").unwrap(); + + let start = Utc.with_ymd_and_hms(2024, 3, 1, 0, 0, 0).unwrap(); + let end = Utc.with_ymd_and_hms(2024, 4, 1, 0, 0, 0).unwrap(); + + let res = aw_client.get_events("aw-watcher-window_brayo",Some(start),Some(end), Some(50)).await.unwrap(); - // Define the query - let _query = vec![ - "events = query_bucket(\"aw-watcher-window_my-hostname\");".to_string(), - "events = merge_events_by_keys(events, [\"app\"]);".to_string(), - "RETURN = sort_by_duration(events);".to_string(), - ]; + let res_string = serde_json::to_string(&res).unwrap(); + // println!("{:?}", res_string); + // Your Firebase callable function URL + let url = "https://us-central1-aw-mockup.cloudfunctions.net/storeDataREST"; - let start = Utc.with_ymd_and_hms(2024, 3, 20, 0, 0, 0).unwrap(); - let end = Utc.with_ymd_and_hms(2024, 3, 28, 0, 0, 0).unwrap(); - let _timeperiod = TimeInterval{start, end}; + // Prepare the request body + let payload = json!({ + "apiKey": "fv3yShDm3VHuMjts1P7A+LcjvR66", + "data": res_string + }); - // let buckets = client.get_buckets().await?; - // println!("{:?}", buckets); - let data = client.get_events("aw-watcher-window_brayo", Some(start), Some(end), Some(50)).await.unwrap(); - // Print the result - println!("{:?}", data); + // Send the POST request + let http_client = reqwest::Client::new(); + let response = http_client + .post(url) + .json(&payload) + .send() + .await? + .json::() + .await?; + + // Handle the response + println!("Response: {:?}", response); Ok(()) -} \ No newline at end of file +} From 04817fb6fd96ab003b74f6517b64e7789312043e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Tue, 2 Apr 2024 15:35:34 -0700 Subject: [PATCH 05/20] feat: added query function in aw-client --- aw-client-rust/src/blocking.rs | 6 ++++++ aw-client-rust/src/lib.rs | 28 +++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/aw-client-rust/src/blocking.rs b/aw-client-rust/src/blocking.rs index 3acd8eb9..f16dc1f0 100644 --- a/aw-client-rust/src/blocking.rs +++ b/aw-client-rust/src/blocking.rs @@ -62,6 +62,12 @@ impl AwClient { stop: Option>, limit: Option ); + proxy_method!( + query, + serde_json::Value, + query: &str, + timeperiods: Vec<(DateTime, DateTime)> + ); proxy_method!(insert_event, (), bucketname: &str, event: &Event); proxy_method!(insert_events, (), bucketname: &str, events: Vec); proxy_method!( diff --git a/aw-client-rust/src/lib.rs b/aw-client-rust/src/lib.rs index 18fad49e..dca5bb54 100644 --- a/aw-client-rust/src/lib.rs +++ b/aw-client-rust/src/lib.rs @@ -11,7 +11,7 @@ use std::vec::Vec; use std::{collections::HashMap, error::Error}; use chrono::{DateTime, Utc}; -use serde_json::Map; +use serde_json::{json, Map}; pub use aw_models::{Bucket, BucketMetadata, Event}; @@ -98,6 +98,32 @@ impl AwClient { Ok(()) } + pub async fn query( + &self, + query: &str, + timeperiods: Vec<(DateTime, DateTime)>, + ) -> Result { + let url = reqwest::Url::parse(format!("{}/api/0/query", self.baseurl).as_str()).unwrap(); + + // Format timeperiods as ISO8601 strings, separated by / + let timeperiods_str: Vec = timeperiods + .iter() + .map(|(start, stop)| (start.to_rfc3339(), stop.to_rfc3339())) + .map(|(start, stop)| format!("{}/{}", start, stop)) + .collect(); + + self.client + .post(url) + .json(&json!({ + "query": query, + "timeperiods": timeperiods_str, + })) + .send() + .await? + .json() + .await + } + pub async fn get_events( &self, bucketname: &str, From a7a93d0b0624924b2432999867411dcc0401fb8e Mon Sep 17 00:00:00 2001 From: Brayo <62670517+brayo-pip@users.noreply.github.com> Date: Sat, 6 Apr 2024 11:09:53 +0300 Subject: [PATCH 06/20] feat: added query function in aw-client (#477) (#3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: added query function in aw-client * fix: fixed client query * fix: improved return type for client query Co-authored-by: Erik Bjäreholt --- Cargo.lock | 5 +++-- aw-client-rust/src/blocking.rs | 2 +- aw-client-rust/src/lib.rs | 6 +++--- aw-client-rust/tests/test.rs | 16 ++++++++++++++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4365d4b6..d9635544 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -474,9 +474,10 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" + dependencies = [ "android-tzdata", "iana-time-zone", diff --git a/aw-client-rust/src/blocking.rs b/aw-client-rust/src/blocking.rs index f16dc1f0..7d6b6a97 100644 --- a/aw-client-rust/src/blocking.rs +++ b/aw-client-rust/src/blocking.rs @@ -64,7 +64,7 @@ impl AwClient { ); proxy_method!( query, - serde_json::Value, + Vec, query: &str, timeperiods: Vec<(DateTime, DateTime)> ); diff --git a/aw-client-rust/src/lib.rs b/aw-client-rust/src/lib.rs index dca5bb54..c95704a9 100644 --- a/aw-client-rust/src/lib.rs +++ b/aw-client-rust/src/lib.rs @@ -102,7 +102,7 @@ impl AwClient { &self, query: &str, timeperiods: Vec<(DateTime, DateTime)>, - ) -> Result { + ) -> Result, reqwest::Error> { let url = reqwest::Url::parse(format!("{}/api/0/query", self.baseurl).as_str()).unwrap(); // Format timeperiods as ISO8601 strings, separated by / @@ -111,11 +111,11 @@ impl AwClient { .map(|(start, stop)| (start.to_rfc3339(), stop.to_rfc3339())) .map(|(start, stop)| format!("{}/{}", start, stop)) .collect(); - + // Result is a sequence, one element per timeperiod self.client .post(url) .json(&json!({ - "query": query, + "query": query.split('\n').collect::>(), "timeperiods": timeperiods_str, })) .send() diff --git a/aw-client-rust/tests/test.rs b/aw-client-rust/tests/test.rs index 6f465f04..8803e41c 100644 --- a/aw-client-rust/tests/test.rs +++ b/aw-client-rust/tests/test.rs @@ -108,6 +108,22 @@ mod test { println!("Events: {events:?}"); assert!(events[0].duration == Duration::try_seconds(1).unwrap()); + // Query + let query = format!( + "events = query_bucket(\"{}\"); +RETURN = events;", + bucket.id + ); + let start: DateTime = DateTime::parse_from_rfc3339("1996-12-19T00:00:00-08:00") + .unwrap() + .into(); + let end: DateTime = DateTime::parse_from_rfc3339("2020-12-19T00:00:00-08:00") + .unwrap() + .into(); + let timeperiods = (start, end); + let query_result = client.query(&query, vec![timeperiods]).unwrap(); + println!("Query result: {query_result:?}"); + client .delete_event(&bucketname, events[0].id.unwrap()) .unwrap(); From 79083d36acc4ac54763549fc04d2661b5d511569 Mon Sep 17 00:00:00 2001 From: brayo Date: Sun, 7 Apr 2024 13:29:43 +0300 Subject: [PATCH 07/20] feat:querying support --- Cargo.lock | 1 - aw-firebase-sync/src/main.rs | 24 ++++++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9635544..9fce2fad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -477,7 +477,6 @@ name = "chrono" version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" - dependencies = [ "android-tzdata", "iana-time-zone", diff --git a/aw-firebase-sync/src/main.rs b/aw-firebase-sync/src/main.rs index 19e34ac0..f5eb72fb 100644 --- a/aw-firebase-sync/src/main.rs +++ b/aw-firebase-sync/src/main.rs @@ -1,6 +1,5 @@ -// use aw_models::{Query, TimeInterval}; use reqwest; -use chrono::{DateTime, TimeZone, Utc}; +use chrono::{TimeZone, Utc}; use serde_json::{json, Value}; use aw_client_rust::AwClient; @@ -10,18 +9,27 @@ async fn main() -> Result<(), Box> { let aw_client = AwClient::new("localhost", 5600, "test").unwrap(); let start = Utc.with_ymd_and_hms(2024, 3, 1, 0, 0, 0).unwrap(); - let end = Utc.with_ymd_and_hms(2024, 4, 1, 0, 0, 0).unwrap(); + let end = Utc.with_ymd_and_hms(2024, 4, 7, 0, 0, 0).unwrap(); + + let query = "window_events = query_bucket(find_bucket(\"aw-watcher-window_\")); + RETURN = window_events;"; + + let timeperiods = vec!( + (start, end) + ); - let res = aw_client.get_events("aw-watcher-window_brayo",Some(start),Some(end), Some(50)).await.unwrap(); + let res = aw_client.query(&query, timeperiods).await.unwrap(); let res_string = serde_json::to_string(&res).unwrap(); - // println!("{:?}", res_string); - // Your Firebase callable function URL - let url = "https://us-central1-aw-mockup.cloudfunctions.net/storeDataREST"; + // strip the leading and trailing '[' and ']' + let res_string = &res_string[1..res_string.len()-1]; + + // let url = "https://us-central1-aw-mockup.cloudfunctions.net/uploadData"; + let url = "http://localhost:5001/aw-mockup/us-central1/uploadData"; // Prepare the request body let payload = json!({ - "apiKey": "fv3yShDm3VHuMjts1P7A+LcjvR66", + "apiKey": "Je_Q45pexF2Y17gioBIt_ePU.iH", "data": res_string }); From 565975eb0fea0f827bdbd47683238085c63dbff3 Mon Sep 17 00:00:00 2001 From: brayo Date: Tue, 9 Apr 2024 17:30:42 +0300 Subject: [PATCH 08/20] WIP --- Cargo.lock | 58 +++++++++++++++++++++++++++++++----- aw-firebase-sync/Cargo.toml | 1 + aw-firebase-sync/config.yaml | 2 ++ aw-firebase-sync/src/main.rs | 28 ++++++++++++----- 4 files changed, 74 insertions(+), 15 deletions(-) create mode 100644 aw-firebase-sync/config.yaml diff --git a/Cargo.lock b/Cargo.lock index 9fce2fad..3d215c8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -238,6 +238,7 @@ dependencies = [ "reqwest", "serde", "serde_json", + "serde_yaml", "tokio", ] @@ -1072,7 +1073,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 2.1.0", "slab", "tokio", "tokio-util", @@ -1085,6 +1086,12 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.3" @@ -1101,7 +1108,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown", + "hashbrown 0.14.3", ] [[package]] @@ -1220,6 +1227,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + [[package]] name = "indexmap" version = "2.1.0" @@ -1227,7 +1244,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.3", "serde", ] @@ -1358,6 +1375,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.4.12" @@ -2018,7 +2041,7 @@ dependencies = [ "either", "figment", "futures", - "indexmap", + "indexmap 2.1.0", "log", "memchr", "multer", @@ -2050,7 +2073,7 @@ checksum = "a2238066abf75f21be6cd7dc1a09d5414a671f4246e384e49fe3f8a4936bd04c" dependencies = [ "devise", "glob", - "indexmap", + "indexmap 2.1.0", "proc-macro2", "quote", "rocket_http", @@ -2087,7 +2110,7 @@ dependencies = [ "futures", "http", "hyper", - "indexmap", + "indexmap 2.1.0", "log", "memchr", "pear", @@ -2332,6 +2355,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_yaml" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" +dependencies = [ + "indexmap 1.9.3", + "ryu", + "serde", + "yaml-rust", +] + [[package]] name = "sha2" version = "0.10.8" @@ -2690,7 +2725,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ - "indexmap", + "indexmap 2.1.0", "serde", "serde_spanned", "toml_datetime", @@ -3214,6 +3249,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "yansi" version = "1.0.0-rc.1" diff --git a/aw-firebase-sync/Cargo.toml b/aw-firebase-sync/Cargo.toml index 972f852e..9e65aaae 100644 --- a/aw-firebase-sync/Cargo.toml +++ b/aw-firebase-sync/Cargo.toml @@ -12,4 +12,5 @@ aw-client-rust = { path = "../aw-client-rust" } aw-models = { path = "../aw-models" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.70" +serde_yaml = "0.8.18" reqwest = "0.11.4" \ No newline at end of file diff --git a/aw-firebase-sync/config.yaml b/aw-firebase-sync/config.yaml new file mode 100644 index 00000000..c2b3d56c --- /dev/null +++ b/aw-firebase-sync/config.yaml @@ -0,0 +1,2 @@ +# you can get your api key from activitywatch leaderboard +apikey: "your-api-key" \ No newline at end of file diff --git a/aw-firebase-sync/src/main.rs b/aw-firebase-sync/src/main.rs index f5eb72fb..1b2e435c 100644 --- a/aw-firebase-sync/src/main.rs +++ b/aw-firebase-sync/src/main.rs @@ -1,23 +1,35 @@ use reqwest; -use chrono::{TimeZone, Utc}; +use chrono::Utc; use serde_json::{json, Value}; +use serde_yaml; use aw_client_rust::AwClient; +use std::fs::File; +use std::io::prelude::*; #[tokio::main] async fn main() -> Result<(), Box> { // Create a new client - let aw_client = AwClient::new("localhost", 5600, "test").unwrap(); - - let start = Utc.with_ymd_and_hms(2024, 3, 1, 0, 0, 0).unwrap(); - let end = Utc.with_ymd_and_hms(2024, 4, 7, 0, 0, 0).unwrap(); + let aw_client = AwClient::new("localhost", 5600, "aw-firebase-sync").unwrap(); + // 7 days ago + let start = Utc::now().date().and_hms_opt(0, 0, 0).unwrap() - chrono::Duration::days(6); + let end = Utc::now().date().and_hms_opt(0, 0, 0).unwrap() + chrono::Duration::days(1); + + let mut file = File::open("config.yaml").expect("Unable to open file"); + let mut contents = String::new(); + file.read_to_string(&mut contents).expect("Unable to read file"); + let yaml: Value = serde_yaml::from_str(&contents).unwrap(); + let apikey = yaml["apikey"].as_str().unwrap().to_string(); + if apikey == "your-api-key" || apikey == "" { + panic!("Please set your API key in the config.yaml file"); + } let query = "window_events = query_bucket(find_bucket(\"aw-watcher-window_\")); RETURN = window_events;"; - + let timeperiods = vec!( (start, end) ); - + let res = aw_client.query(&query, timeperiods).await.unwrap(); let res_string = serde_json::to_string(&res).unwrap(); @@ -29,7 +41,7 @@ async fn main() -> Result<(), Box> { // Prepare the request body let payload = json!({ - "apiKey": "Je_Q45pexF2Y17gioBIt_ePU.iH", + "apiKey": apikey, "data": res_string }); From 3c29ae6471f3e3d27c784c3ba3af5d2d6d952312 Mon Sep 17 00:00:00 2001 From: brayo Date: Tue, 9 Apr 2024 20:37:04 +0300 Subject: [PATCH 09/20] polishing a bit --- aw-firebase-sync/config.yaml | 2 +- aw-firebase-sync/src/main.rs | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/aw-firebase-sync/config.yaml b/aw-firebase-sync/config.yaml index c2b3d56c..05d09222 100644 --- a/aw-firebase-sync/config.yaml +++ b/aw-firebase-sync/config.yaml @@ -1,2 +1,2 @@ # you can get your api key from activitywatch leaderboard -apikey: "your-api-key" \ No newline at end of file +apikey: your-api-key \ No newline at end of file diff --git a/aw-firebase-sync/src/main.rs b/aw-firebase-sync/src/main.rs index 1b2e435c..2bb2dad1 100644 --- a/aw-firebase-sync/src/main.rs +++ b/aw-firebase-sync/src/main.rs @@ -8,9 +8,7 @@ use std::io::prelude::*; #[tokio::main] async fn main() -> Result<(), Box> { - // Create a new client let aw_client = AwClient::new("localhost", 5600, "aw-firebase-sync").unwrap(); - // 7 days ago let start = Utc::now().date().and_hms_opt(0, 0, 0).unwrap() - chrono::Duration::days(6); let end = Utc::now().date().and_hms_opt(0, 0, 0).unwrap() + chrono::Duration::days(1); @@ -36,26 +34,23 @@ async fn main() -> Result<(), Box> { // strip the leading and trailing '[' and ']' let res_string = &res_string[1..res_string.len()-1]; - // let url = "https://us-central1-aw-mockup.cloudfunctions.net/uploadData"; - let url = "http://localhost:5001/aw-mockup/us-central1/uploadData"; + let firebase_url = "https://us-central1-aw-mockup.cloudfunctions.net/uploadData"; + // let firebase_url = "http://localhost:5001/aw-mockup/us-central1/uploadData"; - // Prepare the request body let payload = json!({ "apiKey": apikey, "data": res_string }); - // Send the POST request - let http_client = reqwest::Client::new(); - let response = http_client - .post(url) + let firebase_client = reqwest::Client::new(); + let response = firebase_client + .post(firebase_url) .json(&payload) .send() .await? .json::() .await?; - // Handle the response println!("Response: {:?}", response); Ok(()) From 49249434b9b5bc9cf38ba09ae0bac504900a7a38 Mon Sep 17 00:00:00 2001 From: brayo Date: Mon, 17 Jun 2024 15:13:05 +0300 Subject: [PATCH 10/20] add a README.md --- aw-firebase-sync/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 aw-firebase-sync/README.md diff --git a/aw-firebase-sync/README.md b/aw-firebase-sync/README.md new file mode 100644 index 00000000..9b99400a --- /dev/null +++ b/aw-firebase-sync/README.md @@ -0,0 +1,10 @@ +aw-firebase-sync +================ + +Firebase sync for ActivityWatch [leaderboard](https://github.com/ActivityWatch/aw-firebase-leaderboard). + +This is exports screentime data from ActivityWatch and uploads it to firebase. + +## Status + +Still in early development, not ready for use yet. From f15fe71cab460e2f1ffccc876fc2a100f67ec562 Mon Sep 17 00:00:00 2001 From: brayo Date: Mon, 17 Jun 2024 16:21:56 +0300 Subject: [PATCH 11/20] feat: move config file to platform specific configuration folder Improve error handling --- aw-firebase-sync/Cargo.toml | 3 ++- aw-firebase-sync/src/main.rs | 45 ++++++++++++++++++++++++++---------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/aw-firebase-sync/Cargo.toml b/aw-firebase-sync/Cargo.toml index 9e65aaae..d7d4f56c 100644 --- a/aw-firebase-sync/Cargo.toml +++ b/aw-firebase-sync/Cargo.toml @@ -13,4 +13,5 @@ aw-models = { path = "../aw-models" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.70" serde_yaml = "0.8.18" -reqwest = "0.11.4" \ No newline at end of file +reqwest = { version = "0.12.4" , features = ["full"] } +dirs = "5.0.1" \ No newline at end of file diff --git a/aw-firebase-sync/src/main.rs b/aw-firebase-sync/src/main.rs index 2bb2dad1..2cd9d443 100644 --- a/aw-firebase-sync/src/main.rs +++ b/aw-firebase-sync/src/main.rs @@ -1,9 +1,10 @@ -use reqwest; +use aw_client_rust::AwClient; use chrono::Utc; +use dirs::config_dir; +use reqwest; use serde_json::{json, Value}; use serde_yaml; -use aw_client_rust::AwClient; -use std::fs::File; +use std::fs::{DirBuilder, File}; use std::io::prelude::*; #[tokio::main] @@ -12,11 +13,32 @@ async fn main() -> Result<(), Box> { let start = Utc::now().date().and_hms_opt(0, 0, 0).unwrap() - chrono::Duration::days(6); let end = Utc::now().date().and_hms_opt(0, 0, 0).unwrap() + chrono::Duration::days(1); - let mut file = File::open("config.yaml").expect("Unable to open file"); + let path = config_dir() + .map(|mut path| { + path.push("activitywatch"); + path.push("aw-firebase-sync"); + path.push("config.yaml"); + path + }) + .unwrap(); + + if !path.exists() { + DirBuilder::new() + .recursive(true) + .create(path.as_path().parent().expect("Unable to get parent path")) + .expect("Unable to create config directory"); + let mut file = File::create(&path).expect("Unable to create file"); + file.write_all(b"apikey: your-api-key\n") + .expect("Unable to write to file"); + panic!("Please set your API key at {:?}", path.to_str().unwrap()); + } + + let mut file = File::open(path).expect("Unable to open file"); let mut contents = String::new(); - file.read_to_string(&mut contents).expect("Unable to read file"); - let yaml: Value = serde_yaml::from_str(&contents).unwrap(); - let apikey = yaml["apikey"].as_str().unwrap().to_string(); + file.read_to_string(&mut contents) + .expect("Unable to read file"); + let yaml: Value = serde_yaml::from_str(&contents).expect("Failed parsing yaml from config file"); + let apikey = yaml["apikey"].as_str().expect("unable to get api key from config file"); if apikey == "your-api-key" || apikey == "" { panic!("Please set your API key in the config.yaml file"); } @@ -24,15 +46,14 @@ async fn main() -> Result<(), Box> { let query = "window_events = query_bucket(find_bucket(\"aw-watcher-window_\")); RETURN = window_events;"; - let timeperiods = vec!( - (start, end) - ); + let timeperiods = vec![(start, end)]; - let res = aw_client.query(&query, timeperiods).await.unwrap(); + // TODO: handle errors + let res = aw_client.query(&query, timeperiods).await.unwrap(); let res_string = serde_json::to_string(&res).unwrap(); // strip the leading and trailing '[' and ']' - let res_string = &res_string[1..res_string.len()-1]; + let res_string = &res_string[1..res_string.len() - 1]; let firebase_url = "https://us-central1-aw-mockup.cloudfunctions.net/uploadData"; // let firebase_url = "http://localhost:5001/aw-mockup/us-central1/uploadData"; From 4ff8bc42a8671d6fef256a7a349b8874650d6a87 Mon Sep 17 00:00:00 2001 From: brayo Date: Mon, 17 Jun 2024 17:09:11 +0300 Subject: [PATCH 12/20] fix: features fix on reqwest --- aw-firebase-sync/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aw-firebase-sync/Cargo.toml b/aw-firebase-sync/Cargo.toml index d7d4f56c..fa4c36e3 100644 --- a/aw-firebase-sync/Cargo.toml +++ b/aw-firebase-sync/Cargo.toml @@ -13,5 +13,5 @@ aw-models = { path = "../aw-models" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.70" serde_yaml = "0.8.18" -reqwest = { version = "0.12.4" , features = ["full"] } +reqwest = { version = "0.12.4" , features = ["json"] } dirs = "5.0.1" \ No newline at end of file From e72f7ff03ee392eb67df15c518faa9f2631f4739 Mon Sep 17 00:00:00 2001 From: brayo Date: Wed, 19 Jun 2024 09:53:57 +0300 Subject: [PATCH 13/20] feat: temporarily match only AW events --- aw-firebase-sync/src/main.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/aw-firebase-sync/src/main.rs b/aw-firebase-sync/src/main.rs index 2cd9d443..31580bfe 100644 --- a/aw-firebase-sync/src/main.rs +++ b/aw-firebase-sync/src/main.rs @@ -37,19 +37,30 @@ async fn main() -> Result<(), Box> { let mut contents = String::new(); file.read_to_string(&mut contents) .expect("Unable to read file"); - let yaml: Value = serde_yaml::from_str(&contents).expect("Failed parsing yaml from config file"); - let apikey = yaml["apikey"].as_str().expect("unable to get api key from config file"); + let yaml: Value = + serde_yaml::from_str(&contents).expect("Failed parsing yaml from config file"); + let apikey = yaml["apikey"] + .as_str() + .expect("unable to get api key from config file"); if apikey == "your-api-key" || apikey == "" { panic!("Please set your API key in the config.yaml file"); } - let query = "window_events = query_bucket(find_bucket(\"aw-watcher-window_\")); - RETURN = window_events;"; + + let query = " + events = flood(query_bucket(find_bucket(\"aw-watcher-window_\"))); + not_afk = flood(query_bucket(find_bucket(\"aw-watcher-afk_\"))); + not_afk = filter_keyvals(not_afk, \"status\", [\"not-afk\"]); + events = filter_period_intersect(events, not_afk); + events = categorize(events, [[[\"Work\"], {\"type\": \"regex\", \"regex\": \"aw|ActivityWatch\", \"ignore_case\": true}]]); + events = filter_keyvals(events, \"$category\", [[\"Work\"]]); + RETURN = events; + "; let timeperiods = vec![(start, end)]; // TODO: handle errors - let res = aw_client.query(&query, timeperiods).await.unwrap(); + let res = aw_client.query(&query, timeperiods).await.expect("Failed to query data"); let res_string = serde_json::to_string(&res).unwrap(); // strip the leading and trailing '[' and ']' From 1a3f1022b2b32b7856b127c22f66ac6c7ea79dc8 Mon Sep 17 00:00:00 2001 From: brayo Date: Wed, 19 Jun 2024 12:39:45 +0300 Subject: [PATCH 14/20] feat: minor functionality tweak --- aw-firebase-sync/src/main.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/aw-firebase-sync/src/main.rs b/aw-firebase-sync/src/main.rs index 31580bfe..ea0c4347 100644 --- a/aw-firebase-sync/src/main.rs +++ b/aw-firebase-sync/src/main.rs @@ -59,12 +59,9 @@ async fn main() -> Result<(), Box> { let timeperiods = vec![(start, end)]; - // TODO: handle errors let res = aw_client.query(&query, timeperiods).await.expect("Failed to query data"); - let res_string = serde_json::to_string(&res).unwrap(); - // strip the leading and trailing '[' and ']' - let res_string = &res_string[1..res_string.len() - 1]; + let res_string = serde_json::to_string(&res[0]).unwrap(); let firebase_url = "https://us-central1-aw-mockup.cloudfunctions.net/uploadData"; // let firebase_url = "http://localhost:5001/aw-mockup/us-central1/uploadData"; From b415a74b55a6886a1a9fd294d4b942d9b6ad7ec0 Mon Sep 17 00:00:00 2001 From: brayo Date: Wed, 19 Jun 2024 17:05:35 +0300 Subject: [PATCH 15/20] feat: parse cli arguments --- aw-firebase-sync/src/main.rs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/aw-firebase-sync/src/main.rs b/aw-firebase-sync/src/main.rs index ea0c4347..5eb4c2bd 100644 --- a/aw-firebase-sync/src/main.rs +++ b/aw-firebase-sync/src/main.rs @@ -6,10 +6,30 @@ use serde_json::{json, Value}; use serde_yaml; use std::fs::{DirBuilder, File}; use std::io::prelude::*; +use std::env; #[tokio::main] async fn main() -> Result<(), Box> { - let aw_client = AwClient::new("localhost", 5600, "aw-firebase-sync").unwrap(); + + let args: Vec = env::args().collect(); + let mut port: u16 = 5600; + if args.len() > 1 { + for idx in 1..args.len() { + if args[idx] == "--port" { + port = args[idx + 1].parse().expect("Invalid port number"); + break; + } + if args[idx] == "--testing" { + port = 5699; + } + if args[idx] == "--help" { + println!("Usage: aw-firebase-sync [--testing] [--port PORT] [--help]"); + return Ok(()); + } + } + } + let aw_client = AwClient::new("localhost", port, "aw-firebase-sync").unwrap(); + let start = Utc::now().date().and_hms_opt(0, 0, 0).unwrap() - chrono::Duration::days(6); let end = Utc::now().date().and_hms_opt(0, 0, 0).unwrap() + chrono::Duration::days(1); @@ -59,16 +79,16 @@ async fn main() -> Result<(), Box> { let timeperiods = vec![(start, end)]; - let res = aw_client.query(&query, timeperiods).await.expect("Failed to query data"); + let query_result = aw_client.query(&query, timeperiods).await.expect("Failed to query data"); - let res_string = serde_json::to_string(&res[0]).unwrap(); + let query_data = serde_json::to_string(&query_result[0]).unwrap(); let firebase_url = "https://us-central1-aw-mockup.cloudfunctions.net/uploadData"; // let firebase_url = "http://localhost:5001/aw-mockup/us-central1/uploadData"; let payload = json!({ "apiKey": apikey, - "data": res_string + "data": query_data }); let firebase_client = reqwest::Client::new(); From 68cdf20f04205b894df032c3b9487ac03155c032 Mon Sep 17 00:00:00 2001 From: brayo Date: Tue, 25 Jun 2024 13:55:42 +0300 Subject: [PATCH 16/20] chore: update cargo lock --- Cargo.lock | 367 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 345 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3d215c8c..b44023ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -190,6 +190,12 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.1.0" @@ -205,7 +211,7 @@ dependencies = [ "aw-server", "chrono", "gethostname", - "reqwest", + "reqwest 0.11.22", "rocket", "serde", "serde_json", @@ -235,7 +241,8 @@ dependencies = [ "aw-client-rust", "aw-models", "chrono", - "reqwest", + "dirs 5.0.1", + "reqwest 0.12.5", "serde", "serde_json", "serde_yaml", @@ -314,7 +321,7 @@ dependencies = [ "dirs 5.0.1", "gethostname", "log", - "reqwest", + "reqwest 0.11.22", "serde", "serde_json", "toml", @@ -355,6 +362,12 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "binascii" version = "0.1.4" @@ -1072,7 +1085,26 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.11", + "indexmap 2.1.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", "indexmap 2.1.0", "slab", "tokio", @@ -1134,6 +1166,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.5" @@ -1141,7 +1184,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", - "http", + "http 0.2.11", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -1167,9 +1233,9 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.22", + "http 0.2.11", + "http-body 0.4.5", "httparse", "httpdate", "itoa", @@ -1181,6 +1247,43 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.3.1", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -1188,10 +1291,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.27", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.3.1", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.3.1", + "pin-project-lite", + "socket2 0.5.5", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -1512,7 +1651,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http", + "http 0.2.11", "httparse", "log", "memchr", @@ -1737,6 +1876,26 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1995,16 +2154,16 @@ version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64", + "base64 0.21.5", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", + "h2 0.3.22", + "http 0.2.11", + "http-body 0.4.5", + "hyper 0.14.27", + "hyper-tls 0.5.0", "ipnet", "js-sys", "log", @@ -2024,7 +2183,65 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg", + "winreg 0.50.0", +] + +[[package]] +name = "reqwest" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.3.1", + "hyper-rustls", + "hyper-tls 0.6.0", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.52.0", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if 1.0.0", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", ] [[package]] @@ -2088,7 +2305,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfac3a1df83f8d4fc96aa41dba3b86c786417b7fc0f52ec76295df2ba781aa69" dependencies = [ - "http", + "http 0.2.11", "log", "regex", "rocket", @@ -2108,8 +2325,8 @@ dependencies = [ "cookie", "either", "futures", - "http", - "hyper", + "http 0.2.11", + "hyper 0.14.27", "indexmap 2.1.0", "log", "memchr", @@ -2196,6 +2413,46 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.23.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + +[[package]] +name = "rustls-webpki" +version = "0.102.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -2426,9 +2683,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" @@ -2480,6 +2737,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "subtle" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d0208408ba0c3df17ed26eb06992cb1a1268d41b2c0e12e65203fbe3972cee5" + [[package]] name = "syn" version = "1.0.109" @@ -2502,6 +2765,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + [[package]] name = "system-configuration" version = "0.5.1" @@ -2660,6 +2929,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.14" @@ -2732,6 +3012,27 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -2885,6 +3186,12 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.0" @@ -3249,6 +3556,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if 1.0.0", + "windows-sys 0.48.0", +] + [[package]] name = "yaml-rust" version = "0.4.5" @@ -3286,3 +3603,9 @@ dependencies = [ "quote", "syn 2.0.39", ] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" From ed85145490d23b4301350c5db7179e168190ec6b Mon Sep 17 00:00:00 2001 From: brayo Date: Wed, 26 Jun 2024 11:14:36 +0300 Subject: [PATCH 17/20] feat: run every 5 mins --- aw-firebase-sync/src/main.rs | 59 ++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/aw-firebase-sync/src/main.rs b/aw-firebase-sync/src/main.rs index 5eb4c2bd..09a9922b 100644 --- a/aw-firebase-sync/src/main.rs +++ b/aw-firebase-sync/src/main.rs @@ -4,13 +4,15 @@ use dirs::config_dir; use reqwest; use serde_json::{json, Value}; use serde_yaml; +use std::env; use std::fs::{DirBuilder, File}; use std::io::prelude::*; -use std::env; +use tracing::info; +use tracing_subscriber; #[tokio::main] async fn main() -> Result<(), Box> { - + tracing_subscriber::fmt::init(); let args: Vec = env::args().collect(); let mut port: u16 = 5600; if args.len() > 1 { @@ -30,9 +32,6 @@ async fn main() -> Result<(), Box> { } let aw_client = AwClient::new("localhost", port, "aw-firebase-sync").unwrap(); - let start = Utc::now().date().and_hms_opt(0, 0, 0).unwrap() - chrono::Duration::days(6); - let end = Utc::now().date().and_hms_opt(0, 0, 0).unwrap() + chrono::Duration::days(1); - let path = config_dir() .map(|mut path| { path.push("activitywatch"); @@ -77,30 +76,38 @@ async fn main() -> Result<(), Box> { RETURN = events; "; - let timeperiods = vec![(start, end)]; - - let query_result = aw_client.query(&query, timeperiods).await.expect("Failed to query data"); - - let query_data = serde_json::to_string(&query_result[0]).unwrap(); - let firebase_url = "https://us-central1-aw-mockup.cloudfunctions.net/uploadData"; // let firebase_url = "http://localhost:5001/aw-mockup/us-central1/uploadData"; - let payload = json!({ - "apiKey": apikey, - "data": query_data - }); - let firebase_client = reqwest::Client::new(); - let response = firebase_client - .post(firebase_url) - .json(&payload) - .send() - .await? - .json::() - .await?; - println!("Response: {:?}", response); - - Ok(()) + loop { + #[allow(deprecated)] + let start = + Utc::now().date().and_hms_opt(0, 0, 0).unwrap() - chrono::Duration::seconds(300); + #[allow(deprecated)] + let end = Utc::now().date().and_hms_opt(0, 0, 0).unwrap(); + let timeperiods = vec![(start, end)]; + + let query_result = aw_client + .query(&query, timeperiods) + .await + .expect("Failed to query data"); + let query_data = + serde_json::to_string(&query_result[0]).expect("Failed to serialize query data"); + let payload = json!({ + "apiKey": apikey, + "data": query_data + }); + let response = firebase_client + .post(firebase_url) + .json(&payload) + .send() + .await? + .json::() + .await?; + info!("Response: {:?}", response); + std::thread::sleep(std::time::Duration::from_secs(300)); + } + // Ok(()) } From b973c4b6c3b6847b4fa96227190a56dd7d9cc853 Mon Sep 17 00:00:00 2001 From: brayo Date: Wed, 26 Jun 2024 11:14:54 +0300 Subject: [PATCH 18/20] feat: add tracing support --- Cargo.lock | 2 ++ aw-firebase-sync/Cargo.toml | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index b44023ad..49d83dbd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -247,6 +247,8 @@ dependencies = [ "serde_json", "serde_yaml", "tokio", + "tracing", + "tracing-subscriber", ] [[package]] diff --git a/aw-firebase-sync/Cargo.toml b/aw-firebase-sync/Cargo.toml index fa4c36e3..32efd56d 100644 --- a/aw-firebase-sync/Cargo.toml +++ b/aw-firebase-sync/Cargo.toml @@ -14,4 +14,6 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.70" serde_yaml = "0.8.18" reqwest = { version = "0.12.4" , features = ["json"] } -dirs = "5.0.1" \ No newline at end of file +dirs = "5.0.1" +tracing = "0.1.26" +tracing-subscriber = "0.3.18" \ No newline at end of file From 0f51a9f9f70fc13a8b1f91943f727ed4aedd3749 Mon Sep 17 00:00:00 2001 From: Brayo Date: Wed, 17 Jul 2024 16:16:07 +0300 Subject: [PATCH 19/20] chore: conditionally set the firebase url used from a test flag --- aw-firebase-sync/src/main.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/aw-firebase-sync/src/main.rs b/aw-firebase-sync/src/main.rs index 09a9922b..f3321793 100644 --- a/aw-firebase-sync/src/main.rs +++ b/aw-firebase-sync/src/main.rs @@ -15,6 +15,7 @@ async fn main() -> Result<(), Box> { tracing_subscriber::fmt::init(); let args: Vec = env::args().collect(); let mut port: u16 = 5600; + let mut testing = false; if args.len() > 1 { for idx in 1..args.len() { if args[idx] == "--port" { @@ -22,7 +23,7 @@ async fn main() -> Result<(), Box> { break; } if args[idx] == "--testing" { - port = 5699; + testing = true; } if args[idx] == "--help" { println!("Usage: aw-firebase-sync [--testing] [--port PORT] [--help]"); @@ -76,8 +77,11 @@ async fn main() -> Result<(), Box> { RETURN = events; "; - let firebase_url = "https://us-central1-aw-mockup.cloudfunctions.net/uploadData"; - // let firebase_url = "http://localhost:5001/aw-mockup/us-central1/uploadData"; + let firebase_url = if testing { + "http://localhost:5001/aw-mockup/us-central1/uploadData" + } else { + "https://us-central1-aw-mockup.cloudfunctions.net/uploadData" + }; let firebase_client = reqwest::Client::new(); From 04a32721348380cef9d6f5e023e139b4664bcabd Mon Sep 17 00:00:00 2001 From: Brayo Date: Wed, 17 Jul 2024 16:23:16 +0300 Subject: [PATCH 20/20] feat: Update time calculation to use local timezone --- aw-firebase-sync/src/main.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/aw-firebase-sync/src/main.rs b/aw-firebase-sync/src/main.rs index f3321793..7a6299fd 100644 --- a/aw-firebase-sync/src/main.rs +++ b/aw-firebase-sync/src/main.rs @@ -1,5 +1,5 @@ use aw_client_rust::AwClient; -use chrono::Utc; +use chrono::Local; use dirs::config_dir; use reqwest; use serde_json::{json, Value}; @@ -86,11 +86,8 @@ async fn main() -> Result<(), Box> { let firebase_client = reqwest::Client::new(); loop { - #[allow(deprecated)] - let start = - Utc::now().date().and_hms_opt(0, 0, 0).unwrap() - chrono::Duration::seconds(300); - #[allow(deprecated)] - let end = Utc::now().date().and_hms_opt(0, 0, 0).unwrap(); + let start = Local::now().to_utc() - chrono::Duration::minutes(5); + let end = Local::now().to_utc(); let timeperiods = vec![(start, end)]; let query_result = aw_client