diff --git a/Dockerfile b/Dockerfile index 937537728..5a9a4691f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,6 @@ LABEL org.opencontainers.image.source="https://github.com/meilisearch/meilisea ENV MEILI_HTTP_ADDR 0.0.0.0:7700 ENV MEILI_SERVER_PROVIDER docker -ENV MEILI_CONTACT_EMAIL "" RUN apk add -q --no-cache libgcc tini curl diff --git a/crates/meilisearch/src/analytics/mod.rs b/crates/meilisearch/src/analytics/mod.rs index cd5641375..bd14b0bfa 100644 --- a/crates/meilisearch/src/analytics/mod.rs +++ b/crates/meilisearch/src/analytics/mod.rs @@ -45,7 +45,7 @@ macro_rules! empty_analytics { /// `~/.config/Meilisearch` on *NIX or *BSD. /// `~/Library/ApplicationSupport` on macOS. /// `%APPDATA` (= `C:\Users%USERNAME%\AppData\Roaming`) on windows. -pub static MEILISEARCH_CONFIG_PATH: Lazy> = +static MEILISEARCH_CONFIG_PATH: Lazy> = Lazy::new(|| AppDirs::new(Some("Meilisearch"), false).map(|appdir| appdir.config_dir)); fn config_user_id_path(db_path: &Path) -> Option { diff --git a/crates/meilisearch/src/analytics/segment_analytics.rs b/crates/meilisearch/src/analytics/segment_analytics.rs index 2c0121ffc..ee8a9ee20 100644 --- a/crates/meilisearch/src/analytics/segment_analytics.rs +++ b/crates/meilisearch/src/analytics/segment_analytics.rs @@ -277,7 +277,6 @@ impl Infos { log_level, indexer_options, config_file_path, - contact_email: _, no_analytics: _, } = options; diff --git a/crates/meilisearch/src/main.rs b/crates/meilisearch/src/main.rs index 13f76732a..b16dda097 100644 --- a/crates/meilisearch/src/main.rs +++ b/crates/meilisearch/src/main.rs @@ -12,7 +12,7 @@ use actix_web::web::Data; use actix_web::HttpServer; use index_scheduler::IndexScheduler; use is_terminal::IsTerminal; -use meilisearch::analytics::{Analytics, MEILISEARCH_CONFIG_PATH}; +use meilisearch::analytics::Analytics; use meilisearch::option::LogMode; use meilisearch::search_queue::SearchQueue; use meilisearch::{ @@ -20,18 +20,11 @@ use meilisearch::{ LogStderrType, Opt, SubscriberForSecondLayer, }; use meilisearch_auth::{generate_master_key, AuthController, MASTER_KEY_MIN_SIZE}; -use meilisearch_types::versioning::{VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH}; -use serde_json::json; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; -use tokio::io::{AsyncBufReadExt, BufReader}; use tracing::level_filters::LevelFilter; use tracing_subscriber::layer::SubscriberExt as _; use tracing_subscriber::Layer; -const SKIP_EMAIL_FILENAME: &str = "skip-email"; -const PORTAL_ID: &str = "25945010"; -const FORM_GUID: &str = "991e2a09-77c2-4428-9242-ebf26bfc6c64"; - #[cfg(not(windows))] #[global_allocator] static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; @@ -96,7 +89,7 @@ async fn main() -> anyhow::Result<()> { } async fn try_main() -> anyhow::Result<()> { - let (mut opt, config_read_from) = Opt::try_build()?; + let (opt, config_read_from) = Opt::try_build()?; std::panic::set_hook(Box::new(on_panic)); @@ -131,38 +124,6 @@ async fn try_main() -> anyhow::Result<()> { let (index_scheduler, auth_controller) = setup_meilisearch(&opt)?; - // We ask users their emails just after the data.ms is created - let skip_email_path = - MEILISEARCH_CONFIG_PATH.as_ref().map(|conf| conf.join(SKIP_EMAIL_FILENAME)); - // If the config path does not exist, it means the user don't have a home directory - let skip_email = skip_email_path.as_ref().is_none_or(|path| path.exists()); - opt.contact_email = match opt.contact_email.as_ref().map(|email| email.as_deref()) { - Some(Some("false")) | None if !skip_email => prompt_for_contact_email().await.map(Some)?, - Some(Some(email)) if !skip_email => Some(Some(email.to_string())), - _otherwise => None, - }; - - if let Some(Some(email)) = opt.contact_email.as_ref() { - let email = email.clone(); - // We spawn a task to register the email and create the skip email - // file to avoid blocking the Meilisearch launch further. - let handle = tokio::spawn(async move { - if let Some(skip_email_path) = skip_email_path { - // If the analytics are disabled the directory might not exist at all - if let Err(e) = tokio::fs::create_dir_all(skip_email_path.parent().unwrap()).await { - eprintln!("Failed to create skip email file: {e}"); - } - if let Err(e) = tokio::fs::File::create_new(skip_email_path).await { - eprintln!("Failed to create skip email file: {e}"); - } - } - if let Err(err) = register_contact_email(&email).await { - eprintln!("Failed to register email: {}", err); - } - }); - drop(handle); - } - let analytics = analytics::Analytics::new(&opt, index_scheduler.clone(), auth_controller.clone()).await; @@ -178,76 +139,6 @@ async fn try_main() -> anyhow::Result<()> { Ok(()) } -/// Prompt the user about the contact email for support and news. -/// It only displays the prompt if the input is an interactive terminal. -async fn prompt_for_contact_email() -> anyhow::Result> { - let stdin = tokio::io::stdin(); - - if !stdin.is_terminal() { - return Ok(None); - } - - println!("Get monthly updates about new features and tips to get the most out of Meilisearch."); - println!("Use the --contact-email option to disable this prompt."); - print!("Enter your email or leave blank to skip> "); - std::io::stdout().flush()?; - - let mut email = String::new(); - let mut stdin = BufReader::new(stdin); - let _ = stdin.read_line(&mut email).await?; - let email = email.trim(); - - if email.is_empty() { - Ok(None) - } else { - Ok(Some(email.to_string())) - } -} - -async fn register_contact_email(email: &str) -> anyhow::Result<()> { - let url = format!( - "https://api.hsforms.com/submissions/v3/integration/submit/{PORTAL_ID}/{FORM_GUID}" - ); - - let page_name = format!( - "Meilisearch terminal prompt v{}.{}.{}", - VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH - ); - let response = reqwest::Client::new() - .post(url) - .json(&json!({ - "fields": [{ - "objectTypeId": "0-1", - "name": "email", - "value": email, - }], - "context": { - "pageName": page_name, - }, - "legalConsentOptions": { - "consent": { - "consentToProcess": true, - "text": "I agree to allow Meilisearch to store and process my personal data.", - "communications": [{ - "value": true, - "subscriptionTypeId": 999, - "text": "I agree to receive marketing communications from Meilisearch.", - }], - }, - }, - })) - .send() - .await?; - - let status = response.status(); - if status.is_client_error() || status.is_server_error() { - let response: serde_json::Value = response.json().await?; - eprintln!("Failed to register email: {response:?}"); - } - - Ok(()) -} - async fn run_http( index_scheduler: Arc, auth_controller: Arc, diff --git a/crates/meilisearch/src/option.rs b/crates/meilisearch/src/option.rs index 2a5de7011..6e06b161d 100644 --- a/crates/meilisearch/src/option.rs +++ b/crates/meilisearch/src/option.rs @@ -66,7 +66,6 @@ const MEILI_EXPERIMENTAL_LIMIT_BATCHED_TASKS_TOTAL_SIZE: &str = const MEILI_EXPERIMENTAL_EMBEDDING_CACHE_ENTRIES: &str = "MEILI_EXPERIMENTAL_EMBEDDING_CACHE_ENTRIES"; const MEILI_EXPERIMENTAL_NO_SNAPSHOT_COMPACTION: &str = "MEILI_EXPERIMENTAL_NO_SNAPSHOT_COMPACTION"; -const MEILI_CONTACT_EMAIL: &str = "MEILI_CONTACT_EMAIL"; const DEFAULT_CONFIG_FILE_PATH: &str = "./config.toml"; const DEFAULT_DB_PATH: &str = "./data.ms"; const DEFAULT_HTTP_ADDR: &str = "localhost:7700"; @@ -348,13 +347,6 @@ pub struct Opt { #[serde(default)] pub log_level: LogLevel, - /// Sets the email address to contact for support and news. - /// - /// Use this option to disable contact email prompting. Leave - /// blank or without value to disable contact email prompting. - #[clap(long, env = MEILI_CONTACT_EMAIL)] - pub contact_email: Option>, - /// Experimental contains filter feature. For more information, /// see: /// @@ -564,7 +556,6 @@ impl Opt { ignore_dump_if_db_exists: _, config_file_path: _, no_analytics, - contact_email, experimental_contains_filter, experimental_enable_metrics, experimental_search_queue_size, @@ -597,10 +588,6 @@ impl Opt { } export_to_env_if_not_present(MEILI_NO_ANALYTICS, no_analytics.to_string()); - export_to_env_if_not_present( - MEILI_CONTACT_EMAIL, - contact_email.flatten().unwrap_or_else(|| "false".to_string()), - ); export_to_env_if_not_present( MEILI_HTTP_PAYLOAD_SIZE_LIMIT, http_payload_size_limit.to_string(),