diff --git a/README.md b/README.md index 016d0b0..7e388bd 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ homeserver_url: https://matrix.org username: "headjack" password: "" # Optional, if not given it will ask for it on first run allow_list: "" # Regex for allowed accounts. +state_dir: "$XDG_STATE_HOME/headjack" # Optional, for setting the headjack state directory aichat_config_dir: "$AICHAT_CONFIG_DIR" # Optional, for using a separate aichat config chat_summary_model: "" # Optional, set a different model than the default to use for summarizing the chat ``` diff --git a/src/main.rs b/src/main.rs index 40625d3..ee9eba1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -78,6 +78,9 @@ struct Config { password: Option, /// Allow list of which accounts we will respond to allow_list: Option, + /// Set the state directory for headjack + /// Defaults to $XDG_STATE_HOME/headjack + state_dir: Option, /// Set the config directory for aichat /// Allows for multiple instances setups of aichat aichat_config_dir: Option, @@ -106,18 +109,23 @@ async fn main() -> anyhow::Result<()> { *GLOBAL_CONFIG.lock().unwrap() = Some(config.clone()); // The folder containing the persisted data. - let data_dir = dirs::data_dir() - .expect("no data_dir directory found") - .join("headjack"); + let state_dir = if let Some(state_dir) = &config.state_dir { + PathBuf::from(state_dir) + } else { + dirs::state_dir() + .expect("no state_dir directory found") + .join("headjack") + }; + // The file where the session is persisted. - let session_file = data_dir.join("session"); + let session_file = state_dir.join("session"); let (client, sync_token) = if session_file.exists() { restore_session(&session_file).await? } else { ( login( - &data_dir, + &state_dir, &session_file, config.homeserver_url, &config.username, @@ -147,7 +155,7 @@ fn is_allowed(sender: &str) -> bool { /// Login with a new device. async fn login( - data_dir: &Path, + state_dir: &Path, session_file: &Path, homeserver_url: String, username: &str, @@ -155,7 +163,7 @@ async fn login( ) -> anyhow::Result { eprintln!("No previous session found, logging in…"); - let (client, client_session) = build_client(data_dir, homeserver_url).await?; + let (client, client_session) = build_client(state_dir, homeserver_url).await?; let matrix_auth = client.matrix_auth(); // If there's no password, ask for it @@ -204,7 +212,7 @@ async fn login( /// Build a new client. async fn build_client( - data_dir: &Path, + state_dir: &Path, homeserver: String, ) -> anyhow::Result<(Client, ClientSession)> { let mut rng = thread_rng(); @@ -215,7 +223,7 @@ async fn build_client( .take(7) .map(char::from) .collect(); - let db_path = data_dir.join(db_subfolder); + let db_path = state_dir.join(db_subfolder); // Generate a random passphrase. // It will be saved in the session file and used to encrypt the database.