diff --git a/Cargo.lock b/Cargo.lock index f61fa66..1935bc0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2807,7 +2807,7 @@ dependencies = [ "tracing-subscriber 0.3.17", "utoipa", "utoipa-swagger-ui", - "uuid 1.3.3", + "uuid 1.4.1", ] [[package]] @@ -2817,9 +2817,12 @@ dependencies = [ "chrono", "filenamify", "lazy_static", + "reqwest", "serde", "serde-jsonlines", "serdeconv", + "tokio", + "uuid 1.4.1", ] [[package]] @@ -2916,7 +2919,7 @@ dependencies = [ "tempfile", "thiserror", "time 0.3.21", - "uuid 1.3.3", + "uuid 1.4.1", "winapi", ] @@ -3706,9 +3709,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.3.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "getrandom", "rand", @@ -3718,9 +3721,9 @@ dependencies = [ [[package]] name = "uuid-macro-internal" -version = "1.3.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f67b459f42af2e6e1ee213cb9da4dbd022d3320788c3fb3e1b893093f1e45da" +checksum = "f7e1ba1f333bd65ce3c9f27de592fcbc256dafe3af2717f56d7c87761fbaccf4" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index b1ff613..f9d681a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,3 +27,4 @@ anyhow = "1.0.71" serde-jsonlines = "0.4.0" tantivy = "0.19.2" async-trait = "0.1.72" +reqwest = { version = "0.11.18" } diff --git a/crates/tabby-common/Cargo.toml b/crates/tabby-common/Cargo.toml index 77e217b..f75c431 100644 --- a/crates/tabby-common/Cargo.toml +++ b/crates/tabby-common/Cargo.toml @@ -10,6 +10,9 @@ lazy_static = { workspace = true } serde = { workspace = true } serdeconv = { workspace = true } serde-jsonlines = { workspace = true } +reqwest = { workspace = true, features = [ "json" ] } +tokio = { workspace = true, features = ["rt", "macros"] } +uuid = { version = "1.4.1", features = ["v4"] } [features] testutils = [] diff --git a/crates/tabby-common/src/lib.rs b/crates/tabby-common/src/lib.rs index 60362c7..44483f2 100644 --- a/crates/tabby-common/src/lib.rs +++ b/crates/tabby-common/src/lib.rs @@ -1,6 +1,7 @@ pub mod config; pub mod events; pub mod path; +pub mod usage; use std::{ fs::File, diff --git a/crates/tabby-common/src/path.rs b/crates/tabby-common/src/path.rs index c6e2fec..0a5d094 100644 --- a/crates/tabby-common/src/path.rs +++ b/crates/tabby-common/src/path.rs @@ -27,6 +27,10 @@ pub fn config_file() -> PathBuf { tabby_root().join("config.toml") } +pub fn usage_id_file() -> PathBuf { + tabby_root().join("usage_anonymous_id") +} + pub fn repositories_dir() -> PathBuf { tabby_root().join("repositories") } diff --git a/crates/tabby-common/src/usage.rs b/crates/tabby-common/src/usage.rs new file mode 100644 index 0000000..ab74b03 --- /dev/null +++ b/crates/tabby-common/src/usage.rs @@ -0,0 +1,66 @@ +use std::{ + collections::HashMap, + fs::{self}, +}; + +use lazy_static::lazy_static; +use reqwest::Client; +use uuid::Uuid; + +use crate::path::usage_id_file; + +static USAGE_API_ENDPOINT: &str = "https://app.tabbyml.com/api/usage"; + +struct UsageTracker { + id: String, + client: Option, +} + +impl UsageTracker { + fn new() -> Self { + if fs::metadata(usage_id_file()).is_err() { + // usage id file doesn't exists. + let id = Uuid::new_v4().to_string(); + std::fs::write(usage_id_file(), id).expect("Failed to create usage id"); + } + + let id = fs::read_to_string(usage_id_file()).expect("Failed to read usage id"); + let client = if std::env::var("TABBY_DISABLE_USAGE_COLLECTION").is_ok() { + None + } else { + Some(Client::new()) + }; + + Self { id, client } + } + + async fn capture(&self, event: &str) { + if let Some(client) = &self.client { + let params = HashMap::from([("distinctId", self.id.as_ref()), ("event", event)]); + client + .post(USAGE_API_ENDPOINT) + .json(¶ms) + .send() + .await + .ok(); + } + } +} + +lazy_static! { + static ref TRACKER: UsageTracker = UsageTracker::new(); +} + +pub async fn capture(event: &str) { + TRACKER.capture(event).await +} + +#[cfg(test)] +mod tests { + use super::capture; + + #[tokio::test] + async fn it_fire_event() { + capture("UsageTest").await + } +} diff --git a/crates/tabby-download/Cargo.toml b/crates/tabby-download/Cargo.toml index c2132f0..94a6412 100644 --- a/crates/tabby-download/Cargo.toml +++ b/crates/tabby-download/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" tabby-common = { path = "../tabby-common" } indicatif = "0.17.3" futures-util = "0.3.28" -reqwest = { version = "0.11.18", features = ["stream", "json"] } +reqwest = { workspace = true, features = [ "stream", "json" ] } anyhow = { workspace = true } serde = { workspace = true } serdeconv = { workspace = true }