From f2049a8002a06f369557561d2e51ed4147c82512 Mon Sep 17 00:00:00 2001 From: Rasmus Kaj Date: Sun, 12 May 2019 19:48:21 +0200 Subject: [PATCH] Add a command to fix missing image sizes in db. --- src/adm/findphotos.rs | 41 +++++++++++++++++++++++++++++++++++++++++ src/main.rs | 6 ++++++ src/photosdir.rs | 4 ++-- src/server/mod.rs | 2 +- 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/adm/findphotos.rs b/src/adm/findphotos.rs index c9fce2b..7ead6de 100644 --- a/src/adm/findphotos.rs +++ b/src/adm/findphotos.rs @@ -7,6 +7,7 @@ use diesel::pg::PgConnection; use diesel::prelude::*; use log::{debug, info, warn}; use std::path::Path; +use std::time::Instant; pub fn crawl( db: &PgConnection, @@ -23,6 +24,46 @@ pub fn crawl( Ok(()) } +pub fn find_sizes(db: &PgConnection, pd: &PhotosDir) -> Result<(), Error> { + use crate::schema::photos::dsl as p; + let start = Instant::now(); + let mut c = 0; + while start.elapsed().as_secs() < 5 { + let photos = Photo::query(true) + .filter(p::width.is_null()) + .filter(p::height.is_null()) + .order((p::is_public.desc(), p::date.desc().nulls_last())) + .limit(10) + .load::(db)?; + + if photos.is_empty() { + break; + } else { + c += photos.len(); + } + + for photo in photos { + let exif = ExifData::read_from(&pd.get_raw_path(&photo))?; + let width = exif.width.ok_or(Error::MissingWidth)?; + let height = exif.height.ok_or(Error::MissingHeight)?; + + diesel::update(p::photos.find(photo.id)) + .set((p::width.eq(width as i32), p::height.eq(height as i32))) + .execute(db)?; + debug!("Store img #{} size {} x {}", photo.id, width, height); + } + } + + let e = start.elapsed(); + info!( + "Found size of {} images in {}.{:03} s", + c, + e.as_secs(), + e.subsec_millis(), + ); + Ok(()) +} + fn save_photo( db: &PgConnection, file_path: &str, diff --git a/src/main.rs b/src/main.rs index 2d42ac9..d7efc3b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,6 +41,9 @@ fn main() { "Base directory to search in (relative to the \ image root).", )), + ).subcommand( + SubCommand::with_name("find-sizes") + .about("Find sizes of images lacking that info in db"), ).subcommand( SubCommand::with_name("stats") .about("Show some statistics from the database"), @@ -159,6 +162,9 @@ fn run(args: &ArgMatches) -> Result<(), Error> { } Ok(()) } + ("find-sizes", Some(_args)) => { + findphotos::find_sizes(&get_db()?, &PhotosDir::new(photos_dir())) + } ("makepublic", Some(args)) => { let db = get_db()?; match args.value_of("LIST") { diff --git a/src/photosdir.rs b/src/photosdir.rs index ad24ffb..ca6d804 100644 --- a/src/photosdir.rs +++ b/src/photosdir.rs @@ -48,8 +48,8 @@ impl PhotosDir { } #[allow(dead_code)] - pub fn get_raw_path(&self, photo: Photo) -> PathBuf { - self.basedir.join(photo.path) + pub fn get_raw_path(&self, photo: &Photo) -> PathBuf { + self.basedir.join(&photo.path) } #[allow(dead_code)] diff --git a/src/server/mod.rs b/src/server/mod.rs index 1a0e20e..d71ba39 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -369,7 +369,7 @@ fn show_image(img: ImgName, context: Context) -> Response> { use std::fs::File; use std::io::Read; // TODO: This should be done in a more async-friendly way. - let path = context.photos().get_raw_path(tphoto); + let path = context.photos().get_raw_path(&tphoto); let mut buf = Vec::new(); if File::open(path) .map(|mut f| f.read_to_end(&mut buf))