Rocket based webserver now has parity with warp version.
This commit is contained in:
parent
80ef93f20f
commit
76594dc0c1
101
Cargo.lock
generated
101
Cargo.lock
generated
@ -733,6 +733,18 @@ version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "348138dd23e03bb0018caef99647fb1a5befec5ff4b501991de88f09854d4c28"
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "affc17579b132fc2461adf7c575cc6e8b134ebca52c51f5411388965227dc695"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.6"
|
||||
@ -781,6 +793,25 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61f9b85573bf0f203eed3633f5018abce85250886a62ca073e0eee022ed564d"
|
||||
|
||||
[[package]]
|
||||
name = "fsevent"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"fsevent-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fsevent-sys"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
@ -1366,6 +1397,26 @@ dependencies = [
|
||||
"adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"inotify-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify-sys"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "input_buffer"
|
||||
version = "0.2.0"
|
||||
@ -1455,6 +1506,12 @@ version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
||||
|
||||
[[package]]
|
||||
name = "lcms2"
|
||||
version = "5.1.5"
|
||||
@ -1660,6 +1717,18 @@ dependencies = [
|
||||
"winapi 0.2.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio-extras"
|
||||
version = "2.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
|
||||
dependencies = [
|
||||
"lazycell",
|
||||
"log 0.4.8",
|
||||
"mio",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio-named-pipes"
|
||||
version = "0.1.6"
|
||||
@ -1801,6 +1870,24 @@ dependencies = [
|
||||
"version_check 0.1.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "4.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"filetime",
|
||||
"fsevent",
|
||||
"fsevent-sys",
|
||||
"inotify",
|
||||
"libc",
|
||||
"mio",
|
||||
"mio-extras",
|
||||
"walkdir",
|
||||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.42"
|
||||
@ -2028,6 +2115,7 @@ dependencies = [
|
||||
"regex",
|
||||
"reqwest",
|
||||
"rocket",
|
||||
"rocket_contrib",
|
||||
"rocksdb",
|
||||
"rust-embed",
|
||||
"serde",
|
||||
@ -2595,6 +2683,19 @@ dependencies = [
|
||||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rocket_contrib"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3946ca815127041d8f64455561031d058c22ae1b135251502c5ea523cf9e14b"
|
||||
dependencies = [
|
||||
"log 0.4.8",
|
||||
"notify",
|
||||
"rocket",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rocket_http"
|
||||
version = "0.4.5"
|
||||
|
||||
@ -47,3 +47,8 @@ harness = false
|
||||
# Build dependencies with release optimizations even in dev mode.
|
||||
[profile.dev.package."*"]
|
||||
opt-level = 3
|
||||
|
||||
[dependencies.rocket_contrib]
|
||||
version = "0.4.5"
|
||||
default-features = false
|
||||
features = ["json"]
|
||||
|
||||
142
src/rweb.rs
142
src/rweb.rs
@ -1,23 +1,106 @@
|
||||
use std::error::Error;
|
||||
use std::io::Write;
|
||||
use std::net::SocketAddr;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use cacher::Cacher;
|
||||
use google_photoslibrary1 as photos;
|
||||
use log::error;
|
||||
use photos::schemas::{Album, MediaItem};
|
||||
use prometheus::Encoder;
|
||||
use rocket::error::LaunchError;
|
||||
use rocket::http::ContentType;
|
||||
use rocket::response::content::Html;
|
||||
use rocket::response::status::NotFound;
|
||||
use rocket::response::Content;
|
||||
use rocket::{Request, State};
|
||||
use rocket_contrib::json::Json;
|
||||
use rust_embed::RustEmbed;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::library::Library;
|
||||
|
||||
#[get("/metrics")]
|
||||
fn metrics() -> Content<Vec<u8>> {
|
||||
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()
|
||||
Content(ContentType::Plain, buffer)
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
fn index(lib: State<Library>) -> Result<Content<Vec<u8>>, NotFound<String>> {
|
||||
file("index.html", lib)
|
||||
}
|
||||
|
||||
#[get("/<path..>")]
|
||||
fn path(path: PathBuf, lib: State<Library>) -> Result<Content<Vec<u8>>, NotFound<String>> {
|
||||
let path = path.to_str().unwrap();
|
||||
let path = if path.ends_with("/") {
|
||||
format!("{}index.html", path.to_string())
|
||||
} else {
|
||||
path.to_string()
|
||||
};
|
||||
file(&path, lib)
|
||||
}
|
||||
|
||||
fn file(path: &str, lib: State<Library>) -> Result<Content<Vec<u8>>, NotFound<String>> {
|
||||
match Asset::get(path) {
|
||||
Some(bytes) => {
|
||||
let mime = mime_guess::from_path(path).first_or_octet_stream();
|
||||
let ct = ContentType::parse_flexible(mime.essence_str()).unwrap_or(ContentType::Binary);
|
||||
|
||||
Ok(Content(ct, bytes.into()))
|
||||
}
|
||||
None => Err(NotFound(path.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/api/albums")]
|
||||
fn albums(lib: State<Library>) -> Result<Json<Vec<Album>>, NotFound<String>> {
|
||||
let albums = lib
|
||||
.albums()
|
||||
.map_err(|e| NotFound(format!("Couldn't find albums: {}", e)))?;
|
||||
Ok(Json(albums))
|
||||
}
|
||||
|
||||
#[get("/api/album/<id>")]
|
||||
fn album(id: String, lib: State<Library>) -> Result<Json<Vec<MediaItem>>, NotFound<String>> {
|
||||
let album = lib
|
||||
.album(&id)
|
||||
.map_err(|e| NotFound(format!("Couldn't find album {}: {}", id, e)))?;
|
||||
Ok(Json(album))
|
||||
}
|
||||
|
||||
#[get("/api/image/<media_items_id>?<w>&<h>&<fill>")]
|
||||
fn image(
|
||||
media_items_id: String,
|
||||
w: Option<u32>,
|
||||
h: Option<u32>,
|
||||
fill: Option<bool>,
|
||||
lib: State<Library>,
|
||||
) -> Result<Content<Vec<u8>>, NotFound<String>> {
|
||||
// TODO(wathiede): add caching headers.
|
||||
match lib.thumbnail(&media_items_id, (w, h), fill.unwrap_or(false)) {
|
||||
None => Err(NotFound(format!(
|
||||
"Couldn't find original {}",
|
||||
&media_items_id
|
||||
))),
|
||||
Some(bytes) => Ok(Content(ContentType::JPEG, bytes.into())),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "react-slideshow/build/"]
|
||||
struct Asset;
|
||||
|
||||
/*
|
||||
fn embedz() -> Result<impl warp::Reply, warp::Rejection> {
|
||||
#[get("/embedz")]
|
||||
fn embedz() -> Content<Vec<u8>> {
|
||||
let mut w = Vec::new();
|
||||
write!(
|
||||
w,
|
||||
@ -33,47 +116,26 @@ fn embedz() -> Result<impl warp::Reply, warp::Rejection> {
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
Ok(warp::http::Response::builder()
|
||||
.header("Content-Type", "text/html")
|
||||
.body(w))
|
||||
}
|
||||
*/
|
||||
|
||||
#[get("/")]
|
||||
fn index(lib: State<Library>) -> Result<Content<Vec<u8>>, NotFound<String>> {
|
||||
dbg!("index called");
|
||||
file("index.html", lib)
|
||||
}
|
||||
|
||||
#[get("/<path..>")]
|
||||
fn path(path: PathBuf, lib: State<Library>) -> Result<Content<Vec<u8>>, NotFound<String>> {
|
||||
dbg!(&path);
|
||||
let path = path.to_str().unwrap();
|
||||
let path = if path.ends_with("/") {
|
||||
format!("{}index.html", path.to_string())
|
||||
} else {
|
||||
path.to_string()
|
||||
};
|
||||
file(&path, lib)
|
||||
}
|
||||
|
||||
fn file(path: &str, lib: State<Library>) -> Result<Content<Vec<u8>>, NotFound<String>> {
|
||||
match Asset::get(path) {
|
||||
Some(bytes) => {
|
||||
dbg!(path);
|
||||
let mime = mime_guess::from_path(path).first_or_octet_stream();
|
||||
let ct = ContentType::parse_flexible(mime.essence_str()).unwrap_or(ContentType::Binary);
|
||||
|
||||
Ok(Content(ct, bytes.into()))
|
||||
}
|
||||
None => Err(NotFound(path.to_string())),
|
||||
}
|
||||
Content(ContentType::HTML, w)
|
||||
}
|
||||
|
||||
pub fn run(addr: SocketAddr, lib: Library) -> Result<(), Box<dyn Error>> {
|
||||
rocket::ignite()
|
||||
let e = rocket::ignite()
|
||||
.manage(lib)
|
||||
.mount("/", routes![index, path])
|
||||
.mount(
|
||||
"/",
|
||||
routes![album, albums, image, embedz, metrics, index, path],
|
||||
)
|
||||
.launch();
|
||||
Ok(())
|
||||
match e.kind() {
|
||||
rocket::error::LaunchErrorKind::Collision(v) => {
|
||||
error!("Route collisions:");
|
||||
for (r1, r2) in v {
|
||||
error!(" R1 {}", r1);
|
||||
error!(" R2 {}", r2);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
return Err(e.into());
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user