Implement album index and image resize.
This commit is contained in:
@@ -53,6 +53,12 @@ impl Library {
|
||||
info!("saving {}", path.to_string_lossy());
|
||||
fs::write(path, j)
|
||||
}
|
||||
pub fn albums(&self) -> Result<Vec<Album>, Box<dyn std::error::Error>> {
|
||||
let albums_path = self.root.join("albums.json");
|
||||
info!("loading {}", albums_path.to_string_lossy());
|
||||
let bytes = fs::read(albums_path)?;
|
||||
Ok(serde_json::from_slice(&bytes)?)
|
||||
}
|
||||
pub fn album(&self, album_id: &str) -> Result<Vec<MediaItem>, Box<dyn std::error::Error>> {
|
||||
let album_path = self.root.join(album_id).join("album.json");
|
||||
let bytes = fs::read(album_path)?;
|
||||
@@ -88,4 +94,12 @@ impl Library {
|
||||
}
|
||||
Ok(image_path)
|
||||
}
|
||||
pub fn original(&self, media_items_id: &str) -> Option<PathBuf> {
|
||||
let path = self.originals_dir.join(media_items_id);
|
||||
if path.exists() {
|
||||
Some(path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,6 +197,7 @@ fn sync_albums(
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let lib = Library::new(output_dir)?;
|
||||
let albums = list_albums(client, title_filter)?;
|
||||
info!("albums {:?}", albums);
|
||||
lib.create_album_index(&albums)?;
|
||||
for a in &albums {
|
||||
let album_id = a.id.as_ref().expect("unset album id").to_string();
|
||||
|
||||
59
src/web.rs
59
src/web.rs
@@ -2,6 +2,7 @@ use std::error::Error;
|
||||
use std::net::SocketAddr;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use log::info;
|
||||
use log::warn;
|
||||
use prometheus::Encoder;
|
||||
use serde::Deserialize;
|
||||
@@ -34,6 +35,14 @@ fn index() -> Result<impl warp::Reply, warp::Rejection> {
|
||||
Ok("Hello world")
|
||||
}
|
||||
|
||||
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()
|
||||
})?;
|
||||
Ok(warp::reply::json(&albums))
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -44,17 +53,53 @@ fn album(lib: Library, id: String) -> Result<impl warp::Reply, warp::Rejection>
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct ImageParams {
|
||||
w: Option<usize>,
|
||||
h: Option<usize>,
|
||||
w: Option<u32>,
|
||||
h: Option<u32>,
|
||||
c: Option<bool>,
|
||||
}
|
||||
|
||||
fn image(
|
||||
lib: Library,
|
||||
image_id: String,
|
||||
media_items_id: String,
|
||||
params: ImageParams,
|
||||
) -> Result<impl warp::Reply, warp::Rejection> {
|
||||
Ok(format!("Hello world: {} {:?}", image_id, params))
|
||||
info!("image_id {} params {:?}", media_items_id, params);
|
||||
|
||||
match lib.original(&media_items_id) {
|
||||
None => {
|
||||
warn!("Couldn't find original {}", &media_items_id);
|
||||
Err(warp::reject::not_found())
|
||||
}
|
||||
Some(path) => {
|
||||
let orig_img = image::io::Reader::open(&path)
|
||||
.map_err(|e| {
|
||||
warn!("Couldn't open {}: {}", path.to_string_lossy(), e);
|
||||
warp::reject::not_found()
|
||||
})?
|
||||
.with_guessed_format()
|
||||
.map_err(|e| {
|
||||
warn!("Couldn't guess format {}: {}", path.to_string_lossy(), e);
|
||||
warp::reject::not_found()
|
||||
})?
|
||||
.decode()
|
||||
.map_err(|e| {
|
||||
warn!("Couldn't decode {}: {}", path.to_string_lossy(), e);
|
||||
warp::reject::not_found()
|
||||
})?;
|
||||
let img = orig_img.resize(
|
||||
params.w.unwrap_or(0),
|
||||
params.h.unwrap_or(0),
|
||||
image::imageops::FilterType::CatmullRom,
|
||||
);
|
||||
let mut buf = Vec::new();
|
||||
img.write_to(&mut buf, image::ImageFormat::Jpeg)
|
||||
.map_err(|e| {
|
||||
warn!("Couldn't write_to {}: {}", path.to_string_lossy(), e);
|
||||
warp::reject::not_found()
|
||||
})?;
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(addr: SocketAddr, root: PathBuf) -> Result<(), Box<dyn Error>> {
|
||||
@@ -62,18 +107,20 @@ pub fn run(addr: SocketAddr, root: PathBuf) -> Result<(), Box<dyn Error>> {
|
||||
let lib = warp::any().map(move || lib.clone());
|
||||
let index = warp::path::end().and_then(index);
|
||||
|
||||
// TODO(wathiede): implement album index
|
||||
let albums = warp::path("albums").and(lib.clone()).and_then(albums);
|
||||
|
||||
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 = albums.or(album).or(image);
|
||||
let api = warp::path("api").and(api);
|
||||
|
||||
// Fallback, always keep this last.
|
||||
|
||||
Reference in New Issue
Block a user