diff --git a/rust/src/cli/account.rs b/rust/src/cli/account.rs index 91f88f3461..3cb2dfba60 100644 --- a/rust/src/cli/account.rs +++ b/rust/src/cli/account.rs @@ -25,6 +25,10 @@ pub enum AccountSubcommands { #[arg(long, default_value = "photos")] app: String, + /// API endpoint (defaults to https://api.ente.io) + #[arg(long, default_value = "https://api.ente.io")] + endpoint: String, + /// Export directory path #[arg(long)] export_dir: Option, diff --git a/rust/src/commands/account.rs b/rust/src/commands/account.rs index 08c531e678..234b2146e7 100644 --- a/rust/src/commands/account.rs +++ b/rust/src/commands/account.rs @@ -18,8 +18,9 @@ pub async fn handle_account_command(cmd: AccountCommand, storage: &Storage) -> R email, password, app, + endpoint, export_dir, - } => add_account(storage, email, password, app, export_dir).await, + } => add_account(storage, email, password, app, endpoint, export_dir).await, AccountSubcommands::Update { email, dir, app } => { update_account(storage, &email, &dir, &app).await } @@ -36,14 +37,24 @@ async fn list_accounts(storage: &Storage) -> Result<()> { } println!("\nConfigured accounts:\n"); - println!("{:<30} {:<10} {:<40}", "Email", "App", "Export Directory"); - println!("{}", "-".repeat(80)); + println!("{:<30} {:<10} {:<30} {:<40}", "Email", "App", "Endpoint", "Export Directory"); + println!("{}", "-".repeat(110)); for account in accounts { + // Shorten endpoint display for better readability + let endpoint_display = if account.endpoint == "https://api.ente.io" { + "api.ente.io (prod)".to_string() + } else if account.endpoint.starts_with("http://localhost") { + format!("localhost:{}", account.endpoint.split(':').last().unwrap_or("")) + } else { + account.endpoint.clone() + }; + println!( - "{:<30} {:<10} {:<40}", + "{:<30} {:<10} {:<30} {:<40}", account.email, format!("{:?}", account.app).to_lowercase(), + endpoint_display, account.export_dir.as_deref().unwrap_or("Not configured") ); } @@ -56,6 +67,7 @@ async fn add_account( email_arg: Option, password_arg: Option, app_arg: String, + endpoint: String, export_dir_arg: Option, ) -> Result<()> { println!("\n=== Add Ente Account ===\n"); @@ -132,12 +144,9 @@ async fn add_account( std::fs::create_dir_all(&export_path).map_err(crate::models::error::Error::Io)?; } - // Initialize API client (use ENTE_ENDPOINT env var if set, otherwise default to production) - let api_endpoint = std::env::var("ENTE_ENDPOINT").ok(); - if let Some(ref endpoint) = api_endpoint { - log::debug!("Using custom API endpoint: {endpoint}"); - } - let api_client = ApiClient::new(api_endpoint)?; + // Initialize API client with the specified endpoint + log::info!("Using API endpoint: {}", endpoint); + let api_client = ApiClient::new(Some(endpoint.clone()))?; let auth_client = AuthClient::new(&api_client); println!("\nAuthenticating with Ente servers..."); @@ -231,6 +240,7 @@ async fn add_account( email: email.clone(), user_id: auth_response.id, app, + endpoint: endpoint.clone(), export_dir: Some(export_dir.clone()), }; @@ -249,6 +259,7 @@ async fn add_account( println!("\n✅ Account added successfully!"); println!(" Email: {email}"); println!(" App: {app:?}"); + println!(" Endpoint: {endpoint}"); println!(" Export directory: {export_dir}"); Ok(()) diff --git a/rust/src/models/account.rs b/rust/src/models/account.rs index 667b1585db..8740af7c38 100644 --- a/rust/src/models/account.rs +++ b/rust/src/models/account.rs @@ -10,6 +10,7 @@ pub struct Account { pub email: String, pub user_id: i64, pub app: App, + pub endpoint: String, pub export_dir: Option, } diff --git a/rust/src/storage/account.rs b/rust/src/storage/account.rs index 8bd14366c9..71d9144daf 100644 --- a/rust/src/storage/account.rs +++ b/rust/src/storage/account.rs @@ -21,12 +21,13 @@ impl<'a> AccountStore<'a> { let now = current_timestamp(); self.conn.execute( - "INSERT INTO accounts (email, user_id, app, export_dir, created_at, updated_at) - VALUES (?1, ?2, ?3, ?4, ?5, ?6)", + "INSERT INTO accounts (email, user_id, app, endpoint, export_dir, created_at, updated_at) + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)", params![ account.email, account.user_id, format!("{:?}", account.app).to_lowercase(), + account.endpoint, account.export_dir, now, now @@ -39,7 +40,7 @@ impl<'a> AccountStore<'a> { /// Get an account by email and app pub fn get(&self, email: &str, app: App) -> Result> { let mut stmt = self.conn.prepare( - "SELECT id, email, user_id, app, export_dir FROM accounts + "SELECT id, email, user_id, app, endpoint, export_dir FROM accounts WHERE email = ?1 AND app = ?2", )?; @@ -55,7 +56,7 @@ impl<'a> AccountStore<'a> { /// List all accounts pub fn list(&self) -> Result> { let mut stmt = self.conn.prepare( - "SELECT id, email, user_id, app, export_dir FROM accounts + "SELECT id, email, user_id, app, endpoint, export_dir FROM accounts ORDER BY email, app", )?; @@ -143,7 +144,8 @@ fn row_to_account(row: &Row) -> rusqlite::Result { email: row.get(1)?, user_id: row.get(2)?, app, - export_dir: row.get(4)?, + endpoint: row.get(4)?, + export_dir: row.get(5)?, }) } diff --git a/rust/src/storage/schema.rs b/rust/src/storage/schema.rs index a5079515c4..2e75b41e96 100644 --- a/rust/src/storage/schema.rs +++ b/rust/src/storage/schema.rs @@ -10,10 +10,11 @@ pub fn create_tables(conn: &Connection) -> Result<()> { email TEXT NOT NULL, user_id INTEGER NOT NULL, app TEXT NOT NULL, + endpoint TEXT NOT NULL DEFAULT 'https://api.ente.io', export_dir TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, - UNIQUE(email, app) + UNIQUE(email, app, endpoint) )", [], )?;