From a4f7f867f5896e008a9b7b928264af1e3de5d3d2 Mon Sep 17 00:00:00 2001 From: syui Date: Wed, 11 Jun 2025 11:49:53 +0900 Subject: [PATCH] fix cmd --- .claude/settings.local.json | 3 +- src/data.rs | 86 +++++++++++++++++++------------------ src/main.rs | 59 ++++++++++++++++++++++++- 3 files changed, 104 insertions(+), 44 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 566f2cd..64ee94c 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -15,7 +15,8 @@ "Bash(mkdir:*)", "Bash(chmod:*)", "Bash(git checkout:*)", - "Bash(git add:*)" + "Bash(git add:*)", + "Bash(rg:*)" ], "deny": [] } diff --git a/src/data.rs b/src/data.rs index 8eb3efb..bf8e658 100644 --- a/src/data.rs +++ b/src/data.rs @@ -8,6 +8,9 @@ use std::io::Write; use std::path::PathBuf; use std::env; +/// 設定ディレクトリのベースパス +const CONFIG_BASE_DIR: &str = "~/.config/syui/ai/bot"; + /// ホームディレクトリパスを展開するユーティリティ関数 /// "~"で始まるパスをユーザーのホームディレクトリに展開します fn expand_home_path(path: &str) -> PathBuf { @@ -22,7 +25,7 @@ fn expand_home_path(path: &str) -> PathBuf { /// 設定ディレクトリのベースパスを取得し、必要に応じて作成する fn get_config_base_path() -> PathBuf { - let path = expand_home_path("~/.config/syui/ai/bot"); + let path = expand_home_path(CONFIG_BASE_DIR); if !path.is_dir() { let _ = fs::create_dir_all(&path); } @@ -158,15 +161,14 @@ pub struct BaseUrl { } pub fn url(s: &str) -> String { - let s = String::from(s); - let data = Data::new().unwrap(); - let data = Data { - host: data.host, - password: data.password, - handle: data.handle, - did: data.did, - access: data.access, - refresh: data.refresh, + let data = match Data::new() { + Ok(data) => data, + Err(_) => { + eprintln!("Error: Configuration file not found at {}/token.toml", + get_config_base_path().display()); + eprintln!("Please run 'aibot login -p ' first to authenticate."); + std::process::exit(1); + } }; let t = "https://".to_string() + &data.host.to_string() + &"/xrpc/".to_string(); let baseurl = BaseUrl { @@ -223,29 +225,29 @@ pub fn url(s: &str) -> String { "follows" => t.to_string() + &baseurl.follows, "followers" => t.to_string() + &baseurl.followers, "feed_get" => t.to_string() + &baseurl.feed_get, - _ => s, + _ => s.to_string(), } } pub fn data_toml(s: &str) -> String { - let s = String::from(s); - let data = Data::new().unwrap(); - let data = Data { - host: data.host, - password: data.password, - handle: data.handle, - did: data.did, - access: data.access, - refresh: data.refresh, + let data = match Data::new() { + Ok(data) => data, + Err(_) => { + eprintln!("Error: Configuration file not found at {}/token.toml", + get_config_base_path().display()); + eprintln!("Please run 'aibot login -p ' first to authenticate."); + std::process::exit(1); + } }; - match &*s { + + match s { "host" => data.host, "password" => data.password, "handle" => data.handle, "did" => data.did, "access" => data.access, "refresh" => data.refresh, - _ => s, + _ => s.to_string(), } } @@ -261,37 +263,39 @@ pub fn c_refresh(access: &str, refresh: &str) { } pub fn data_refresh(s: &str) -> String { - let s = String::from(s); - - let data = Data::new().unwrap(); - let data = Data { - host: data.host, - password: data.password, - handle: data.handle, - did: data.did, - access: data.access, - refresh: data.refresh, + let data = match Data::new() { + Ok(data) => data, + Err(_) => { + eprintln!("Error: Configuration file not found at {}/token.toml", + get_config_base_path().display()); + eprintln!("Please run 'aibot login -p ' first to authenticate."); + std::process::exit(1); + } }; - let mut _file = match Refresh::new() - { + let mut _file = match Refresh::new() { Err(_why) => c_refresh(&data.access, &data.refresh), Ok(_) => println!(""), }; - let refresh = Refresh::new().unwrap(); - let refresh = Refresh { - access: refresh.access, - refresh: refresh.refresh, + + let refresh = match Refresh::new() { + Ok(refresh) => refresh, + Err(_) => { + eprintln!("Error: Refresh token file not found."); + eprintln!("Please run 'aibot login -p ' to re-authenticate."); + std::process::exit(1); + } }; - match &*s { + + match s { "access" => refresh.access, "refresh" => refresh.refresh, - _ => s, + _ => s.to_string(), } } pub fn data_scpt(s: &str) -> String { - let mut path = expand_home_path("~/.config/syui/ai/bot/scpt"); + let mut path = get_config_path("scpt"); path.push(format!("{}.zsh", s)); path.to_string_lossy().to_string() } diff --git a/src/main.rs b/src/main.rs index 3749623..28cbb09 100644 --- a/src/main.rs +++ b/src/main.rs @@ -508,6 +508,11 @@ fn openai_key(c: &Context) { } fn token(c: &Context) { + if c.args.is_empty() { + eprintln!("Error: Handle is required."); + eprintln!("Usage: aibot login -p "); + std::process::exit(1); + } let m = c.args[0].to_string(); let h = async { if let Ok(p) = c.string_flag("password") { @@ -600,6 +605,11 @@ fn timeline(c: &Context) { fn post(c: &Context) { refresh(c); + if c.args.is_empty() { + eprintln!("Error: Post text is required."); + eprintln!("Usage: aibot post "); + std::process::exit(1); + } let m = c.args[0].to_string(); let h = async { if let Ok(link) = c.string_flag("link") { @@ -619,6 +629,11 @@ fn post(c: &Context) { fn delete(c: &Context) { refresh(c); + if c.args.is_empty() { + eprintln!("Error: Record key is required."); + eprintln!("Usage: aibot delete --col "); + std::process::exit(1); + } let m = c.args[0].to_string(); let h = async { if let Ok(col) = c.string_flag("col") { @@ -632,6 +647,11 @@ fn delete(c: &Context) { fn like(c: &Context) { refresh(c); + if c.args.is_empty() { + eprintln!("Error: CID is required."); + eprintln!("Usage: aibot like --uri "); + std::process::exit(1); + } let m = c.args[0].to_string(); let h = async { if let Ok(uri) = c.string_flag("uri") { @@ -784,6 +804,11 @@ fn game_login(c: &Context) { fn repost(c: &Context) { refresh(c); + if c.args.is_empty() { + eprintln!("Error: CID is required."); + eprintln!("Usage: aibot repost --uri "); + std::process::exit(1); + } let m = c.args[0].to_string(); let h = async { if let Ok(uri) = c.string_flag("uri") { @@ -797,6 +822,11 @@ fn repost(c: &Context) { fn follow(c: &Context) { refresh(c); + if c.args.is_empty() { + eprintln!("Error: Handle is required."); + eprintln!("Usage: aibot follow "); + std::process::exit(1); + } let m = c.args[0].to_string(); let h = async { let handle = data_toml(&"handle"); @@ -820,10 +850,10 @@ fn profile(c: &Context) { let h = async { if c.args.len() == 0 { let j = profile::get_request(data_toml(&"handle")).await; - println!("{}", j); + print!("{}", j); } else { let j = profile::get_request(c.args[0].to_string()).await; - println!("{}", j); + print!("{}", j); } }; let res = tokio::runtime::Runtime::new().unwrap().block_on(h); @@ -832,6 +862,11 @@ fn profile(c: &Context) { fn mention(c: &Context) { refresh(c); + if c.args.is_empty() { + eprintln!("Error: Handle is required."); + eprintln!("Usage: aibot mention "); + std::process::exit(1); + } let m = c.args[0].to_string(); let h = async { let str = profile::get_request(m.to_string()).await; @@ -861,6 +896,11 @@ fn mention(c: &Context) { fn reply(c: &Context) { refresh(c); + if c.args.is_empty() { + eprintln!("Error: Reply text is required."); + eprintln!("Usage: aibot reply --cid --uri "); + std::process::exit(1); + } let m = c.args[0].to_string(); let h = async { if let Ok(cid) = c.string_flag("cid") { @@ -900,6 +940,11 @@ fn reply(c: &Context) { #[tokio::main] async fn c_img_upload(c: &Context) -> reqwest::Result<()> { + if c.args.is_empty() { + eprintln!("Error: Image file path is required."); + eprintln!("Usage: aibot img_upload "); + std::process::exit(1); + } let token = data_refresh(&"access"); let atoken = "Authorization: Bearer ".to_owned() + &token; let con = "Content-Type: image/png"; @@ -931,6 +976,11 @@ fn img_upload(c: &Context) { } fn img_post(c: &Context) { + if c.args.is_empty() { + eprintln!("Error: Text is required."); + eprintln!("Usage: aibot img_post --link --cid --uri "); + std::process::exit(1); + } let m = c.args[0].to_string(); let link = c.string_flag("link").unwrap(); let cid = c.string_flag("cid").unwrap(); @@ -977,6 +1027,11 @@ fn reply_og(c: &Context) { } fn openai(c: &Context) { + if c.args.is_empty() { + eprintln!("Error: Message is required."); + eprintln!("Usage: aibot openai "); + std::process::exit(1); + } let m = c.args[0].to_string(); let h = async { let str = openai::post_request(m.to_string()).await;