Move file creation code to library module.

This commit is contained in:
Bill Thiede 2020-02-10 20:59:52 -08:00
parent 48da92e278
commit c4deab996b
4 changed files with 101 additions and 51 deletions

1
Cargo.lock generated
View File

@ -1195,6 +1195,7 @@ dependencies = [
"prometheus", "prometheus",
"regex", "regex",
"reqwest", "reqwest",
"serde",
"serde_json", "serde_json",
"stderrlog", "stderrlog",
"structopt", "structopt",

View File

@ -20,6 +20,7 @@ stderrlog = "0.4.3"
structopt = "0.3.9" structopt = "0.3.9"
yup-oauth2 = "^3.1" yup-oauth2 = "^3.1"
warp = "0.1" warp = "0.1"
serde = { version = "1.0.104", features = ["derive"] }
[dependencies.prometheus] [dependencies.prometheus]
features = ["process"] features = ["process"]

84
src/library.rs Normal file
View File

@ -0,0 +1,84 @@
use std::fs;
use std::fs::File;
use std::io;
use std::path::Path;
use std::path::PathBuf;
use google_photoslibrary1 as photos;
use log::info;
use photos::schemas::Album;
use photos::schemas::MediaItem;
pub struct Library {
root: PathBuf,
originals_dir: PathBuf,
}
impl Library {
pub fn new(root: PathBuf) -> io::Result<Library> {
let lib = Library {
originals_dir: root.join("images").join("originals"),
root,
};
if !lib.originals_dir.exists() {
info!(
"create originals dir {}",
&lib.originals_dir.to_string_lossy()
);
fs::create_dir_all(&lib.originals_dir)?;
}
Ok(lib)
}
pub fn create_album_index(&self, albums: &Vec<Album>) -> io::Result<()> {
// Serialize it to a JSON string.
let j = serde_json::to_string(albums)?;
let path = self.root.join("albums.json");
info!("saving {}", path.to_string_lossy());
fs::write(path, j)
}
pub fn create_album<P: AsRef<Path>>(
&self,
album_id: P,
media_items: &Vec<MediaItem>,
) -> io::Result<()> {
let album_dir = self.root.join(album_id);
if !album_dir.exists() {
info!("making album directory {}", album_dir.to_string_lossy());
fs::create_dir_all(&album_dir)?;
}
let j = serde_json::to_string(&media_items)?;
let path = album_dir.join("album.json");
info!("saving {}", path.to_string_lossy());
fs::write(path, j)
}
pub fn download_image(
&self,
filename: &str,
media_items_id: &str,
base_url: &str,
) -> Result<PathBuf, Box<dyn std::error::Error>> {
// Put images from all albums in common directory.
let image_path = self.originals_dir.join(media_items_id);
if image_path.exists() {
info!(
"Skipping already downloaded {} @ {}",
&filename,
image_path.to_string_lossy()
);
} else {
let download_path = image_path.with_extension("download");
let url = format!("{}=d", base_url);
let mut r = reqwest::blocking::get(&url)?;
let mut w = File::create(&download_path)?;
let _n = io::copy(&mut r, &mut w)?;
info!(
"Rename {} -> {}",
download_path.to_string_lossy(),
image_path.to_string_lossy()
);
fs::rename(download_path, &image_path)?;
}
Ok(image_path)
}
}

View File

@ -17,6 +17,7 @@ use reqwest;
use structopt::StructOpt; use structopt::StructOpt;
use yup_oauth2::{Authenticator, InstalledFlow}; use yup_oauth2::{Authenticator, InstalledFlow};
mod library;
mod web; mod web;
#[derive(Debug, StructOpt)] #[derive(Debug, StructOpt)]
@ -198,67 +199,30 @@ fn sync_albums(
title_filter: Option<Regex>, title_filter: Option<Regex>,
output_dir: PathBuf, output_dir: PathBuf,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
// Put images from all albums in common directory. let lib = library::Library::new(output_dir)?;
let image_dir = output_dir.join("images");
if !image_dir.exists() {
fs::create_dir_all(&image_dir)?;
}
let albums = list_albums(client, title_filter)?; let albums = list_albums(client, title_filter)?;
lib.create_album_index(&albums)?;
for a in &albums { for a in &albums {
let album_id = a.id.as_ref().expect("unset album id").to_string(); let album_id = a.id.as_ref().expect("unset album id").to_string();
let album_dir = output_dir.join(&album_id); let media_items = search_media_items(client, &album_id)?;
if !album_dir.exists() { lib.create_album(&album_id, &media_items)?;
info!("making album directory {}", album_dir.to_string_lossy()); for (i, mi) in media_items.iter().enumerate() {
fs::create_dir_all(&album_dir)?;
}
let album = search_media_items(client, &album_id)?;
for (i, mi) in album.iter().enumerate() {
let mi_id = mi.id.as_ref().expect("unset media item id").to_string(); let mi_id = mi.id.as_ref().expect("unset media item id").to_string();
let filename = mi let filename = mi
.filename .filename
.as_ref() .as_ref()
.map_or("NO_FILENAME".to_string(), |s| s.to_string()); .map_or("NO_FILENAME".to_string(), |s| s.to_string());
let image_path = image_dir.join(mi_id); let base_url = mi.base_url.as_ref().expect("missing base_url");
if image_path.exists() { let image_path = lib.download_image(&filename, &mi_id, &base_url)?;
info!( info!(
"Skipping already downloaded {} @ {}", "({}/{}) Downloading {} -> {}",
&filename, i + 1,
image_path.to_string_lossy() &media_items.len(),
); &filename,
} else { image_path.to_string_lossy()
let download_path = image_path.with_extension("download"); );
info!(
"({}/{}) Downloading {} -> {}",
i + 1,
&album.len(),
&filename,
download_path.to_string_lossy()
);
let base_url = mi.base_url.as_ref().expect("missing base_url");
let url = format!("{}=d", base_url);
let mut r = reqwest::blocking::get(&url)?;
let mut w = File::create(&download_path)?;
let _n = io::copy(&mut r, &mut w)?;
info!(
"Rename {} -> {}",
download_path.to_string_lossy(),
image_path.to_string_lossy()
);
fs::rename(download_path, &image_path)?;
}
} }
let j = serde_json::to_string(&album)?;
let path = album_dir.join("album.json");
info!("saving {}", path.to_string_lossy());
fs::write(path, j)?;
} }
// Serialize it to a JSON string.
let j = serde_json::to_string(&albums)?;
let path = output_dir.join("albums.json");
info!("saving {}", path.to_string_lossy());
fs::write(path, j)?;
Ok(()) Ok(())
} }