From 5afd58086d692420cfa6e03c9644125edca87a89 Mon Sep 17 00:00:00 2001 From: Rasmus Kaj Date: Thu, 24 Nov 2016 22:42:57 +0100 Subject: [PATCH] Include makepublic in rphotosadm. Another separate binary merged into the general adm binary. --- Cargo.toml | 4 --- src/adm/makepublic.rs | 58 ++++++++++++++++++++++++++++++++ src/adm/mod.rs | 1 + src/adm/result.rs | 12 ++++++- src/public_from_list.rs | 73 ----------------------------------------- src/rphotosadm.rs | 52 ++++++++++++++++++++++++++--- 6 files changed, 117 insertions(+), 83 deletions(-) create mode 100644 src/adm/makepublic.rs delete mode 100644 src/public_from_list.rs diff --git a/Cargo.toml b/Cargo.toml index a6d63df..34a0297 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,10 +33,6 @@ path = "src/readkpa.rs" name = "findphotos" path = "src/findphotos.rs" -[[bin]] -name = "public_from_list" -path = "src/public_from_list.rs" - [dependencies] nickel = "^0.9" nickel-jwt-session = "^0.5" diff --git a/src/adm/makepublic.rs b/src/adm/makepublic.rs new file mode 100644 index 0000000..20d5e2f --- /dev/null +++ b/src/adm/makepublic.rs @@ -0,0 +1,58 @@ +use adm::result::Error; +use diesel::pg::PgConnection; +use diesel::prelude::*; +use diesel::result::Error as DieselError; +use diesel::update; +use photosdir::PhotosDir; +use rphotos::models::{Modification, Photo}; +use std::io::prelude::*; + +pub fn one(db: &PgConnection, + photodir: &PhotosDir, + tpath: &str) + -> Result<(), Error> { + use rphotos::schema::photos::dsl::*; + match update(photos.filter(path.eq(&tpath))) + .set(is_public.eq(true)) + .get_result::(db) { + Ok(photo) => { + println!("Made {} public: {:?}", tpath, photo); + Ok(()) + } + Err(DieselError::NotFound) => { + if !photodir.has_file(&tpath) { + return Err(Error::Other(format!("File {} does not exist", + tpath))); + } + let photo = try!(register_photo(db, &tpath)); + println!("New photo {:?} is public.", photo); + Ok(()) + } + Err(error) => Err(error.into()), + } +} + +pub fn by_file_list(db: &PgConnection, + photodir: &PhotosDir, + list: In) + -> Result<(), Error> { + for line in list.lines() { + try!(one(db, photodir, &try!(line))); + } + Ok(()) +} + +fn register_photo(db: &PgConnection, + tpath: &str) + -> Result { + use rphotos::schema::photos::dsl::{photos, is_public}; + let photo = + match try!(Photo::create_or_set_basics(&db, &tpath, None, 0, None)) { + Modification::Created(photo) => photo, + Modification::Updated(photo) => photo, + Modification::Unchanged(photo) => photo, + }; + update(photos.find(photo.id)) + .set(is_public.eq(true)) + .get_result::(db) +} diff --git a/src/adm/mod.rs b/src/adm/mod.rs index 5636e42..4918db3 100644 --- a/src/adm/mod.rs +++ b/src/adm/mod.rs @@ -1,3 +1,4 @@ +pub mod makepublic; pub mod result; pub mod stats; pub mod users; diff --git a/src/adm/result.rs b/src/adm/result.rs index 4b426d6..b239de1 100644 --- a/src/adm/result.rs +++ b/src/adm/result.rs @@ -1,12 +1,14 @@ use diesel::prelude::ConnectionError; use diesel::result::Error as DieselError; +use std::{io, fmt}; use std::convert::From; -use std::fmt; #[derive(Debug)] pub enum Error { Connection(ConnectionError), Db(DieselError), + Io(io::Error), + Other(String), } impl fmt::Display for Error { @@ -14,6 +16,8 @@ impl fmt::Display for Error { match self { &Error::Connection(ref e) => write!(f, "Connection error: {}", e), &Error::Db(ref e) => write!(f, "Database error: {}", e), + &Error::Io(ref e) => write!(f, "I/O error: {}", e), + &Error::Other(ref s) => write!(f, "Error: {}", s), } } } @@ -29,3 +33,9 @@ impl From for Error { Error::Db(e) } } + +impl From for Error { + fn from(e: io::Error) -> Self { + Error::Io(e) + } +} diff --git a/src/public_from_list.rs b/src/public_from_list.rs deleted file mode 100644 index 058f0ff..0000000 --- a/src/public_from_list.rs +++ /dev/null @@ -1,73 +0,0 @@ -#[macro_use] -extern crate log; -extern crate env_logger; -extern crate dotenv; -extern crate diesel; -extern crate rphotos; -extern crate image; -extern crate rexif; - -use diesel::pg::PgConnection; -use diesel::prelude::*; -use diesel::result::Error as DieselError; -use diesel::result::Error; -use dotenv::dotenv; -use rphotos::models::{Modification, Photo}; -use std::io; -use std::io::prelude::*; - -mod env; -use env::{dburl, photos_dir}; -mod photosdir; -use photosdir::PhotosDir; - -fn main() { - dotenv().ok(); - env_logger::init().unwrap(); - let photodir = PhotosDir::new(photos_dir()); - let db = PgConnection::establish(&dburl()) - .expect("Error connecting to database"); - - let stdin = io::stdin(); - for line in stdin.lock().lines() { - match line { - Ok(line) => { - use rphotos::schema::photos::dsl::*; - match diesel::update(photos.filter(path.eq(&line))) - .set(is_public.eq(true)) - .get_result::(&db) { - Ok(photo) => - info!("Made {} public: {:?}", line, photo), - Err(Error::NotFound) => { - if !photodir.has_file(&line) { - panic!("File {} does not exist", line); - } - let photo = register_photo(&db, &line) - .expect("Register photo"); - info!("New photo {:?} is public.", photo); - } - Err(error) => - panic!("Problem with {}: {:?}", line, error), - } - } - Err(err) => { - panic!("Failed to read a line: {:?}", err); - } - } - } -} - -fn register_photo(db: &PgConnection, tpath: &str) - -> Result { - debug!("Should add {} to database", tpath); - use rphotos::schema::photos::dsl::{photos, is_public}; - let photo = - match try!(Photo::create_or_set_basics(&db, &tpath, None, 0, None)) { - Modification::Created(photo) => photo, - Modification::Updated(photo) => photo, - Modification::Unchanged(photo) => photo, - }; - diesel::update(photos.find(photo.id)) - .set(is_public.eq(true)) - .get_result::(db) -} diff --git a/src/rphotosadm.rs b/src/rphotosadm.rs index 60f2522..db092ac 100644 --- a/src/rphotosadm.rs +++ b/src/rphotosadm.rs @@ -7,18 +7,26 @@ extern crate djangohashers; extern crate dotenv; extern crate env_logger; extern crate rand; +#[macro_use] +extern crate log; +extern crate image; +extern crate rexif; mod adm; mod env; +mod photosdir; use adm::result::Error; use adm::stats::show_stats; -use adm::users; +use adm::{makepublic, users}; use clap::{App, Arg, ArgMatches, SubCommand}; use diesel::pg::PgConnection; use diesel::prelude::*; use dotenv::dotenv; -use env::dburl; +use env::{dburl, photos_dir}; +use photosdir::PhotosDir; +use std::fs::File; +use std::io::{self, BufReader}; use std::process::exit; fn main() { @@ -32,9 +40,21 @@ fn main() { .about("List users")) .subcommand(SubCommand::with_name("userpass") .about("Set password for a (new or existing) user") - .arg(Arg::with_name("USER") - .required(true) - .help("Username to set password for"))) + .arg(Arg::with_name("USER") + .required(true) + .help("Username to set password for"))) + .subcommand(SubCommand::with_name("makepublic") + .about("make specific image(s) public") + .arg(Arg::with_name("LIST") + .long("list") + .short("l") + .takes_value(true) + .help("File listing image paths to make public")) + .arg(Arg::with_name("IMAGE") + .required_unless("LIST") + .help("Image path to make public")) + .after_help("The image path(s) are relative to the \ + image root.")) .get_matches(); match run(args) { @@ -48,6 +68,28 @@ fn main() { fn run(args: ArgMatches) -> Result<(), Error> { match args.subcommand() { + ("makepublic", Some(args)) => { + let pd = PhotosDir::new(photos_dir()); + if let Some(f) = args.value_of("LIST") { + if f == "-" { + let list = io::stdin(); + try!(makepublic::by_file_list(&try!(get_db()), + &pd, + list.lock())); + } else { + let list = try!(File::open(f)); + let list = BufReader::new(list); + try!(makepublic::by_file_list(&try!(get_db()), + &pd, + list)); + } + Ok(()) + } else { + makepublic::one(&try!(get_db()), + &pd, + args.value_of("IMAGE").unwrap()) + } + } ("stats", Some(_args)) => show_stats(&try!(get_db())), ("userlist", Some(_args)) => users::list(&try!(get_db())), ("userpass", Some(args)) => users::passwd(&try!(get_db()),