album/src/main.rs

208 lines
6.4 KiB
Rust
Raw Normal View History

#![recursion_limit = "128"]
extern crate brotli2;
2016-11-26 13:31:21 +03:00
extern crate chrono;
extern crate clap;
#[macro_use]
extern crate diesel;
#[macro_use]
2018-01-04 03:15:17 +04:00
extern crate diesel_infer_schema;
extern crate djangohashers;
extern crate dotenv;
extern crate env_logger;
2018-03-04 17:35:30 +04:00
extern crate exif;
extern crate flate2;
2017-09-02 01:14:17 +04:00
extern crate hyper;
extern crate image;
2017-09-02 01:14:17 +04:00
extern crate libc;
#[macro_use]
extern crate log;
2017-09-02 01:14:17 +04:00
extern crate memcached;
#[macro_use]
extern crate nickel;
extern crate nickel_jwt_session;
extern crate plugin;
extern crate r2d2;
extern crate r2d2_diesel;
extern crate rand;
2017-09-02 01:14:17 +04:00
extern crate regex;
2017-11-06 02:03:55 +04:00
extern crate rustc_serialize;
extern crate slug;
2017-09-02 01:14:17 +04:00
extern crate time;
extern crate typemap;
mod adm;
mod env;
2017-09-02 01:14:17 +04:00
mod memcachemiddleware;
mod models;
2018-03-04 17:35:30 +04:00
mod myexif;
2017-09-02 01:14:17 +04:00
mod nickel_diesel;
mod photosdir;
2017-09-02 01:14:17 +04:00
mod photosdirmiddleware;
mod pidfiles;
mod requestloggermiddleware;
mod schema;
2017-09-02 01:14:17 +04:00
mod server;
use adm::result::Error;
use adm::stats::show_stats;
2018-04-08 05:10:38 +04:00
use adm::{findphotos, makepublic, precache, storestatics, users};
use clap::{App, Arg, ArgMatches, SubCommand};
use diesel::pg::PgConnection;
use diesel::prelude::*;
use dotenv::dotenv;
use env::{dburl, photos_dir};
use photosdir::PhotosDir;
use std::fs::File;
use std::io::{self, BufReader};
2016-11-26 13:31:21 +03:00
use std::path::Path;
use std::process::exit;
fn main() {
dotenv().ok();
env_logger::init();
2017-11-09 03:06:12 +04:00
let args = App::new("rphotos")
.version(env!("CARGO_PKG_VERSION"))
.about("Command line interface for rphotos")
.subcommand(
SubCommand::with_name("findphotos")
.about("Find new photos in the photo directory")
.arg(Arg::with_name("BASE").multiple(true).help(
"Base directory to search in (relative to the \
image root).",
)),
)
.subcommand(
SubCommand::with_name("stats")
.about("Show some statistics from the database"),
)
.subcommand(
SubCommand::with_name("userlist").about("List existing 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"),
),
)
.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(
2017-11-09 03:06:12 +04:00
"The image path(s) are relative to the image root.",
),
)
.subcommand(
SubCommand::with_name("precache")
.about("Make sure the photos has thumbnails stored in cache."),
)
.subcommand(
SubCommand::with_name("storestatics")
.about("Store statics as files for a web server")
.arg(
Arg::with_name("DIR")
.required(true)
.help("Directory to store the files in"),
),
)
.subcommand(
SubCommand::with_name("runserver")
.arg(
Arg::with_name("PIDFILE")
.long("pidfile")
.takes_value(true)
.help(
2017-11-09 03:06:12 +04:00
"Write (and read, if --replace) a pid file with \
the name given as <PIDFILE>.",
),
)
.arg(Arg::with_name("REPLACE").long("replace").help(
2017-11-09 03:06:12 +04:00
"Kill old server (identified by pid file) before running",
)),
)
.get_matches();
match run(&args) {
Ok(()) => (),
Err(err) => {
println!("{}", err);
exit(1);
}
}
}
fn run(args: &ArgMatches) -> Result<(), Error> {
match args.subcommand() {
2016-11-26 13:31:21 +03:00
("findphotos", Some(args)) => {
let pd = PhotosDir::new(photos_dir());
2017-05-09 00:01:59 +04:00
let db = get_db()?;
2016-11-26 13:31:21 +03:00
if let Some(bases) = args.values_of("BASE") {
for base in bases {
findphotos::crawl(&db, &pd, Path::new(&base)).map_err(
|e| {
2017-12-12 00:10:18 +04:00
Error::Other(format!(
"Failed to crawl {}: {}",
base, e,
))
},
)?;
2016-11-26 13:31:21 +03:00
}
} else {
2017-12-12 00:10:18 +04:00
findphotos::crawl(&db, &pd, Path::new("")).map_err(|e| {
Error::Other(format!("Failed to crawl: {}", e))
})?;
2016-11-26 13:31:21 +03:00
}
Ok(())
}
("makepublic", Some(args)) => {
2017-05-09 00:01:59 +04:00
let db = get_db()?;
2016-11-26 14:32:16 +03:00
match args.value_of("LIST") {
Some("-") => {
let list = io::stdin();
makepublic::by_file_list(&db, list.lock())?;
2016-11-26 14:32:16 +03:00
Ok(())
}
Some(f) => {
2017-05-09 00:01:59 +04:00
let list = File::open(f)?;
let list = BufReader::new(list);
makepublic::by_file_list(&db, list)
}
None => makepublic::one(&db, args.value_of("IMAGE").unwrap()),
}
}
2017-05-09 00:01:59 +04:00
("stats", Some(_args)) => show_stats(&get_db()?),
("userlist", Some(_args)) => users::list(&get_db()?),
2016-11-26 13:31:21 +03:00
("userpass", Some(args)) => {
2017-05-09 00:01:59 +04:00
users::passwd(&get_db()?, args.value_of("USER").unwrap())
2016-11-26 13:31:21 +03:00
}
("precache", _) => {
precache::precache(&get_db()?, &PhotosDir::new(photos_dir()))
}
("storestatics", Some(args)) => {
storestatics::to_dir(args.value_of("DIR").unwrap())
}
("runserver", Some(args)) => server::run(args),
2018-07-06 01:28:57 +04:00
_ => Ok(println!("No subcommand given.\n\n{}", args.usage())),
}
}
fn get_db() -> Result<PgConnection, ConnectionError> {
PgConnection::establish(&dburl())
}
2017-09-02 01:14:17 +04:00
include!(concat!(env!("OUT_DIR"), "/templates.rs"));