diff --git a/Cargo.toml b/Cargo.toml index 03c9e2d..7adb975 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,6 @@ path = "src/alias.rs" seahorse = "*" reqwest = { version = "*", features = ["blocking", "json"] } tokio = { version = "1", features = ["full"] } -shellexpand = "*" config = "*" serde = "*" serde_json = "*" diff --git a/src/data.rs b/src/data.rs index 2a761a9..0a49911 100644 --- a/src/data.rs +++ b/src/data.rs @@ -5,94 +5,51 @@ use std::fs; use std::fs::OpenOptions; use std::io::Read; use std::io::Write; -use std::path::Path; +use std::path::{Path, PathBuf}; +use std::env; + +/// ホームディレクトリパスを展開するユーティリティ関数 +/// "~"で始まるパスをユーザーのホームディレクトリに展開します +fn expand_home_path(path: &str) -> PathBuf { + if path.starts_with("~") { + let home = env::var("HOME").unwrap_or_else(|_| ".".to_string()); + let path_without_tilde = path.strip_prefix("~/").unwrap_or(&path[1..]); + PathBuf::from(home).join(path_without_tilde) + } else { + PathBuf::from(path) + } +} pub fn data_file(s: &str) -> String { - // 新しい設定ディレクトリ(優先) - let new_config_dir = "/.config/syui/ai/bot/"; - let mut new_path = shellexpand::tilde("~").to_string(); - new_path.push_str(&new_config_dir); + let path = expand_home_path("~/.config/ai"); - // 旧設定ディレクトリ(互換性のため) - let old_config_dir = "/.config/ai/"; - let mut old_path = shellexpand::tilde("~").to_string(); - old_path.push_str(&old_config_dir); - - // 新しいディレクトリを作成 - let new_dir = Path::new(&new_path); - if !new_dir.is_dir() { - let _ = fs::create_dir_all(new_path.clone()); + if !path.is_dir() { + let _ = fs::create_dir_all(&path); } - let filename = match &*s { - "toml" => "token.toml", - "json" => "token.json", - "refresh" => "refresh.toml", - _ => &format!(".{}", s), - }; - - let new_file = new_path.clone() + filename; - let old_file = old_path + filename; - - // 新しいパスにファイルが存在する場合は新しいパスを使用 - if Path::new(&new_file).exists() { - return new_file; + let mut path_str = path.to_string_lossy().to_string(); + match &*s { + "toml" => path_str + "/token.toml", + "json" => path_str + "/token.json", + "refresh" => path_str + "/refresh.toml", + _ => path_str + "/." + &s, } - - // 旧パスにファイルが存在し、新しいパスに存在しない場合は移行を試行 - if Path::new(&old_file).exists() && !Path::new(&new_file).exists() { - if let Ok(_) = fs::copy(&old_file, &new_file) { - eprintln!("Migrated config file: {} -> {}", old_file, new_file); - return new_file; - } - } - - // デフォルトは新しいパス - new_file } pub fn log_file(s: &str) -> String { - // 新しい設定ディレクトリ(優先) - let new_log_dir = "/.config/syui/ai/bot/txt/"; - let mut new_path = shellexpand::tilde("~").to_string(); - new_path.push_str(&new_log_dir); + let path = expand_home_path("~/.config/ai/txt"); - // 旧設定ディレクトリ(互換性のため) - let old_log_dir = "/.config/ai/txt/"; - let mut old_path = shellexpand::tilde("~").to_string(); - old_path.push_str(&old_log_dir); - - // 新しいディレクトリを作成 - let new_dir = Path::new(&new_path); - if !new_dir.is_dir() { - let _ = fs::create_dir_all(new_path.clone()); + if !path.is_dir() { + let _ = fs::create_dir_all(&path); } - let filename = match &*s { - "n1" => "notify_cid.txt", - "n2" => "notify_cid_run.txt", - "c1" => "comment_cid.txt", - _ => s, - }; - - let new_file = new_path.clone() + filename; - let old_file = old_path + filename; - - // 新しいパスにファイルが存在する場合は新しいパスを使用 - if Path::new(&new_file).exists() { - return new_file; + let mut path_str = path.to_string_lossy().to_string(); + match &*s { + "n1" => path_str + "/notify_cid.txt", + "n2" => path_str + "/notify_cid_run.txt", + "c1" => path_str + "/comment_cid.txt", + _ => path_str + "/" + &s, } - - // 旧パスにファイルが存在し、新しいパスに存在しない場合は移行を試行 - if Path::new(&old_file).exists() && !Path::new(&new_file).exists() { - if let Ok(_) = fs::copy(&old_file, &new_file) { - eprintln!("Migrated log file: {} -> {}", old_file, new_file); - return new_file; - } - } - - // デフォルトは新しいパス - new_file } impl Token { @@ -318,11 +275,9 @@ pub fn data_refresh(s: &str) -> String { } pub fn data_scpt(s: &str) -> String { - let s = String::from(s); - let file = "/.config/ai/scpt/".to_owned() + &s + &".zsh"; - let mut f = shellexpand::tilde("~").to_string(); - f.push_str(&file); - return f; + let mut path = expand_home_path("~/.config/ai/scpt"); + path.push(format!("{}.zsh", s)); + path.to_string_lossy().to_string() } #[derive(Serialize, Deserialize)] @@ -659,11 +614,10 @@ pub fn w_cid(cid: String, file: String, t: bool) -> bool { } pub fn c_follow_all() { - let file = "/.config/ai/scpt/follow_all.zsh"; - let mut f = shellexpand::tilde("~").to_string(); - f.push_str(&file); + let path = expand_home_path("~/.config/ai/scpt/follow_all.zsh"); + use std::process::Command; - let output = Command::new(&f).output().expect("zsh"); + let output = Command::new(path.to_str().unwrap()).output().expect("zsh"); let d = String::from_utf8_lossy(&output.stdout); let d = "\n".to_owned() + &d.to_string(); println!("{}", d); @@ -673,9 +627,10 @@ pub fn c_openai_key(c: &Context) { let api = c.args[0].to_string(); let o = "api='".to_owned() + &api.to_string() + &"'".to_owned(); let o = o.to_string(); - let l = shellexpand::tilde("~") + "/.config/ai/openai.toml"; - let l = l.to_string(); - let mut l = fs::File::create(l).unwrap(); + + let path = expand_home_path("~/.config/ai/openai.toml"); + + let mut l = fs::File::create(&path).unwrap(); if o != "" { l.write_all(&o.as_bytes()).unwrap(); } @@ -684,9 +639,10 @@ pub fn c_openai_key(c: &Context) { impl Open { pub fn new() -> Result { - let d = shellexpand::tilde("~") + "/.config/ai/openai.toml"; + let path = expand_home_path("~/.config/ai/openai.toml"); + let s = Config::builder() - .add_source(File::with_name(&d)) + .add_source(File::with_name(path.to_str().unwrap())) .add_source(config::Environment::with_prefix("APP")) .build()?; s.try_deserialize()