album/src/main.rs

138 lines
4.4 KiB
Rust
Raw Normal View History

#[macro_use] extern crate nickel;
2015-11-21 18:21:44 +03:00
#[macro_use] extern crate log;
extern crate env_logger;
2015-11-21 18:21:44 +03:00
extern crate rustorm;
extern crate rustc_serialize;
2015-11-22 15:01:39 +03:00
extern crate typemap;
extern crate plugin;
extern crate image;
extern crate hyper;
extern crate time;
2015-11-22 15:01:39 +03:00
use time::Duration;
use hyper::header::{Expires, HttpDate};
use std::collections::HashMap;
2015-11-22 15:01:39 +03:00
use nickel::{Nickel, Request, Response, Middleware, Continue, MiddlewareResult};
use rustorm::pool::{ManagedPool,Platform};
use rustorm::database::Database;
use rustorm::table::IsTable;
use rustorm::dao::{IsDao, ToValue};
2015-11-21 18:21:44 +03:00
use std::env::var;
use std::process::exit;
2015-11-22 15:01:39 +03:00
use typemap::Key;
use plugin::{Pluggable, Extensible};
use image::open as image_open;
use image::{FilterType, GenericImage, ImageFormat};
use nickel::mimes::MediaType;
2015-11-21 18:21:44 +03:00
mod models;
use models::{Photo, query_for};
fn dburl() -> String {
let db_var = "RPHOTOS_DB";
match var(db_var) {
Ok(result) => result,
Err(error) => {
println!("A database url needs to be given in env {}: {}",
db_var, error);
exit(1);
}
}
}
2015-11-22 15:01:39 +03:00
struct RustormMiddleware {
pool: ManagedPool
}
impl RustormMiddleware {
pub fn new(db_url: &str) -> RustormMiddleware {
RustormMiddleware {
pool: ManagedPool::init(db_url, 5).unwrap(),
}
}
}
impl Key for RustormMiddleware { type Value = Platform; }
impl<D> Middleware<D> for RustormMiddleware {
fn invoke<'mw, 'conn>(&self, req: &mut Request<'mw, 'conn, D>, res: Response<'mw, D>) -> MiddlewareResult<'mw, D> {
req.extensions_mut().insert::<RustormMiddleware>(
self.pool.connect().unwrap());
Ok(Continue(res))
}
}
pub trait RustormRequestExtensions {
fn db_conn(&self) -> &Database;
fn orm_get<T: IsTable + IsDao>(&self, key: &str, val: &ToValue) -> T;
}
impl<'a, 'b, D> RustormRequestExtensions for Request<'a, 'b, D> {
fn db_conn(&self) -> &Database {
self.extensions().get::<RustormMiddleware>().unwrap().as_ref()
}
fn orm_get<T: IsTable + IsDao>(&self, key: &str, val: &ToValue) -> T {
query_for::<T>().filter_eq(key, val)
.collect_one(self.db_conn()).unwrap()
}
}
fn get_scaled_image(photo: Photo, width: u32, height: u32) -> Vec<u8> {
let path = format!("/home/kaj/Bilder/foto/{}", photo.path);
info!("Should open {}", path);
let img = image_open(path).unwrap();
let scaled = img.resize(width, height, FilterType::Nearest);
// TODO Put the icon in some kind of cache!
let mut buf : Vec<u8> = Vec::new();
scaled.save(&mut buf, ImageFormat::JPEG).unwrap();
buf
}
fn main() {
env_logger::init().unwrap();
2015-11-21 18:21:44 +03:00
info!("Initalized logger");
// NOTE pool will need to be mut if we do db writes?
2015-11-22 15:01:39 +03:00
// let pool = ManagedPool::init(&dburl(), 1).unwrap();
2015-11-21 18:21:44 +03:00
info!("Initalized pool");
let mut server = Nickel::new();
2015-11-22 15:01:39 +03:00
server.utilize(RustormMiddleware::new(&dburl()));
server.utilize(router! {
2015-11-22 15:01:39 +03:00
get "/" => |req, res| {
2015-11-21 18:21:44 +03:00
let photos: Vec<Photo> = query_for::<Photo>()
2015-11-22 15:01:39 +03:00
.collect(req.db_conn()).unwrap();
2015-11-21 18:21:44 +03:00
info!("Got some photos: {:?}", photos);
let mut data = HashMap::new();
2015-11-21 18:21:44 +03:00
data.insert("photos", &photos);
// data.insert("name", "Self".into());
return res.render("templates/index.tpl", &data);
}
2015-11-22 15:01:39 +03:00
get "/details/:id" => |req, res| {
let id = req.param("id").unwrap().parse::<i32>().unwrap();
let photo = req.orm_get::<Photo>("id", &id);
let mut data = HashMap::new();
data.insert("photo", &photo);
return res.render("templates/details.tpl", &data);
}
get "/icon/:id" => |req, mut res| {
let id = req.param("id").unwrap().parse::<i32>().unwrap();
let photo = req.orm_get::<Photo>("id", &id);
let buf = get_scaled_image(photo, 200, 180);
res.set(MediaType::Jpeg);
res.set(Expires(HttpDate(time::now() + Duration::days(14))));
return res.send(buf);
}
get "/view/:id" => |req, mut res| {
let id = req.param("id").unwrap().parse::<i32>().unwrap();
let photo = req.orm_get::<Photo>("id", &id);
let buf = get_scaled_image(photo, 800, 600);
res.set(MediaType::Jpeg);
res.set(Expires(HttpDate(time::now() + Duration::days(14))));
return res.send(buf);
}
});
server.listen("127.0.0.1:6767");
}