nice
This commit is contained in:
parent
fdb5c7a9b3
commit
8d50817587
5 changed files with 78 additions and 26 deletions
44
src/handler.rs
Normal file
44
src/handler.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
use failure::{err_msg, Error};
|
||||
use serde_json::Value as JsonValue;
|
||||
use toml::Value as TomlValue;
|
||||
|
||||
use PROGRAMS;
|
||||
|
||||
pub struct Handler {
|
||||
exec: PathBuf,
|
||||
}
|
||||
|
||||
impl Handler {
|
||||
pub fn from(config: &TomlValue) -> Result<Self, Error> {
|
||||
let handler = config
|
||||
.get("type")
|
||||
.ok_or(err_msg("No 'type' found."))?
|
||||
.as_str()
|
||||
.ok_or(err_msg("'type' is not a string."))?;
|
||||
let exec = {
|
||||
let programs = PROGRAMS.lock().unwrap();
|
||||
programs
|
||||
.get(handler)
|
||||
.ok_or(err_msg(format!("'{}' is not a valid executable", handler)))
|
||||
.map(|value| value.clone())?
|
||||
};
|
||||
Ok(Handler { exec })
|
||||
}
|
||||
pub fn run(&self, _: Result<JsonValue, Error>) -> Result<JsonValue, Error> {
|
||||
Command::new(&self.exec)
|
||||
.output()
|
||||
.map_err(|err| err_msg(format!("{}", err)))
|
||||
.and_then(|output| {
|
||||
if !output.status.success() {
|
||||
return Err(err_msg(format!(
|
||||
"'{:?}' returned with a non-zero status code: {}",
|
||||
self.exec, output.status
|
||||
)));
|
||||
}
|
||||
Ok(json!({}))
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
pub struct HandlerBuilder {}
|
|
@ -1,17 +0,0 @@
|
|||
mod builder;
|
||||
|
||||
use failure::Error;
|
||||
use serde_json::Value as JsonValue;
|
||||
use toml::Value as TomlValue;
|
||||
|
||||
pub use self::builder::*;
|
||||
|
||||
pub struct Handler {
|
||||
pub handle: fn(Result<JsonValue, Error>) -> Result<JsonValue, Error>,
|
||||
}
|
||||
|
||||
impl Handler {
|
||||
pub fn from(config: &TomlValue) -> Result<Self, Error> {
|
||||
bail!("rip")
|
||||
}
|
||||
}
|
|
@ -52,7 +52,7 @@ impl Hook {
|
|||
pub fn iter(&self) -> Iter<Handler> {
|
||||
self.handlers.iter()
|
||||
}
|
||||
pub fn handle(&self, payload: &Request<Body>) -> Result<Response<Body>, Error> {
|
||||
pub fn handle(&self, _payload: &Request<Body>) -> Result<Response<Body>, Error> {
|
||||
Ok(Response::new(Body::from("lol")))
|
||||
}
|
||||
}
|
||||
|
|
40
src/lib.rs
40
src/lib.rs
|
@ -1,6 +1,5 @@
|
|||
//! # Dip
|
||||
|
||||
#[macro_use]
|
||||
extern crate failure;
|
||||
extern crate hyper;
|
||||
extern crate serde;
|
||||
|
@ -13,11 +12,11 @@ extern crate regex;
|
|||
extern crate toml;
|
||||
extern crate walkdir;
|
||||
|
||||
pub mod handlers;
|
||||
pub mod handler;
|
||||
pub mod hook;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{mpsc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
@ -30,7 +29,7 @@ use notify::{RecommendedWatcher, RecursiveMode, Watcher};
|
|||
use regex::Regex;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
pub use handlers::Handler;
|
||||
pub use handler::*;
|
||||
use hook::*;
|
||||
|
||||
const URIPATTERN_STR: &str = r"/webhook/(?P<name>[A-Za-z._][A-Za-z0-9._]*)";
|
||||
|
@ -38,6 +37,7 @@ const URIPATTERN_STR: &str = r"/webhook/(?P<name>[A-Za-z._][A-Za-z0-9._]*)";
|
|||
lazy_static! {
|
||||
static ref URIPATTERN: Regex = Regex::new(URIPATTERN_STR).unwrap();
|
||||
static ref HANDLERS: Mutex<HashMap<String, Box<Handler>>> = Mutex::new(HashMap::new());
|
||||
static ref PROGRAMS: Mutex<HashMap<String, PathBuf>> = Mutex::new(HashMap::new());
|
||||
static ref HOOKS: Mutex<HashMap<String, Hook>> = Mutex::new(HashMap::new());
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ fn service_fn(req: &Request<Body>) -> Result<Response<Body>, Error> {
|
|||
"method": req.method().as_str(),
|
||||
});
|
||||
hook.iter()
|
||||
.fold(Ok(req_obj), |prev, handler| (handler.handle)(prev))
|
||||
.fold(Ok(req_obj), |prev, handler| handler.run(prev))
|
||||
.map(|_| Response::new(Body::from("success")))
|
||||
}
|
||||
|
||||
|
@ -91,8 +91,34 @@ where
|
|||
println!("Reloading config...");
|
||||
// hold on to the lock while config is being reloaded
|
||||
{
|
||||
let mut handlers = HANDLERS.lock().unwrap();
|
||||
handlers.clear();
|
||||
let mut programs = PROGRAMS.lock().unwrap();
|
||||
programs.clear();
|
||||
let programs_dir = {
|
||||
let mut p = root.as_ref().to_path_buf();
|
||||
p.push("handlers");
|
||||
p
|
||||
};
|
||||
if programs_dir.exists() {
|
||||
for entry in WalkDir::new(programs_dir) {
|
||||
let path = match entry.as_ref().map(|e| e.path()) {
|
||||
Ok(path) => path,
|
||||
_ => continue,
|
||||
};
|
||||
if !path.is_file() {
|
||||
continue;
|
||||
}
|
||||
match path
|
||||
.file_name()
|
||||
.and_then(|s| s.to_str())
|
||||
.ok_or(err_msg("???"))
|
||||
.map(|s| {
|
||||
let filename = s.to_owned();
|
||||
programs.insert(filename, path.to_path_buf())
|
||||
}) {
|
||||
_ => (), // don't care
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut hooks = HOOKS.lock().unwrap();
|
||||
|
|
Loading…
Add table
Reference in a new issue