From 2c867eaf5c449f9267583abba1b20cfa95785419 Mon Sep 17 00:00:00 2001 From: syui Date: Sun, 22 Mar 2026 18:57:03 +0900 Subject: [PATCH] fix config --- src/commands/bot.rs | 24 ++++++++++-------------- src/commands/oauth.rs | 36 +++++------------------------------- src/commands/sync.rs | 7 +++---- src/commands/token.rs | 30 ++++++++++++++++++++++++++++++ src/main.rs | 14 ++++---------- 5 files changed, 52 insertions(+), 59 deletions(-) diff --git a/src/commands/bot.rs b/src/commands/bot.rs index fdac91d..f7731b0 100644 --- a/src/commands/bot.rs +++ b/src/commands/bot.rs @@ -233,11 +233,9 @@ fn save_state(state: &BotState) -> Result<()> { Ok(()) } -/// Load admin DID from config.json -fn load_admin_did(config_path: &str) -> Result { - let content = fs::read_to_string(config_path) - .with_context(|| format!("Config file not found: {}", config_path))?; - let config: Value = serde_json::from_str(&content)?; +/// Load admin DID from config.json ($cfg first, then fallback) +fn load_admin_did() -> Result { + let config = token::load_config()?; config["did"] .as_str() .map(|s| s.to_string()) @@ -342,8 +340,8 @@ async fn post_reply( } /// Main bot entry point -pub async fn start(interval_secs: u64, config_path: &str) -> Result<()> { - let admin_did = load_admin_did(config_path)?; +pub async fn start(interval_secs: u64) -> Result<()> { + let admin_did = load_admin_did()?; eprintln!("bot: admin DID = {}", admin_did); eprintln!("bot: polling interval = {}s", interval_secs); @@ -564,10 +562,8 @@ fn save_chat_state(state: &ChatBotState) -> Result<()> { } /// Load chat proxy from config.json network field -fn load_chat_proxy(config_path: &str) -> Result { - let content = fs::read_to_string(config_path) - .with_context(|| format!("Config file not found: {}", config_path))?; - let config: Value = serde_json::from_str(&content)?; +fn load_chat_proxy() -> Result { + let config = token::load_config()?; if let Some(network) = config["network"].as_str() { Ok(format!("did:web:bsky.{}#bsky_chat", network)) } else { @@ -578,9 +574,9 @@ fn load_chat_proxy(config_path: &str) -> Result { // Chat API uses XrpcClient with atproto-proxy header via query_auth_proxy / call_proxy /// Main chat bot entry point -pub async fn start_chat(interval_secs: u64, config_path: &str) -> Result<()> { - let admin_did = load_admin_did(config_path)?; - let proxy_did = load_chat_proxy(config_path)?; +pub async fn start_chat(interval_secs: u64) -> Result<()> { + let admin_did = load_admin_did()?; + let proxy_did = load_chat_proxy()?; eprintln!("chat-bot: admin DID = {}", admin_did); eprintln!("chat-bot: proxy = {}", proxy_did); eprintln!("chat-bot: polling interval = {}s", interval_secs); diff --git a/src/commands/oauth.rs b/src/commands/oauth.rs index d0d70b8..30b5557 100644 --- a/src/commands/oauth.rs +++ b/src/commands/oauth.rs @@ -8,38 +8,12 @@ use std::io::{self, Write}; use super::token::{self, Session, BUNDLE_ID}; -#[derive(Debug, Deserialize)] -struct SiteConfig { - #[serde(rename = "siteUrl")] - site_url: Option, -} - fn load_site_url() -> Result { - // 1. Try public/config.json in current directory - let local_path = std::path::Path::new("public/config.json"); - if local_path.exists() { - let content = std::fs::read_to_string(local_path)?; - let config: SiteConfig = serde_json::from_str(&content)?; - if let Some(url) = config.site_url { - return Ok(url.trim_end_matches('/').to_string()); - } - } - - // 2. Fallback to ~/.config/ai.syui.log/config.json - if let Some(cfg_dir) = dirs::config_dir() { - let cfg_path = cfg_dir.join(BUNDLE_ID).join("config.json"); - if cfg_path.exists() { - let content = std::fs::read_to_string(&cfg_path)?; - let config: SiteConfig = serde_json::from_str(&content)?; - if let Some(url) = config.site_url { - return Ok(url.trim_end_matches('/').to_string()); - } - } - } - - anyhow::bail!( - "No siteUrl found. Create public/config.json or run ailog oauth with --client-id" - ); + let config = super::token::load_config()?; + config["siteUrl"] + .as_str() + .map(|s| s.trim_end_matches('/').to_string()) + .context("No siteUrl found in config.json. Run 'ailog setup' first.") } diff --git a/src/commands/sync.rs b/src/commands/sync.rs index af3f647..48b3d7c 100644 --- a/src/commands/sync.rs +++ b/src/commands/sync.rs @@ -29,10 +29,9 @@ pub async fn sync_to_local( collection.to_string(), ) } else { - // User mode: use config.json - let config_content = - fs::read_to_string("public/config.json").context("config.json not found")?; - let config: Config = serde_json::from_str(&config_content)?; + // User mode: use config.json ($cfg first, then public/config.json) + let config_value = super::token::load_config()?; + let config: Config = serde_json::from_value(config_value)?; println!("Syncing data for {}", config.handle); diff --git a/src/commands/token.rs b/src/commands/token.rs index 8d2efaa..9bc99ce 100644 --- a/src/commands/token.rs +++ b/src/commands/token.rs @@ -70,3 +70,33 @@ pub fn save_bot_session(session: &Session) -> Result<()> { fs::write(&path, content)?; Ok(()) } + +/// Get config.json path: $cfg/ai.syui.log/config.json +pub fn config_path() -> Result { + let cfg_dir = dirs::config_dir() + .context("Could not find config directory")? + .join(BUNDLE_ID); + Ok(cfg_dir.join("config.json")) +} + +/// Load config.json: $cfg/ai.syui.log/config.json (primary), public/config.json (fallback) +pub fn load_config() -> Result { + // 1. $cfg/ai.syui.log/config.json + if let Ok(cfg_path) = config_path() { + if cfg_path.exists() { + let content = fs::read_to_string(&cfg_path)?; + return Ok(serde_json::from_str(&content)?); + } + } + + // 2. Fallback: public/config.json (for backward compat) + let local_path = std::path::Path::new("public/config.json"); + if local_path.exists() { + let content = fs::read_to_string(local_path)?; + return Ok(serde_json::from_str(&content)?); + } + + anyhow::bail!( + "config.json not found. Run 'ailog setup' first." + ) +} diff --git a/src/main.rs b/src/main.rs index a2e30d3..decc2af 100644 --- a/src/main.rs +++ b/src/main.rs @@ -287,18 +287,12 @@ enum BotCommands { /// Poll interval in seconds #[arg(short, long, default_value = "30")] interval: u64, - /// Path to config.json - #[arg(short, long, default_value = "public/config.json")] - config: String, }, /// Start the DM chat bot (poll chat messages and reply) Chat { /// Poll interval in seconds #[arg(short, long, default_value = "30")] interval: u64, - /// Path to config.json - #[arg(short, long, default_value = "public/config.json")] - config: String, }, } @@ -418,11 +412,11 @@ async fn main() -> Result<()> { } Commands::Bot { command } => { match command { - BotCommands::Start { interval, config } => { - commands::bot::start(interval, &config).await?; + BotCommands::Start { interval } => { + commands::bot::start(interval).await?; } - BotCommands::Chat { interval, config } => { - commands::bot::start_chat(interval, &config).await?; + BotCommands::Chat { interval } => { + commands::bot::start_chat(interval).await?; } } }