Fix examples and SDK for Immich v2 API compatibility
Some checks failed
Integration Tests / integration-test (push) Failing after 6s

- Fix AssetUploadStatus serialization to use snake_case (created/duplicate/rejected)
- Fix AssetOrder serialization to use lowercase (asc/desc)
- Add file_created_at/file_modified_at to UploadAssetBuilder
- Fix AddAssetsBuilder response type to Vec<Value> instead of AlbumResponse
- Fix ServerAbout model - version is String not ServerVersion struct
- Update upload_photos.rs to handle duplicate responses correctly
- Update server_info.rs to display new ServerAbout fields
- Update AGENTS.md with new example list
This commit is contained in:
Joakim Hulthe
2026-04-14 20:18:41 +00:00
parent 2e7db3b35a
commit c39e0a5058
6 changed files with 104 additions and 11 deletions

View File

@@ -6,7 +6,10 @@ use std::path::Path;
use crate::{
Client,
error::{ImmichError, Result},
models::{AssetId, AssetMediaSize, AssetResponse, AssetUploadResponse, DeleteAssetsRequest, MetadataSearchRequest, SearchResponse},
models::{
AssetId, AssetMediaSize, AssetResponse, AssetUploadResponse, DeleteAssetsRequest,
MetadataSearchRequest, SearchResponse,
},
};
/// Response from downloading a thumbnail containing image data and metadata
@@ -161,7 +164,7 @@ impl ListAssetsBuilder {
/// Execute the request
pub async fn execute(self) -> Result<Vec<AssetResponse>> {
let req = self.client.post("/search/metadata");
let mut body = MetadataSearchRequest::default();
if let Some(album_id) = self.album_id {
@@ -215,6 +218,8 @@ pub struct UploadAssetBuilder {
device_asset_id: Option<String>,
device_id: Option<String>,
is_favorite: bool,
file_created_at: Option<String>,
file_modified_at: Option<String>,
}
impl UploadAssetBuilder {
@@ -226,6 +231,8 @@ impl UploadAssetBuilder {
device_asset_id: None,
device_id: None,
is_favorite: false,
file_created_at: None,
file_modified_at: None,
}
}
@@ -253,6 +260,18 @@ impl UploadAssetBuilder {
self
}
/// Set file creation timestamp (ISO 8601 format)
pub fn file_created_at(mut self, timestamp: impl Into<String>) -> Self {
self.file_created_at = Some(timestamp.into());
self
}
/// Set file modification timestamp (ISO 8601 format)
pub fn file_modified_at(mut self, timestamp: impl Into<String>) -> Self {
self.file_modified_at = Some(timestamp.into());
self
}
/// Execute the upload
pub async fn execute(self) -> Result<AssetUploadResponse> {
let file_path = self
@@ -282,6 +301,11 @@ impl UploadAssetBuilder {
form = form.text("isFavorite", self.is_favorite.to_string());
// Add file timestamps (required by Immich API v2)
let now = chrono::Utc::now().to_rfc3339();
form = form.text("fileCreatedAt", self.file_created_at.unwrap_or_else(|| now.clone()));
form = form.text("fileModifiedAt", self.file_modified_at.unwrap_or(now));
let req = self.client.post("/assets").multipart(form);
let response = self.client.execute(req.build()?).await?;
let result: AssetUploadResponse = response.json().await?;