album/src/main.rs

241 lines
9.1 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-12-22 20:22:21 +03:00
extern crate chrono;
2016-01-31 16:34:48 +03:00
extern crate rexif;
2015-12-25 20:32:11 +03:00
use chrono::UTC;
use chrono::offset::TimeZone;
use chrono::{Duration as ChDuration};
use chrono::Datelike;
2015-11-22 15:01:39 +03:00
use hyper::header::{Expires, HttpDate};
use nickel::{MediaType, Nickel, StaticFilesHandler};
use plugin::{Pluggable};
use rustc_serialize::Encodable;
2015-12-22 20:22:21 +03:00
use rustorm::query::Query;
use time::Duration;
2015-11-21 18:21:44 +03:00
2015-12-25 20:32:11 +03:00
mod models;
use models::{Entity, Photo, Tag, Person, Place, query_for};
mod env;
2015-12-07 01:00:05 +03:00
use env::{dburl, env_or, photos_dir};
2015-11-21 18:21:44 +03:00
2015-12-26 22:18:44 +03:00
mod photosdir;
use photosdir::PhotosDir;
mod rustormmiddleware;
use rustormmiddleware::{RustormMiddleware, RustormRequestExtensions};
mod requestloggermiddleware;
use requestloggermiddleware::RequestLoggerMiddleware;
macro_rules! render {
($res:expr, $template:expr, { $($param:ident : $ptype:ty = $value:expr),* })
=>
{
{
#[derive(Debug, Clone, RustcEncodable)]
struct ParamData {
$(
$param: $ptype,
)*
}
$res.render($template, &ParamData {
$(
$param: $value,
)*
})
}
}
}
2015-12-22 20:22:21 +03:00
fn orm_get_related<T: Entity, Src: Entity>(src: &Src, rel_table: &str)
-> Query
{
let mut q = Query::select();
q.only_from(&T::table());
q.left_join_table(rel_table, &format!("{}.id", T::table().name),
&format!("{}.{}", rel_table, T::table().name))
.filter_eq(&format!("{}.{}", rel_table, Src::table().name), src.id());
q
}
fn main() {
env_logger::init().unwrap();
2015-11-21 18:21:44 +03:00
info!("Initalized logger");
2015-12-07 01:00:05 +03:00
let photos = PhotosDir::new(photos_dir());
let mut server = Nickel::new();
server.utilize(RequestLoggerMiddleware);
2015-11-27 01:20:36 +03:00
server.utilize(StaticFilesHandler::new("static/"));
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| {
return render!(res, "templates/index.tpl", {
photos: Vec<Photo> = query_for::<Photo>()
2015-12-22 20:22:21 +03:00
.desc_nulls_last("grade")
.desc_nulls_last("date")
.limit(24)
.collect(req.db_conn()).unwrap()
});
}
2015-11-22 15:01:39 +03:00
get "/details/:id" => |req, res| {
if let Ok(id) = req.param("id").unwrap().parse::<i32>() {
if let Ok(photo) = req.orm_get::<Photo>("id", &id) {
return render!(res, "templates/details.tpl", {
people: Vec<Person> =
req.orm_get_related(&photo, "photo_person").unwrap(),
places: Vec<Place> =
req.orm_get_related(&photo, "photo_place").unwrap(),
tags: Vec<Tag> =
req.orm_get_related(&photo, "photo_tag").unwrap(),
2015-12-25 20:32:11 +03:00
time: String = match photo.date {
Some(d) => d.format("%T").to_string(),
None => "".to_string()
},
year: i32 = match photo.date {
Some(d) => d.year(),
None => 0
},
month: u32 = match photo.date {
Some(d) => d.month(),
None => 0
},
day: u32 = match photo.date {
Some(d) => d.day(),
None => 0
},
photo: Photo = photo
});
}
}
}
2015-11-27 02:02:18 +03:00
get "/tag/" => |req, res| {
return render!(res, "templates/tags.tpl", {
tags: Vec<Tag> = query_for::<Tag>().asc("tag")
.collect(req.db_conn()).unwrap()
});
2015-11-27 02:02:18 +03:00
}
get "/tag/:tag" => |req, res| {
let slug = req.param("tag").unwrap();
if let Ok(tag) = req.orm_get::<Tag>("slug", &slug) {
return render!(res, "templates/tag.tpl", {
photos: Vec<Photo> =
req.orm_get_related(&tag, "photo_tag").unwrap(),
tag: Tag = tag
2015-11-28 11:53:12 +03:00
});
}
}
get "/person/" => |req, res| {
return render!(res, "templates/people.tpl", {
people: Vec<Person> = query_for::<Person>().asc("name")
.collect(req.db_conn()).unwrap()
});
2015-11-28 11:53:12 +03:00
}
get "/person/:slug" => |req, res| {
let slug = req.param("slug").unwrap();
if let Ok(person) = req.orm_get::<Person>("slug", &slug) {
return render!(res, "templates/person.tpl", {
photos: Vec<Photo> =
2015-12-22 20:22:21 +03:00
orm_get_related::<Photo, Person>(&person, "photo_person")
.desc_nulls_last("grade")
.desc_nulls_last("date")
.collect(req.db_conn()).unwrap(),
person: Person = person
});
}
}
get "/place/" => |req, res| {
return render!(res, "templates/places.tpl", {
places: Vec<Place> = query_for::<Place>().asc("place")
.collect(req.db_conn()).unwrap()
});
}
get "/place/:slug" => |req, res| {
let slug = req.param("slug").unwrap();
if let Ok(place) = req.orm_get::<Place>("slug", &slug) {
return render!(res, "templates/place.tpl", {
photos: Vec<Photo> =
req.orm_get_related(&place, "photo_place").unwrap(),
place: Place = place
});
}
2015-11-22 15:01:39 +03:00
}
2015-12-06 16:42:03 +03:00
get "/img/:id/:size" => |req, mut res| {
if let Ok(id) = req.param("id").unwrap().parse::<i32>() {
if let Ok(photo) = req.orm_get::<Photo>("id", &id) {
2015-12-06 16:42:03 +03:00
if let Some(size) = match req.param("size").unwrap() {
"s" => Some(200),
"m" => Some(800),
"l" => Some(1200),
_ => None
} {
let buf = photos.get_scaled_image(photo, size, size);
2015-12-06 16:42:03 +03:00
res.set(MediaType::Jpeg);
res.set(Expires(HttpDate(time::now() + Duration::days(14))));
return res.send(buf);
}
}
}
2015-11-22 15:01:39 +03:00
}
2015-12-25 20:32:11 +03:00
get "/:year/" => |req, res| {
if let Ok(year) = req.param("year").unwrap().parse::<i32>() {
let date = UTC.ymd(year, 1, 1).and_hms(0,0,0);
return render!(res, "templates/index.tpl", {
photos: Vec<Photo> = query_for::<Photo>()
.filter_gte("date", &date)
.filter_lt("date", &(date + ChDuration::days(366)))
.desc_nulls_last("grade")
.asc_nulls_last("date")
.limit(36)
.collect(req.db_conn()).unwrap()
});
}
}
get "/:year/:month/" => |req, res| {
if let Ok(year) = req.param("year").unwrap().parse::<i32>() {
if let Ok(month) = req.param("month").unwrap().parse::<u32>() {
let date = UTC.ymd(year, month, 1).and_hms(0,0,0);
return render!(res, "templates/index.tpl", {
photos: Vec<Photo> = query_for::<Photo>()
.filter_gte("date", &date)
.filter_lt("date", &(date + ChDuration::days(31)))
.desc_nulls_last("grade")
.asc_nulls_last("date")
.limit(36)
.collect(req.db_conn()).unwrap()
});
}
}
}
get "/:year/:month/:day" => |req, res| {
if let Ok(year) = req.param("year").unwrap().parse::<i32>() {
if let Ok(month) = req.param("month").unwrap().parse::<u32>() {
if let Ok(day) = req.param("day").unwrap().parse::<u32>() {
let date = UTC.ymd(year, month, day).and_hms(0,0,0);
return render!(res, "templates/index.tpl", {
photos: Vec<Photo> = query_for::<Photo>()
.filter_gte("date", &date)
.filter_lt("date", &(date + ChDuration::days(1)))
.desc_nulls_last("grade")
.asc_nulls_last("date")
.collect(req.db_conn()).unwrap()
});
}
}
}
}
});
server.listen(&*env_or("RPHOTOS_LISTEN", "127.0.0.1:6767"));
}