This commit is contained in:
Rasmus Kaj 2018-07-05 23:28:57 +02:00
parent 96a5a07ce7
commit 20c72d5ef3
18 changed files with 97 additions and 201 deletions

View File

@ -17,4 +17,4 @@ matrix:
before_script: before_script:
- rustup component add rustfmt-preview - rustup component add rustfmt-preview
script: script:
- cargo fmt -- --unstable-features --write-mode=diff - cargo fmt -- --check

View File

@ -1,6 +1,4 @@
max_width = 79 max_width = 79
reorder_imported_names = true
reorder_imports = true reorder_imports = true
report_fixme = "Always" report_fixme = "Always"
write_mode = "Diff"

View File

@ -12,16 +12,12 @@ pub fn crawl(
photos: &PhotosDir, photos: &PhotosDir,
only_in: &Path, only_in: &Path,
) -> Result<(), Error> { ) -> Result<(), Error> {
Ok( Ok(photos.find_files(only_in, &|path, exif| match save_photo(
photos.find_files(only_in, &|path, exif| match save_photo( db, path, exif,
db,
path,
exif,
) { ) {
Ok(()) => debug!("Saved photo {}", path), Ok(()) => debug!("Saved photo {}", path),
Err(e) => warn!("Failed to save photo {}: {:?}", path, e), Err(e) => warn!("Failed to save photo {}: {:?}", path, e),
})?, })?)
)
} }
fn save_photo( fn save_photo(
@ -29,14 +25,12 @@ fn save_photo(
file_path: &str, file_path: &str,
exif: &ExifData, exif: &ExifData,
) -> Result<(), Error> { ) -> Result<(), Error> {
let width = exif.width.ok_or(Error::Other(format!( let width = exif
"Image {} missing width", .width
file_path, .ok_or(Error::Other(format!("Image {} missing width", file_path,)))?;
)))?; let height = exif
let height = exif.height.ok_or(Error::Other(format!( .height
"Image {} missing height", .ok_or(Error::Other(format!("Image {} missing height", file_path,)))?;
file_path,
)))?;
let photo = match Photo::create_or_set_basics( let photo = match Photo::create_or_set_basics(
db, db,
file_path, file_path,

View File

@ -16,10 +16,9 @@ pub fn one(db: &PgConnection, tpath: &str) -> Result<(), Error> {
println!("Made {} public: {:?}", tpath, photo); println!("Made {} public: {:?}", tpath, photo);
Ok(()) Ok(())
} }
Err(DieselError::NotFound) => Err(Error::Other(format!( Err(DieselError::NotFound) => {
"File {} is not known", Err(Error::Other(format!("File {} is not known", tpath,)))
tpath, }
))),
Err(error) => Err(error.into()), Err(error) => Err(error.into()),
} }
} }

View File

@ -1,8 +1,8 @@
use adm::result::Error; use adm::result::Error;
use diesel::pg::PgConnection; use diesel::pg::PgConnection;
use diesel::prelude::*; use diesel::prelude::*;
use memcached::Client;
use memcached::proto::{Operation, ProtoType}; use memcached::proto::{Operation, ProtoType};
use memcached::Client;
use models::Photo; use models::Photo;
use photosdir::PhotosDir; use photosdir::PhotosDir;
use schema::photos::dsl::{date, is_public}; use schema::photos::dsl::{date, is_public};
@ -15,10 +15,8 @@ use server::SizeTag;
/// The images are handled in public first, new first order, to have /// The images are handled in public first, new first order, to have
/// the probably most requested images precached as soon as possible. /// the probably most requested images precached as soon as possible.
pub fn precache(db: &PgConnection, pd: &PhotosDir) -> Result<(), Error> { pub fn precache(db: &PgConnection, pd: &PhotosDir) -> Result<(), Error> {
let mut cache = Client::connect( let mut cache =
&[("tcp://127.0.0.1:11211", 1)], Client::connect(&[("tcp://127.0.0.1:11211", 1)], ProtoType::Binary)?;
ProtoType::Binary,
)?;
let size = SizeTag::Small; let size = SizeTag::Small;
let (mut n, mut n_stored) = (0, 0); let (mut n, mut n_stored) = (0, 0);
let photos = Photo::query(true) let photos = Photo::query(true)
@ -32,8 +30,7 @@ pub fn precache(db: &PgConnection, pd: &PhotosDir) -> Result<(), Error> {
debug!("Cache: {} found for {}", key, photo.path); debug!("Cache: {} found for {}", key, photo.path);
} else { } else {
let size = size.px(); let size = size.px();
let data = pd.scale_image(&photo, size, size) let data = pd.scale_image(&photo, size, size).map_err(|e| {
.map_err(|e| {
Error::Other(format!( Error::Other(format!(
"Failed to scale #{} ({}): {}", "Failed to scale #{} ({}): {}",
photo.id, photo.path, e, photo.id, photo.path, e,
@ -43,10 +40,7 @@ pub fn precache(db: &PgConnection, pd: &PhotosDir) -> Result<(), Error> {
debug!("Cache: stored {} for {}", key, photo.path); debug!("Cache: stored {} for {}", key, photo.path);
n_stored += 1; n_stored += 1;
if n_stored % 64 == 0 { if n_stored % 64 == 0 {
info!( info!("{} images of {} updated in cache ...", n_stored, n);
"{} images of {} updated in cache ...",
n_stored, n
);
} }
} }
} }

View File

@ -3,8 +3,8 @@ use diesel::pg::PgConnection;
use diesel::prelude::*; use diesel::prelude::*;
use diesel::{insert_into, update}; use diesel::{insert_into, update};
use djangohashers::make_password; use djangohashers::make_password;
use rand::distributions::IndependentSample;
use rand::distributions::range::Range; use rand::distributions::range::Range;
use rand::distributions::IndependentSample;
use rand::os::OsRng; use rand::os::OsRng;
use std::iter::Iterator; use std::iter::Iterator;
@ -26,19 +26,13 @@ pub fn passwd(db: &PgConnection, uname: &str) -> Result<(), Error> {
.execute(db)? .execute(db)?
{ {
1 => { 1 => {
println!( println!("Updated password for {:?} to {:?}", uname, pword);
"Updated password for {:?} to {:?}",
uname, pword
);
} }
0 => { 0 => {
insert_into(users) insert_into(users)
.values((username.eq(uname), password.eq(&hashword))) .values((username.eq(uname), password.eq(&hashword)))
.execute(db)?; .execute(db)?;
println!( println!("Created user {:?} with password {:?}", uname, pword);
"Created user {:?} with password {:?}",
uname, pword
);
} }
n => { n => {
println!( println!(

View File

@ -9,12 +9,8 @@ fn main() {
let base_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); let base_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let mut statics = StaticFiles::new(&out_dir).unwrap(); let mut statics = StaticFiles::new(&out_dir).unwrap();
let s_dir = base_dir.join("res"); let s_dir = base_dir.join("res");
statics statics.add_sass_file(&s_dir.join("photos.scss")).unwrap();
.add_sass_file(&s_dir.join("photos.scss")) statics.add_file(&s_dir.join("admin.js")).unwrap();
.unwrap();
statics
.add_file(&s_dir.join("admin.js"))
.unwrap();
statics.add_file(&s_dir.join("ux.js")).unwrap(); statics.add_file(&s_dir.join("ux.js")).unwrap();
statics statics
.add_files_as(&s_dir.join("leaflet-1.3.1"), "l131") .add_files_as(&s_dir.join("leaflet-1.3.1"), "l131")

View File

@ -196,10 +196,7 @@ fn run(args: &ArgMatches) -> Result<(), Error> {
storestatics::to_dir(args.value_of("DIR").unwrap()) storestatics::to_dir(args.value_of("DIR").unwrap())
} }
("runserver", Some(args)) => server::run(args), ("runserver", Some(args)) => server::run(args),
_ => Ok(println!( _ => Ok(println!("No subcommand given.\n\n{}", args.usage())),
"No subcommand given.\n\n{}",
args.usage()
)),
} }
} }

View File

@ -1,5 +1,5 @@
use memcached::Client;
use memcached::proto::{Error as MprotError, Operation, ProtoType}; use memcached::proto::{Error as MprotError, Operation, ProtoType};
use memcached::Client;
use nickel::{Continue, Middleware, MiddlewareResult, Request, Response}; use nickel::{Continue, Middleware, MiddlewareResult, Request, Response};
use plugin::Extensible; use plugin::Extensible;
use std::convert::From; use std::convert::From;

View File

@ -116,12 +116,7 @@ impl Photo {
use diesel::prelude::*; use diesel::prelude::*;
use schema::photos::dsl::*; use schema::photos::dsl::*;
if let Some(result) = Self::update_by_path( if let Some(result) = Self::update_by_path(
db, db, file_path, newwidth, newheight, exifdate, &camera,
file_path,
newwidth,
newheight,
exifdate,
&camera,
)? { )? {
Ok(result) Ok(result)
} else { } else {
@ -146,13 +141,9 @@ impl Photo {
use schema::people::dsl::{id, people}; use schema::people::dsl::{id, people};
use schema::photo_people::dsl::{person_id, photo_id, photo_people}; use schema::photo_people::dsl::{person_id, photo_id, photo_people};
people people
.filter( .filter(id.eq_any(
id.eq_any( photo_people.select(person_id).filter(photo_id.eq(self.id)),
photo_people ))
.select(person_id)
.filter(photo_id.eq(self.id)),
),
)
.load(db) .load(db)
} }
@ -163,13 +154,9 @@ impl Photo {
use schema::photo_places::dsl::{photo_id, photo_places, place_id}; use schema::photo_places::dsl::{photo_id, photo_places, place_id};
use schema::places::dsl::{id, places}; use schema::places::dsl::{id, places};
places places
.filter( .filter(id.eq_any(
id.eq_any( photo_places.select(place_id).filter(photo_id.eq(self.id)),
photo_places ))
.select(place_id)
.filter(photo_id.eq(self.id)),
),
)
.load(db) .load(db)
} }
pub fn load_tags( pub fn load_tags(
@ -179,11 +166,7 @@ impl Photo {
use schema::photo_tags::dsl::{photo_id, photo_tags, tag_id}; use schema::photo_tags::dsl::{photo_id, photo_tags, tag_id};
use schema::tags::dsl::{id, tags}; use schema::tags::dsl::{id, tags};
tags.filter( tags.filter(
id.eq_any( id.eq_any(photo_tags.select(tag_id).filter(photo_id.eq(self.id))),
photo_tags
.select(tag_id)
.filter(photo_id.eq(self.id)),
),
).load(db) ).load(db)
} }
@ -212,8 +195,7 @@ impl Photo {
} }
pub fn load_camera(&self, db: &PgConnection) -> Option<Camera> { pub fn load_camera(&self, db: &PgConnection) -> Option<Camera> {
use schema::cameras::dsl::cameras; use schema::cameras::dsl::cameras;
self.camera_id self.camera_id.and_then(|i| cameras.find(i).first(db).ok())
.and_then(|i| cameras.find(i).first(db).ok())
} }
pub fn get_size(&self, max_size: u32) -> Option<(u32, u32)> { pub fn get_size(&self, max_size: u32) -> Option<(u32, u32)> {
if let (Some(width), Some(height)) = (self.width, self.height) { if let (Some(width), Some(height)) = (self.width, self.height) {

View File

@ -82,13 +82,11 @@ impl ExifData {
// possibly utc, instead. // possibly utc, instead.
if let (&Some(date), &Some((h, m, s))) = (&self.gpsdate, &self.gpstime) if let (&Some(date), &Some((h, m, s))) = (&self.gpsdate, &self.gpstime)
{ {
let naive = date.and_hms(h as u32, m as u32, s as u32) let naive = date
.and_hms(h as u32, m as u32, s as u32)
.with_timezone(&Local) .with_timezone(&Local)
.naive_local(); .naive_local();
debug!( debug!("GPS Date {}, {}:{}:{} => {}", date, h, m, s, naive);
"GPS Date {}, {}:{}:{} => {}",
date, h, m, s, naive
);
Some(naive) Some(naive)
} else if let Some(date) = self.dateval { } else if let Some(date) = self.dateval {
Some(date) Some(date)
@ -175,10 +173,7 @@ fn is_datetime(f: &Field, tag: &Tag) -> Option<NaiveDateTime> {
match single_datetime(&f.value) { match single_datetime(&f.value) {
Ok(date) => Some(date), Ok(date) => Some(date),
Err(err) => { Err(err) => {
println!( println!("ERROR: Expected datetime for {}: {:?}", tag, err);
"ERROR: Expected datetime for {}: {:?}",
tag, err
);
None None
} }
} }
@ -205,7 +200,9 @@ fn is_time(f: &Field, tag: &Tag) -> Option<(u8, u8, u8)> {
if f.tag == *tag { if f.tag == *tag {
match &f.value { match &f.value {
&Value::Rational(ref v) &Value::Rational(ref v)
if v.len() == 3 && v[0].denom == 1 && v[1].denom == 1 if v.len() == 3
&& v[0].denom == 1
&& v[1].denom == 1
&& v[2].denom == 1 => && v[2].denom == 1 =>
{ {
Some((v[0].num as u8, v[1].num as u8, v[2].num as u8)) Some((v[0].num as u8, v[1].num as u8, v[2].num as u8))

View File

@ -37,10 +37,7 @@ impl PhotosDir {
_x @ 135...224 => img.rotate180(), _x @ 135...224 => img.rotate180(),
_x @ 225...314 => img.rotate270(), _x @ 225...314 => img.rotate270(),
x => { x => {
warn!( warn!("Should rotate photo {} deg, which is unsupported", x);
"Should rotate photo {} deg, which is unsupported",
x
);
img img
} }
}; };

View File

@ -36,8 +36,6 @@ pub trait PhotosDirRequestExtensions {
impl<'a, 'b, D> PhotosDirRequestExtensions for Request<'a, 'b, D> { impl<'a, 'b, D> PhotosDirRequestExtensions for Request<'a, 'b, D> {
fn photos(&self) -> &PhotosDir { fn photos(&self) -> &PhotosDir {
self.extensions() self.extensions().get::<PhotosDirMiddleware>().unwrap()
.get::<PhotosDirMiddleware>()
.unwrap()
} }
} }

View File

@ -65,11 +65,9 @@ impl<D> Middleware<D> for RequestLoggerMiddleware {
) -> MiddlewareResult<'mw, D> { ) -> MiddlewareResult<'mw, D> {
let mu = format!("{} {}", req.origin.method, req.origin.uri); let mu = format!("{} {}", req.origin.method, req.origin.uri);
let status = Arc::new(Mutex::new(StatusCode::Continue)); let status = Arc::new(Mutex::new(StatusCode::Continue));
req.extensions_mut() req.extensions_mut().insert::<RequestLoggerMiddleware>(
.insert::<RequestLoggerMiddleware>(RequestLogger::new( RequestLogger::new(mu, Arc::clone(&status)),
mu, );
Arc::clone(&status),
));
res.on_send(move |r| { res.on_send(move |r| {
if let Ok(mut sw) = status.lock() { if let Ok(mut sw) = status.lock() {
*sw = r.status(); *sw = r.status();

View File

@ -24,10 +24,7 @@ pub fn rotate<'mw>(
let c: &PgConnection = &req.db_conn(); let c: &PgConnection = &req.db_conn();
if let Ok(mut image) = photos.find(image).first::<Photo>(c) { if let Ok(mut image) = photos.find(image).first::<Photo>(c) {
let newvalue = (360 + image.rotation + angle) % 360; let newvalue = (360 + image.rotation + angle) % 360;
info!( info!("Rotation was {}, setting to {}", image.rotation, newvalue);
"Rotation was {}, setting to {}",
image.rotation, newvalue
);
image.rotation = newvalue; image.rotation = newvalue;
match image.save_changes::<Photo>(c) { match image.save_changes::<Photo>(c) {
Ok(image) => { Ok(image) => {
@ -177,23 +174,14 @@ pub fn set_grade<'mw>(
} }
Ok(0) => (), Ok(0) => (),
Ok(n) => { Ok(n) => {
warn!( warn!("Strange, updated {} images with id {}", n, image);
"Strange, updated {} images with id {}",
n, image
);
} }
Err(error) => { Err(error) => {
warn!( warn!("Failed set grade of image #{}: {}", image, error);
"Failed set grade of image #{}: {}",
image, error
);
} }
} }
} else { } else {
info!( info!("Grade {} is out of range for image #{}", newgrade, image);
"Grade {} is out of range for image #{}",
newgrade, image
);
} }
} }
info!("Missing image and/or angle to rotate or image not found"); info!("Missing image and/or angle to rotate or image not found");

View File

@ -20,12 +20,14 @@ use memcachemiddleware::{MemcacheMiddleware, MemcacheRequestExtensions};
use models::{Person, Photo, Place, Tag}; use models::{Person, Photo, Place, Tag};
use nickel::extensions::response::Redirect; use nickel::extensions::response::Redirect;
use nickel::status::StatusCode; use nickel::status::StatusCode;
use nickel::{Action, Continue, FormBody, Halt, HttpRouter, MediaType, use nickel::{
MiddlewareResult, Nickel, NickelError, QueryString, Request, Action, Continue, FormBody, Halt, HttpRouter, MediaType, MiddlewareResult,
Response}; Nickel, NickelError, QueryString, Request, Response,
};
use nickel_diesel::{DieselMiddleware, DieselRequestExtensions}; use nickel_diesel::{DieselMiddleware, DieselRequestExtensions};
use nickel_jwt_session::{SessionMiddleware, SessionRequestExtensions, use nickel_jwt_session::{
SessionResponseExtensions}; SessionMiddleware, SessionRequestExtensions, SessionResponseExtensions,
};
use photosdirmiddleware::{PhotosDirMiddleware, PhotosDirRequestExtensions}; use photosdirmiddleware::{PhotosDirMiddleware, PhotosDirRequestExtensions};
use pidfiles::handle_pid_file; use pidfiles::handle_pid_file;
use r2d2::NopErrorHandler; use r2d2::NopErrorHandler;
@ -48,7 +50,8 @@ impl PhotoLink {
PhotoLink::from(&g[0]) PhotoLink::from(&g[0])
} else { } else {
fn imgscore(p: &Photo) -> i16 { fn imgscore(p: &Photo) -> i16 {
p.grade.unwrap_or(27) + if p.is_public { 38 } else { 0 } // Only score below 19 is worse than ungraded.
p.grade.unwrap_or(19) * if p.is_public { 5 } else { 4 }
} }
let photo = g.iter().max_by_key(|p| imgscore(p)).unwrap(); let photo = g.iter().max_by_key(|p| imgscore(p)).unwrap();
PhotoLink { PhotoLink {
@ -116,9 +119,10 @@ pub fn run(args: &ArgMatches) -> Result<(), Error> {
let mut server = Nickel::new(); let mut server = Nickel::new();
server.utilize(RequestLoggerMiddleware); server.utilize(RequestLoggerMiddleware);
wrap3!(server.get "/static/",.. static_file); wrap3!(server.get "/static/",.. static_file);
server.utilize(MemcacheMiddleware::new(vec![ server.utilize(MemcacheMiddleware::new(vec![(
("tcp://127.0.0.1:11211".into(), 1), "tcp://127.0.0.1:11211".into(),
])); 1,
)]));
server.utilize(SessionMiddleware::new(&jwt_key())); server.utilize(SessionMiddleware::new(&jwt_key()));
let dm: DieselMiddleware<PgConnection> = let dm: DieselMiddleware<PgConnection> =
DieselMiddleware::new(&dburl(), 5, Box::new(NopErrorHandler)).unwrap(); DieselMiddleware::new(&dburl(), 5, Box::new(NopErrorHandler)).unwrap();
@ -255,10 +259,7 @@ fn test_sanitize_good_1() {
} }
#[test] #[test]
fn test_sanitize_good_2() { fn test_sanitize_good_2() {
assert_eq!( assert_eq!(Some("/2017/7/15"), sanitize_next(Some("/2017/7/15")))
Some("/2017/7/15"),
sanitize_next(Some("/2017/7/15"))
)
} }
fn logout<'mw>( fn logout<'mw>(
@ -346,23 +347,15 @@ fn tag_all<'mw>(
} else { } else {
use schema::photo_tags::dsl as tp; use schema::photo_tags::dsl as tp;
use schema::photos::dsl as p; use schema::photos::dsl as p;
query.filter( query.filter(id.eq_any(tp::photo_tags.select(tp::tag_id).filter(
id.eq_any( tp::photo_id.eq_any(p::photos.select(p::id).filter(p::is_public)),
tp::photo_tags.select(tp::tag_id).filter( )))
tp::photo_id
.eq_any(p::photos.select(p::id).filter(p::is_public)),
),
),
)
}; };
res.ok(|o| { res.ok(|o| {
templates::tags( templates::tags(
o, o,
req, req,
&query &query.order(tag_name).load(c).expect("List tags"),
.order(tag_name)
.load(c)
.expect("List tags"),
) )
}) })
} }
@ -378,11 +371,7 @@ fn tag_one<'mw>(
use schema::photo_tags::dsl::{photo_id, photo_tags, tag_id}; use schema::photo_tags::dsl::{photo_id, photo_tags, tag_id};
use schema::photos::dsl::id; use schema::photos::dsl::id;
let photos = Photo::query(req.authorized_user().is_some()).filter( let photos = Photo::query(req.authorized_user().is_some()).filter(
id.eq_any( id.eq_any(photo_tags.select(photo_id).filter(tag_id.eq(tag.id))),
photo_tags
.select(photo_id)
.filter(tag_id.eq(tag.id)),
),
); );
let (links, coords) = links_by_time(req, photos); let (links, coords) = links_by_time(req, photos);
return res.ok(|o| templates::tag(o, req, &links, &coords, &tag)); return res.ok(|o| templates::tag(o, req, &links, &coords, &tag));
@ -401,24 +390,16 @@ fn place_all<'mw>(
} else { } else {
use schema::photo_places::dsl as pp; use schema::photo_places::dsl as pp;
use schema::photos::dsl as p; use schema::photos::dsl as p;
query.filter( query.filter(id.eq_any(pp::photo_places.select(pp::place_id).filter(
id.eq_any( pp::photo_id.eq_any(p::photos.select(p::id).filter(p::is_public)),
pp::photo_places.select(pp::place_id).filter( )))
pp::photo_id
.eq_any(p::photos.select(p::id).filter(p::is_public)),
),
),
)
}; };
let c: &PgConnection = &req.db_conn(); let c: &PgConnection = &req.db_conn();
res.ok(|o| { res.ok(|o| {
templates::places( templates::places(
o, o,
req, req,
&query &query.order(place_name).load(c).expect("List places"),
.order(place_name)
.load(c)
.expect("List places"),
) )
}) })
} }
@ -446,13 +427,10 @@ fn place_one<'mw>(
if let Ok(place) = places.filter(slug.eq(tslug)).first::<Place>(c) { if let Ok(place) = places.filter(slug.eq(tslug)).first::<Place>(c) {
use schema::photo_places::dsl::{photo_id, photo_places, place_id}; use schema::photo_places::dsl::{photo_id, photo_places, place_id};
use schema::photos::dsl::id; use schema::photos::dsl::id;
let photos = Photo::query(req.authorized_user().is_some()).filter( let photos =
id.eq_any( Photo::query(req.authorized_user().is_some()).filter(id.eq_any(
photo_places photo_places.select(photo_id).filter(place_id.eq(place.id)),
.select(photo_id) ));
.filter(place_id.eq(place.id)),
),
);
let (links, coord) = links_by_time(req, photos); let (links, coord) = links_by_time(req, photos);
return res.ok(|o| templates::place(o, req, &links, &coord, &place)); return res.ok(|o| templates::place(o, req, &links, &coord, &place));
} }
@ -470,24 +448,16 @@ fn person_all<'mw>(
} else { } else {
use schema::photo_people::dsl as pp; use schema::photo_people::dsl as pp;
use schema::photos::dsl as p; use schema::photos::dsl as p;
query.filter( query.filter(id.eq_any(pp::photo_people.select(pp::person_id).filter(
id.eq_any( pp::photo_id.eq_any(p::photos.select(p::id).filter(p::is_public)),
pp::photo_people.select(pp::person_id).filter( )))
pp::photo_id
.eq_any(p::photos.select(p::id).filter(p::is_public)),
),
),
)
}; };
let c: &PgConnection = &req.db_conn(); let c: &PgConnection = &req.db_conn();
res.ok(|o| { res.ok(|o| {
templates::people( templates::people(
o, o,
req, req,
&query &query.order(person_name).load(c).expect("list people"),
.order(person_name)
.load(c)
.expect("list people"),
) )
}) })
} }
@ -623,7 +593,8 @@ fn auto_complete_tag<'mw>(
if let Some(q) = req.query().get("q").map(String::from) { if let Some(q) = req.query().get("q").map(String::from) {
use schema::tags::dsl::{tag_name, tags}; use schema::tags::dsl::{tag_name, tags};
let c: &PgConnection = &req.db_conn(); let c: &PgConnection = &req.db_conn();
let q = tags.select(tag_name) let q = tags
.select(tag_name)
.filter(tag_name.ilike(q + "%")) .filter(tag_name.ilike(q + "%"))
.order(tag_name) .order(tag_name)
.limit(10); .limit(10);

View File

@ -1,5 +1,5 @@
use super::PhotoLink;
use super::views_by_date::query_date; use super::views_by_date::query_date;
use super::PhotoLink;
use diesel::pg::{Pg, PgConnection}; use diesel::pg::{Pg, PgConnection};
use diesel::prelude::*; use diesel::prelude::*;
use models::{Coord, Photo}; use models::{Coord, Photo};

View File

@ -1,7 +1,7 @@
use super::splitlist::links_by_time; use super::splitlist::links_by_time;
use super::{Link, PhotoLink, SizeTag}; use super::{Link, PhotoLink, SizeTag};
use chrono::Duration as ChDuration;
use chrono::naive::{NaiveDate, NaiveDateTime}; use chrono::naive::{NaiveDate, NaiveDateTime};
use chrono::Duration as ChDuration;
use diesel::expression::sql_literal::SqlLiteral; use diesel::expression::sql_literal::SqlLiteral;
use diesel::pg::PgConnection; use diesel::pg::PgConnection;
use diesel::prelude::*; use diesel::prelude::*;
@ -222,12 +222,7 @@ pub fn all_for_day<'mw>(
templates::index( templates::index(
o, o,
req, req,
&format!( &format!("Photos from {} {} {}", day, monthname(month), year),
"Photos from {} {} {}",
day,
monthname(month),
year
),
&[Link::year(year), Link::month(year, month)], &[Link::year(year), Link::month(year, month)],
&links, &links,
&coords, &coords,
@ -269,11 +264,9 @@ pub fn on_this_day<'mw>(
.iter() .iter()
.map(|&(year, count)| { .map(|&(year, count)| {
let year = year.map(|y| y as i32).unwrap_or(0); let year = year.map(|y| y as i32).unwrap_or(0);
let fromdate = NaiveDate::from_ymd( let fromdate =
year, NaiveDate::from_ymd(year, month as u32, day)
month as u32, .and_hms(0, 0, 0);
day,
).and_hms(0, 0, 0);
let photo = Photo::query(req.authorized_user().is_some()) let photo = Photo::query(req.authorized_user().is_some())
.filter(date.ge(fromdate)) .filter(date.ge(fromdate))
.filter(date.lt(fromdate + ChDuration::days(1))) .filter(date.lt(fromdate + ChDuration::days(1)))