forked from wathiede/photosync
Add search iterator
This commit is contained in:
parent
3952f9e1fb
commit
7a31a73e60
114
src/main.rs
114
src/main.rs
@ -2,8 +2,8 @@ use std::error::Error;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use google_api_auth;
|
||||
use google_photoslibrary1;
|
||||
use google_photoslibrary1::schemas::SearchMediaItemsRequest;
|
||||
use google_photoslibrary1 as photos;
|
||||
use photos::schemas::{MediaItem, SearchMediaItemsRequest};
|
||||
use regex::Regex;
|
||||
use structopt::StructOpt;
|
||||
use yup_oauth2::{Authenticator, InstalledFlow};
|
||||
@ -43,7 +43,7 @@ struct Opt {
|
||||
fn new_client(
|
||||
credentials: &PathBuf,
|
||||
token_cache: &PathBuf,
|
||||
) -> Result<google_photoslibrary1::Client, Box<dyn Error>> {
|
||||
) -> Result<photos::Client, Box<dyn Error>> {
|
||||
let secret = yup_oauth2::read_application_secret(credentials)?;
|
||||
|
||||
// Create an authenticator that uses an InstalledFlow to authenticate. The
|
||||
@ -58,53 +58,87 @@ fn new_client(
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let scopes = vec!["https://www.googleapis.com/auth/photoslibrary.readonly".to_string()];
|
||||
let scopes = vec!["https://www.googleapis.com/auth/photoslibrary.readonly"];
|
||||
|
||||
let auth = google_api_auth::yup_oauth2::from_authenticator(auth, scopes);
|
||||
|
||||
Ok(google_photoslibrary1::Client::new(auth))
|
||||
Ok(photos::Client::new(auth))
|
||||
}
|
||||
|
||||
fn search_media_items(
|
||||
client: google_photoslibrary1::Client,
|
||||
album_id: String,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let mut page_token = None;
|
||||
let mut total = 0;
|
||||
loop {
|
||||
let resp = client
|
||||
.media_items()
|
||||
.search(SearchMediaItemsRequest {
|
||||
album_id: Some(album_id.clone()),
|
||||
// 100 is the documented max.
|
||||
page_size: Some(100),
|
||||
page_token,
|
||||
..Default::default()
|
||||
})
|
||||
.execute_with_all_fields()?;
|
||||
struct SearchIter<'a> {
|
||||
client: &'a photos::Client,
|
||||
items: ::std::vec::IntoIter<MediaItem>,
|
||||
finished: bool,
|
||||
req: SearchMediaItemsRequest,
|
||||
}
|
||||
|
||||
let media_items = resp.media_items.ok_or("no results")?;
|
||||
println!("got ({}) items", media_items.len());
|
||||
total += media_items.len();
|
||||
for mi in media_items {
|
||||
println!(
|
||||
"{} {}",
|
||||
mi.id.unwrap_or("NO ID".to_string()),
|
||||
mi.filename.unwrap_or("NO FILENAME".to_string())
|
||||
);
|
||||
}
|
||||
page_token = resp.next_page_token;
|
||||
if page_token.is_none() {
|
||||
println!("({}) items total", total);
|
||||
return Ok(());
|
||||
impl<'a> SearchIter<'a> {
|
||||
fn new(client: &'a photos::Client, req: SearchMediaItemsRequest) -> Self {
|
||||
SearchIter {
|
||||
client,
|
||||
items: Vec::new().into_iter(),
|
||||
finished: false,
|
||||
req,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn list_albums(
|
||||
client: google_photoslibrary1::Client,
|
||||
title_filter: Option<Regex>,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
impl<'a> Iterator for SearchIter<'a> {
|
||||
type Item = Result<MediaItem, photos::Error>;
|
||||
|
||||
fn next(&mut self) -> Option<Result<MediaItem, photos::Error>> {
|
||||
loop {
|
||||
if let Some(v) = self.items.next() {
|
||||
return Some(Ok(v));
|
||||
}
|
||||
if self.finished {
|
||||
return None;
|
||||
}
|
||||
let resp = match self
|
||||
.client
|
||||
.media_items()
|
||||
.search(self.req.clone())
|
||||
.execute_with_default_fields()
|
||||
{
|
||||
Ok(resp) => resp,
|
||||
Err(err) => return Some(Err(err)),
|
||||
};
|
||||
if resp.next_page_token.is_none() {
|
||||
self.finished = true;
|
||||
}
|
||||
self.req.page_token = resp.next_page_token;
|
||||
if let Some(items) = resp.media_items {
|
||||
self.items = items.into_iter();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn search_media_items(client: photos::Client, album_id: String) -> Result<(), Box<dyn Error>> {
|
||||
let mut total = 0;
|
||||
let media_items = SearchIter::new(
|
||||
&client,
|
||||
SearchMediaItemsRequest {
|
||||
album_id: Some(album_id.clone()),
|
||||
// 100 is the documented max.
|
||||
page_size: Some(100),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
for mi in media_items {
|
||||
let mi = mi?;
|
||||
total += 1;
|
||||
println!(
|
||||
"{} {}",
|
||||
mi.id.unwrap_or("NO ID".to_string()),
|
||||
mi.filename.unwrap_or("NO FILENAME".to_string())
|
||||
);
|
||||
}
|
||||
println!("({}) items total", total);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn list_albums(client: photos::Client, title_filter: Option<Regex>) -> Result<(), Box<dyn Error>> {
|
||||
for album in client
|
||||
.shared_albums()
|
||||
.list()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user