Parse config file and act upon
All dependencies were updated. An example configuration file `config.yml` is added to show the configuration options. Following locations are checked: - `/etc/webhookey/config.yml` - `<config_dir>/webhookey/config.yml` - `./config.yml` Whereas `<config_dir>` is depending on the platform: - Linux: `$XDG_CONFIG_HOME` or `$HOME/.config` - macOS: `$HOME/Library/Application Support` - Windows: `{FOLDERID_RoamingAppData}` Each hook's action is executed if all of the specified filters match.
This commit is contained in:
parent
d8ca63ab37
commit
c8505b27c5
4 changed files with 440 additions and 137 deletions
109
src/main.rs
109
src/main.rs
|
@ -1,24 +1,121 @@
|
|||
#![feature(proc_macro_hygiene, decl_macro)]
|
||||
|
||||
use rocket::{get, post, routes};
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use regex::Regex;
|
||||
use rocket::{fairing::AdHoc, get, post, routes, State};
|
||||
use rocket_contrib::json::Json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::process::Command;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
struct Data (serde_json::Value);
|
||||
struct Config {
|
||||
hooks: HashMap<String, Hook>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
struct Hook {
|
||||
action: Option<String>,
|
||||
filters: HashMap<String, Filter>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
struct Filter {
|
||||
pointer: String,
|
||||
regex: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
struct Data(serde_json::Value);
|
||||
|
||||
#[get("/")]
|
||||
fn index() -> &'static str {
|
||||
"Hello, webhookey!"
|
||||
}
|
||||
|
||||
#[post("/", format = "json", data = "<data>")]
|
||||
fn receive_hook(data: Json<Data>) -> String {
|
||||
format!("data: {:?}", data)
|
||||
fn execute_hook(name: &str, hook: &Hook, data: &serde_json::Value) -> Result<()> {
|
||||
println!(
|
||||
"hook: {:?} action: {:?} filters: {:?}",
|
||||
name, hook.action, hook.filters
|
||||
);
|
||||
|
||||
for (filter_name, filter) in hook.filters.iter() {
|
||||
println!("filter: {:?}", filter);
|
||||
|
||||
if let Some(value) = data.pointer(&filter.pointer) {
|
||||
let regex = Regex::new(&filter.regex)?;
|
||||
|
||||
if let Some(value) = value.as_str() {
|
||||
if !regex.is_match(value) {
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
println!("Error could not parse pointer");
|
||||
anyhow!(
|
||||
"Could not parse pointer in hook `{}` from filter `{}`",
|
||||
name,
|
||||
filter_name
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("execute action");
|
||||
|
||||
if let Some(action) = &hook.action {
|
||||
println!("execute {}", action);
|
||||
|
||||
Command::new(action).spawn()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
#[post("/", format = "json", data = "<data>")]
|
||||
fn receive_hook(config: State<Config>, data: Json<Data>) -> Result<String> {
|
||||
let data = serde_json::to_value(data.0)?;
|
||||
|
||||
for (hook_name, hook) in config.hooks.iter() {
|
||||
execute_hook(&hook_name, &hook, &data)?;
|
||||
}
|
||||
|
||||
Ok("Request received.".to_string())
|
||||
}
|
||||
|
||||
fn get_config() -> Result<File> {
|
||||
if let Ok(config) = File::open("/etc/webhookey/config.yml") {
|
||||
return Ok(config);
|
||||
}
|
||||
|
||||
if let Some(mut path) = dirs::config_dir() {
|
||||
path.push("webhookey/config.yml");
|
||||
|
||||
if let Ok(config) = File::open(path) {
|
||||
return Ok(config);
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(config) = File::open("config.yml") {
|
||||
return Ok(config);
|
||||
}
|
||||
|
||||
bail!("No configuration files found.");
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let config: Config = serde_yaml::from_reader(BufReader::new(get_config()?))?;
|
||||
|
||||
println!("{}", serde_yaml::to_string(&config)?);
|
||||
|
||||
rocket::ignite()
|
||||
.mount("/", routes![index, receive_hook])
|
||||
.attach(AdHoc::on_attach("webhookey config", move |rocket| {
|
||||
Ok(rocket.manage(config))
|
||||
}))
|
||||
.launch();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue