Start of rewrite from warp->rocket.

This commit is contained in:
2020-06-20 12:50:22 -07:00
parent a19874fe47
commit 80ef93f20f
9 changed files with 458 additions and 53 deletions

View File

@@ -1,2 +1,7 @@
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
pub mod library;
pub mod web;
pub mod rweb;

View File

@@ -22,21 +22,18 @@ use rocksdb::DB;
const LIBRARY_GENERATION: &'static str = "14";
#[derive(Clone)]
pub struct Library<C>
where
C: Cacher,
{
pub struct Library {
root: PathBuf,
originals_dir: PathBuf,
cache_db: Arc<DB>,
image_cache: C,
image_cache: Arc<Box<dyn Cacher>>,
}
impl<C> Library<C>
where
C: Cacher,
{
pub fn new(root: PathBuf, image_cache: C) -> Result<Library<C>, Box<dyn std::error::Error>> {
impl Library {
pub fn new(
root: PathBuf,
image_cache: Arc<Box<dyn Cacher>>,
) -> Result<Library, Box<dyn std::error::Error>> {
let db = DB::open_default(root.join("cache"))?;
let cache_db = Arc::new(db);
let lib = Library {
@@ -60,7 +57,7 @@ where
}
// Removes all data in the database from older schema.
pub fn clean_db(&self) -> Result<usize, rocksdb::Error> {
Library::<C>::gc(LIBRARY_GENERATION, &self.cache_db)
Library::gc(LIBRARY_GENERATION, &self.cache_db)
}
fn gc(generation: &str, db: &DB) -> Result<usize, rocksdb::Error> {
let gen = format!("{}/", generation);
@@ -193,22 +190,16 @@ where
dimensions: (Option<u32>, Option<u32>),
fill: bool,
) -> Option<Vec<u8>> {
fn cache_key<C: Cacher>(
media_items_id: &str,
dimensions: (Option<u32>, Option<u32>),
) -> String {
fn cache_key(media_items_id: &str, dimensions: (Option<u32>, Option<u32>)) -> String {
let dim = match dimensions {
(Some(w), Some(h)) => format!("-w={}-h={}", w, h),
(Some(w), None) => format!("-w={}", w),
(None, Some(h)) => format!("-h={}", h),
(None, None) => "".to_string(),
};
Library::<C>::generational_key(
LIBRARY_GENERATION,
&format!("{}{}", media_items_id, dim),
)
Library::generational_key(LIBRARY_GENERATION, &format!("{}{}", media_items_id, dim))
}
let key = cache_key::<C>(media_items_id, dimensions);
let key = cache_key(media_items_id, dimensions);
let db = self.cache_db.clone();
match db.get(key.as_bytes()) {
// Cache hit, return bytes as-is.

View File

@@ -2,10 +2,11 @@ use std::collections::HashMap;
use std::error::Error;
use std::net::SocketAddr;
use std::path::PathBuf;
use std::sync::Arc;
use std::thread;
use std::time;
use cacher::S3Cacher;
use cacher::{Cacher, S3Cacher};
use google_api_auth;
use google_photoslibrary1 as photos;
use hexihasher;
@@ -17,7 +18,7 @@ use structopt::StructOpt;
use yup_oauth2::{Authenticator, InstalledFlow};
use photosync::library::Library;
use photosync::web;
use photosync::rweb;
fn parse_duration(src: &str) -> Result<time::Duration, std::num::ParseIntError> {
let secs = str::parse::<u64>(src)?;
@@ -310,7 +311,7 @@ fn background_sync(
}
pub fn serve(addr: SocketAddr, lib: Library) -> Result<(), Box<dyn Error>> {
web::run(addr, lib)
rweb::run(addr, lib)
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
@@ -321,7 +322,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.init()
.unwrap();
debug!("opt: {:?}", opt);
let image_cache = S3Cacher::new("photosync")?;
let image_cache: Box<dyn Cacher> = Box::new(S3Cacher::new("photosync".to_string())?);
let image_cache = Arc::new(image_cache);
match opt.cmd {
Command::ListAlbums { auth, title_filter } => {
let client = new_client(&auth.credentials, &auth.token_cache)?;

79
src/rweb.rs Normal file
View File

@@ -0,0 +1,79 @@
use std::error::Error;
use std::net::SocketAddr;
use std::path::PathBuf;
use cacher::Cacher;
use rocket::http::ContentType;
use rocket::response::content::Html;
use rocket::response::status::NotFound;
use rocket::response::Content;
use rocket::{Request, State};
use rust_embed::RustEmbed;
use crate::library::Library;
#[derive(RustEmbed)]
#[folder = "react-slideshow/build/"]
struct Asset;
/*
fn embedz() -> Result<impl warp::Reply, warp::Rejection> {
let mut w = Vec::new();
write!(
w,
r#"<html><table><tbody><tr><th>size</th><th style="text-align: left;">path</th></tr>"#
)
.unwrap();
for path in Asset::iter() {
write!(
w,
r#"<tr><td style="text-align: right;">{0}</td><td><a href="{1}">{1}</a></td</tr>"#,
Asset::get(&path).unwrap().len(),
path
)
.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())),
}
}
pub fn run(addr: SocketAddr, lib: Library) -> Result<(), Box<dyn Error>> {
rocket::ignite()
.manage(lib)
.mount("/", routes![index, path])
.launch();
Ok(())
}

View File

@@ -54,7 +54,7 @@ fn index(path: warp::path::FullPath) -> Result<impl warp::Reply, warp::Rejection
}
}
fn albums<C: Cacher>(lib: Library<C>) -> Result<impl warp::Reply, warp::Rejection> {
fn albums(lib: Library) -> Result<impl warp::Reply, warp::Rejection> {
let albums = lib.albums().map_err(|e| {
warn!("Couldn't find albums: {}", e);
warp::reject::not_found()
@@ -62,7 +62,7 @@ fn albums<C: Cacher>(lib: Library<C>) -> Result<impl warp::Reply, warp::Rejectio
Ok(warp::reply::json(&albums))
}
fn album<C: Cacher>(lib: Library<C>, id: String) -> Result<impl warp::Reply, warp::Rejection> {
fn album(lib: Library, id: String) -> Result<impl warp::Reply, warp::Rejection> {
let album = lib.album(&id).map_err(|e| {
warn!("Couldn't find album {}: {}", id, e);
warp::reject::not_found()
@@ -77,8 +77,8 @@ struct ImageParams {
fill: Option<bool>,
}
fn image<C: Cacher>(
lib: Library<C>,
fn image(
lib: Library,
media_items_id: String,
params: ImageParams,
) -> Result<impl warp::Reply, warp::Rejection> {
@@ -123,24 +123,24 @@ fn embedz() -> Result<impl warp::Reply, warp::Rejection> {
.body(w))
}
pub fn run<C: Cacher>(addr: SocketAddr, lib: Library<C>) -> Result<(), Box<dyn Error>> {
pub fn run(addr: SocketAddr, lib: Library) -> Result<(), Box<dyn Error>> {
let lib = warp::any().map(move || lib.clone());
let index = warp::get2().and(warp::path::full()).and_then(index);
let albums = warp::path("albums").and(lib.clone()).and_then(index);
let albums = warp::path("albums").and(lib.clone()).and_then(albums);
let embedz = warp::path("embedz").and_then(embedz);
let album = warp::path("album")
.and(lib.clone())
.and(warp::path::param())
.and_then(index);
.and_then(album);
let image = warp::path("image")
.and(lib.clone())
.and(warp::path::param())
.and(warp::query::<ImageParams>())
.and_then(index);
.and_then(image);
let api = albums.or(album).or(image);
let api = warp::path("api").and(api);