diff options
| -rw-r--r-- | README.md | 18 | ||||
| -rw-r--r-- | example_config.toml | 71 | ||||
| -rwxr-xr-x | run.sh | 64 | ||||
| -rw-r--r-- | src/main.rs | 44 |
4 files changed, 124 insertions, 73 deletions
@@ -60,20 +60,26 @@ opens the popup chat window for the channel. :) --- -How to run: +How to install and run: ```sh git clone https://github.com/dilluti0n/chzzkd cd chzzkd cargo install --path . -chzzkd < config.toml +mkdir -p "$HOME/.config/chzzkd/" +cp example_config.toml "$HOME/.config/chzzkd/config.toml" +chzzkd # Run as daemon -RUST_LOG=info setsid chzzkd < config.toml >/dev/null 2>chzzkd.log +RUST_LOG=info setsid chzzkd 2>chzzkd.log # Stop daemon pkill chzzkd ``` -Currently, configuration is read from stdin. The first release will -replace it with a default config file (such as `/etc/chzzkd.toml`) and -a command-line override. +Synopsis: `chzzkd [CONFIG]` + +Configuration path precedence: + 1. `CONFIG` (command line argument) + 2. $XDG_CONFIG_HOME/chzzkd/config.toml + 3. $HOME/.config/chzzkd/config.toml + 4. /etc/chzzkd/config.toml diff --git a/example_config.toml b/example_config.toml new file mode 100644 index 0000000..3dc16cb --- /dev/null +++ b/example_config.toml @@ -0,0 +1,71 @@ +timeout = 10 + +[hooks] +went_open = ''' +url="https://chzzk.naver.com/live/$CHZZKD_ID" +action=$(notify-send -a chzzkd \ + -A default="mpv" \ + "$CHZZKD_ALIAS: hello" \ + "$CHZZKD_LIVE_TITLE") + +case "$action" in + default) mpv "$url" ;; +esac +''' +went_close = 'notify-send -a chzzkd "$CHZZKD_ALIAS: bye"' + +[[channel]] +id = "c847a58a1599988f6154446c75366523" +alias = "dopa" + +[[channel]] +id = "a7e175625fdea5a7d98428302b7aa57f" +alias = "chamcham" + +[[channel]] +id = "6e06f5e1907f17eff543abd06cb62891" +alias = "nokduro" + +[[channel]] +id = "9381e7d6816e6d915a44a13c0195b202" +alias = "lck" + +[[channel]] +id = "0b33823ac81de48d5b78a38cdbc0ab94" +alias = "wolf" + +[[channel]] +id = "42597020c1a79fb151bd9b9beaa9779b" +alias = "paka" + +[[channel]] +id = "26ae7850ad5b6b09ca864d482dc7fa50" +alias = "qb" + +[[channel]] +id = "c100f81959d1c17044be0541eed56f5b" +alias = "megajw" + +[[channel]] +id = "b5ed5db484d04faf4d150aedd362f34b" +alias = "gg" + +[[channel]] +id = "8b3e8e3a13201cff0836c69cfab62f45" +alias = "flame" + +[[channel]] +id = "6cac96d5c9b7a9fd28903aa32fc61749" +alias = "hd" + +[[channel]] +id = "bc2dbff369307b5c446224cce192c8b1" +alias = "goarosa" + +[[channel]] +id = "732f6f16d20991243ec3f2d7afed8821" +alias = "0du" + +[[channel]] +id = "96e44e40a448971244bfd9dd8c832505" +alias = "gn" @@ -1,65 +1,3 @@ #!/bin/sh -cmd='cargo run' -$cmd << 'EOF' -timeout = 10 - -[hooks] -went_open = 'echo "$CHZZKD_ALIAS: $CHZZKD_LIVE_TITLE"' - -[[channel]] -id = "c847a58a1599988f6154446c75366523" -alias = "dopa" - -[[channel]] -id = "a7e175625fdea5a7d98428302b7aa57f" -alias = "chamcham" - -[[channel]] -id = "6e06f5e1907f17eff543abd06cb62891" -alias = "nokduro" - -[[channel]] -id = "9381e7d6816e6d915a44a13c0195b202" -alias = "lck" - -[[channel]] -id = "0b33823ac81de48d5b78a38cdbc0ab94" -alias = "wolf" - -[[channel]] -id = "42597020c1a79fb151bd9b9beaa9779b" -alias = "paka" - -[[channel]] -id = "26ae7850ad5b6b09ca864d482dc7fa50" -alias = "qb" - -[[channel]] -id = "c100f81959d1c17044be0541eed56f5b" -alias = "megajw" - -[[channel]] -id = "b5ed5db484d04faf4d150aedd362f34b" -alias = "gg" - -[[channel]] -id = "8b3e8e3a13201cff0836c69cfab62f45" -alias = "flame" - -[[channel]] -id = "6cac96d5c9b7a9fd28903aa32fc61749" -alias = "hd" - -[[channel]] -id = "bc2dbff369307b5c446224cce192c8b1" -alias = "goarosa" - -[[channel]] -id = "732f6f16d20991243ec3f2d7afed8821" -alias = "0du" - -[[channel]] -id = "96e44e40a448971244bfd9dd8c832505" -alias = "gn" -EOF +cargo run example_config.toml diff --git a/src/main.rs b/src/main.rs index d0423ee..9dfdc5f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,8 @@ use serde::Deserialize; +use std::fs; +use std::path::PathBuf; +use std::env; +use std::io; use std::time::Duration; use std::sync::Arc; use std::fmt; @@ -221,6 +225,38 @@ async fn watch(cfg: Arc<Config>, idx: usize, client: reqwest::Client) { ch.event_loop(&client, cfg.timeout, &cfg.hooks).await; } +/// Resolves config file path. Precedence: +/// 1. argv[1] +/// 2. $XDG_CONFIG_HOME/chzzkd/config.toml +/// 3. $HOME/.config/chzzkd/config.toml +/// 4. /etc/chzzkd/config.toml +fn resolve_cfg_path() -> Result<PathBuf, io::Error> { + if let Some(arg) = env::args_os().nth(1) { + let p = PathBuf::from(arg); + return if p.is_file() { + Ok(p) + } else { + Err(io::Error::new( + io::ErrorKind::NotFound, + format!("{}: no such config file", p.display()), + )) + }; + } + + let xdg = env::var_os("XDG_CONFIG_HOME") + .filter(|s| !s.is_empty()) + .map(|d| PathBuf::from(d).join("chzzkd/config.toml")); + let home = env::var_os("HOME") + .filter(|s| !s.is_empty()) + .map(|h| PathBuf::from(h).join(".config/chzzkd/config.toml")); + + xdg.into_iter() + .chain(home) + .chain(std::iter::once(PathBuf::from("/etc/chzzkd/config.toml"))) + .find(|p| p.is_file()) + .ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "no config file found")) +} + #[tokio::main] async fn main() -> anyhow::Result<()> { env_logger::init(); @@ -229,11 +265,11 @@ async fn main() -> anyhow::Result<()> { .user_agent("Mozilla/5.0") .build()?; - let cfg = { - use std::io::Read; + let cfg_path = resolve_cfg_path()?; + info!("Found config {:?}, using it", cfg_path); - let mut s = String::new(); - std::io::stdin().read_to_string(&mut s)?; + let cfg = { + let s = fs::read_to_string(&cfg_path)?; Arc::new(toml::from_str::<Config>(&s)?) }; |
