photosync/src/web.rs

84 lines
2.3 KiB
Rust

use std::error::Error;
use std::net::SocketAddr;
use std::path::PathBuf;
use prometheus::Encoder;
use serde::Deserialize;
use warp;
use warp::http::header::{HeaderMap, HeaderValue};
use warp::reject::Rejection;
use warp::Filter;
use crate::library::Library;
fn metrics() -> impl Filter<Extract = (impl warp::reply::Reply,), Error = Rejection> + Clone {
let mut text_headers = HeaderMap::new();
text_headers.insert("content-type", HeaderValue::from_static("text/plain"));
warp::path("metrics")
.map(|| {
let mut buffer = Vec::new();
let encoder = prometheus::TextEncoder::new();
// Gather the metrics.
let metric_families = prometheus::gather();
// Encode them to send.
encoder.encode(&metric_families, &mut buffer).unwrap();
// TODO(wathiede): see if there's a wrapper like html()
buffer
})
.with(warp::reply::with::headers(text_headers))
}
fn index() -> Result<impl warp::Reply, warp::Rejection> {
Ok("Hello world")
}
fn album(lib: Library, id: String) -> Result<impl warp::Reply, warp::Rejection> {
Ok(format!("Hello world: {}", id))
}
#[derive(Debug, Deserialize)]
struct ImageParams {
w: Option<usize>,
h: Option<usize>,
c: Option<bool>,
}
fn image(
lib: Library,
image_id: String,
params: ImageParams,
) -> Result<impl warp::Reply, warp::Rejection> {
Ok(format!("Hello world: {} {:?}", image_id, params))
}
pub fn run(addr: SocketAddr, root: PathBuf) -> Result<(), Box<dyn Error>> {
let lib = Library::new(root)?;
let lib = warp::any().map(move || lib.clone());
let index = warp::path::end().and_then(index);
let album = warp::path("album")
.and(lib.clone())
.and(warp::path::param())
.and_then(album);
let image = warp::path("image")
.and(lib.clone())
.and(warp::path::param())
.and(warp::query::<ImageParams>())
.and_then(image);
let api = album.or(image);
let api = warp::path("api").and(api);
// Fallback, always keep this last.
let api = api.or(index);
let api = api.with(warp::log("photosync"));
// We don't want metrics & heath checking filling up the logs, so we add this handler after
// wrapping with the log filter.
let routes = metrics().or(api);
warp::serve(routes).run(addr);
Ok(())
}