use crate::{ models::library::Library, types::{AssetResponseDto, MetadataSearchDto}, Client, }; use chrono::{TimeZone, Utc}; use color_eyre::eyre::Result; use log::debug; #[derive(Debug, Default)] pub struct AssetQuery { pub library: Option, pub is_offline: Option, pub with_exif: bool, } pub async fn fetch_all_assets(query: AssetQuery, client: &Client) -> Result> { debug!("Fetching assets with query {:?}", query); // is_offline is ignored, let's fetch trashed assets instead and filter them later let trashed_after = if query.is_offline == Some(true) { Some(Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap()) } else { None }; let mut all_assets = Vec::new(); let mut page_number = None; let mut has_next_page = true; while has_next_page { let fetched = client .search_metadata(&MetadataSearchDto { checksum: None, city: None, country: None, created_after: None, created_before: None, device_asset_id: None, device_id: None, encoded_video_path: None, id: None, is_archived: None, is_encoded: None, is_favorite: None, is_motion: None, is_not_in_album: None, is_offline: query.is_offline, is_visible: None, lens_model: None, library_id: query.library.clone().map(|library| library.id), make: None, model: None, order: None, original_file_name: None, original_path: None, page: page_number, person_ids: vec![], preview_path: None, size: None, state: None, taken_after: None, taken_before: None, thumbnail_path: None, trashed_after, trashed_before: None, type_: None, updated_after: None, updated_before: None, with_archived: true, with_deleted: None, with_exif: Some(query.with_exif), with_people: None, with_stacked: None, }) .await?; all_assets.extend(fetched.assets.items.clone()); has_next_page = fetched.assets.next_page.is_some(); page_number = fetched .assets .next_page .clone() .map(|page| page.parse::().unwrap()); } if query.is_offline == Some(true) { all_assets.retain(|asset| asset.is_offline); } Ok(all_assets) }