immich-tools/src/utils/assets.rs

91 lines
2.8 KiB
Rust

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<Library>,
pub is_offline: Option<bool>,
pub with_exif: bool,
}
pub async fn fetch_all_assets(query: AssetQuery, client: &Client) -> Result<Vec<AssetResponseDto>> {
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::<f64>().unwrap());
}
if query.is_offline == Some(true) {
all_assets.retain(|asset| asset.is_offline);
}
Ok(all_assets)
}