Compare commits
1 Commits
master
...
757005f4f8
| Author | SHA1 | Date | |
|---|---|---|---|
| 757005f4f8 |
2
.github/workflows/integration-test.yml
vendored
2
.github/workflows/integration-test.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-action@master
|
||||||
|
|
||||||
- name: Install Podman
|
- name: Install Podman
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1016,7 +1016,6 @@ dependencies = [
|
|||||||
"bytes",
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
"image",
|
"image",
|
||||||
"mime",
|
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ image = "0.25"
|
|||||||
url = "2.5"
|
url = "2.5"
|
||||||
bytes = "1.10"
|
bytes = "1.10"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
mime = "0.3.17"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio-test = "0.4"
|
tokio-test = "0.4"
|
||||||
|
|||||||
249
TODO.md
249
TODO.md
@@ -1,249 +0,0 @@
|
|||||||
# Immich SDK Implementation Progress
|
|
||||||
|
|
||||||
| Method | Path | Status |
|
|
||||||
| :--- | :--- | :--- |
|
|
||||||
| DELETE | /activities/{id} | Not Implemented |
|
|
||||||
| DELETE | /admin/database-backups | Not Implemented |
|
|
||||||
| DELETE | /admin/users/{id} | Not Implemented |
|
|
||||||
| DELETE | /albums/{id} | Implemented |
|
|
||||||
| DELETE | /albums/{id}/assets | Implemented |
|
|
||||||
| DELETE | /albums/{id}/user/{userId} | Not Implemented |
|
|
||||||
| DELETE | /api-keys/{id} | Not Implemented |
|
|
||||||
| DELETE | /assets | Implemented |
|
|
||||||
| DELETE | /assets/metadata | Not Implemented |
|
|
||||||
| DELETE | /assets/{id}/edits | Not Implemented |
|
|
||||||
| DELETE | /assets/{id}/metadata/{key} | Not Implemented |
|
|
||||||
| DELETE | /auth/pin-code | Not Implemented |
|
|
||||||
| DELETE | /duplicates | Not Implemented |
|
|
||||||
| DELETE | /duplicates/{id} | Not Implemented |
|
|
||||||
| DELETE | /faces/{id} | Not Implemented |
|
|
||||||
| DELETE | /libraries/{id} | Not Implemented |
|
|
||||||
| DELETE | /memories/{id} | Not Implemented |
|
|
||||||
| DELETE | /memories/{id}/assets | Not Implemented |
|
|
||||||
| DELETE | /notifications | Not Implemented |
|
|
||||||
| DELETE | /notifications/{id} | Not Implemented |
|
|
||||||
| DELETE | /partners/{id} | Not Implemented |
|
|
||||||
| DELETE | /people | Not Implemented |
|
|
||||||
| DELETE | /people/{id} | Not Implemented |
|
|
||||||
| DELETE | /queues/{name}/jobs | Not Implemented |
|
|
||||||
| DELETE | /server/license | Not Implemented |
|
|
||||||
| DELETE | /sessions | Not Implemented |
|
|
||||||
| DELETE | /sessions/{id} | Not Implemented |
|
|
||||||
| DELETE | /shared-links/{id} | Not Implemented |
|
|
||||||
| DELETE | /shared-links/{id}/assets | Not Implemented |
|
|
||||||
| DELETE | /stacks | Not Implemented |
|
|
||||||
| DELETE | /stacks/{id} | Not Implemented |
|
|
||||||
| DELETE | /stacks/{id}/assets/{assetId} | Not Implemented |
|
|
||||||
| DELETE | /sync/ack | Not Implemented |
|
|
||||||
| DELETE | /tags/{id} | Not Implemented |
|
|
||||||
| DELETE | /tags/{id}/assets | Not Implemented |
|
|
||||||
| DELETE | /users/me/license | Not Implemented |
|
|
||||||
| DELETE | /users/me/onboarding | Not Implemented |
|
|
||||||
| DELETE | /users/profile-image | Not Implemented |
|
|
||||||
| DELETE | /workflows/{id} | Not Implemented |
|
|
||||||
| GET | /activities | Not Implemented |
|
|
||||||
| GET | /activities/statistics | Not Implemented |
|
|
||||||
| GET | /admin/database-backups | Not Implemented |
|
|
||||||
| GET | /admin/database-backups/{filename} | Not Implemented |
|
|
||||||
| GET | /admin/maintenance/detect-install | Not Implemented |
|
|
||||||
| GET | /admin/maintenance/status | Not Implemented |
|
|
||||||
| GET | /admin/users | Not Implemented |
|
|
||||||
| GET | /admin/users/{id} | Not Implemented |
|
|
||||||
| GET | /admin/users/{id}/preferences | Not Implemented |
|
|
||||||
| GET | /admin/users/{id}/sessions | Not Implemented |
|
|
||||||
| GET | /admin/users/{id}/statistics | Not Implemented |
|
|
||||||
| GET | /albums | Implemented |
|
|
||||||
| GET | /albums/statistics | Not Implemented |
|
|
||||||
| GET | /albums/{id} | Implemented |
|
|
||||||
| GET | /api-keys | Not Implemented |
|
|
||||||
| GET | /api-keys/me | Not Implemented |
|
|
||||||
| GET | /api-keys/{id} | Not Implemented |
|
|
||||||
| GET | /assets/device/{deviceId} | Not Implemented |
|
|
||||||
| GET | /assets/random | Not Implemented |
|
|
||||||
| GET | /assets/statistics | Not Implemented |
|
|
||||||
| GET | /assets/{id} | Not Implemented |
|
|
||||||
| GET | /assets/{id}/edits | Not Implemented |
|
|
||||||
| GET | /assets/{id}/metadata | Not Implemented |
|
|
||||||
| GET | /assets/{id}/metadata/{key} | Not Implemented |
|
|
||||||
| GET | /assets/{id}/ocr | Not Implemented |
|
|
||||||
| GET | /assets/{id}/original | Not Implemented |
|
|
||||||
| GET | /assets/{id}/thumbnail | Not Implemented |
|
|
||||||
| GET | /assets/{id}/video/playback | Not Implemented |
|
|
||||||
| GET | /auth/status | Not Implemented |
|
|
||||||
| GET | /duplicates | Not Implemented |
|
|
||||||
| GET | /faces | Not Implemented |
|
|
||||||
| GET | /jobs | Not Implemented |
|
|
||||||
| GET | /libraries | Not Implemented |
|
|
||||||
| GET | /libraries/{id} | Not Implemented |
|
|
||||||
| GET | /libraries/{id}/statistics | Not Implemented |
|
|
||||||
| GET | /map/markers | Not Implemented |
|
|
||||||
| GET | /map/reverse-geocode | Not Implemented |
|
|
||||||
| GET | /memories | Not Implemented |
|
|
||||||
| GET | /memories/statistics | Not Implemented |
|
|
||||||
| GET | /memories/{id} | Not Implemented |
|
|
||||||
| GET | /notifications | Not Implemented |
|
|
||||||
| GET | /notifications/{id} | Not Implemented |
|
|
||||||
| GET | /oauth/mobile-redirect | Not Implemented |
|
|
||||||
| GET | /partners | Not Implemented |
|
|
||||||
| GET | /people | Not Implemented |
|
|
||||||
| GET | /people/{id} | Not Implemented |
|
|
||||||
| GET | /people/{id}/statistics | Not Implemented |
|
|
||||||
| GET | /people/{id}/thumbnail | Not Implemented |
|
|
||||||
| GET | /plugins | Not Implemented |
|
|
||||||
| GET | /plugins/triggers | Not Implemented |
|
|
||||||
| GET | /plugins/{id} | Not Implemented |
|
|
||||||
| GET | /queues | Not Implemented |
|
|
||||||
| GET | /queues/{name} | Not Implemented |
|
|
||||||
| GET | /queues/{name}/jobs | Not Implemented |
|
|
||||||
| GET | /search/cities | Not Implemented |
|
|
||||||
| GET | /search/explore | Not Implemented |
|
|
||||||
| GET | /search/person | Not Implemented |
|
|
||||||
| GET | /search/places | Not Implemented |
|
|
||||||
| GET | /search/suggestions | Not Implemented |
|
|
||||||
| GET | /server/about | Implemented |
|
|
||||||
| GET | /server/apk-links | Implemented |
|
|
||||||
| GET | /server/config | Implemented |
|
|
||||||
| GET | /server/features | Implemented |
|
|
||||||
| GET | /server/license | Implemented |
|
|
||||||
| GET | /server/media-types | Implemented |
|
|
||||||
| GET | /server/ping | Implemented |
|
|
||||||
| GET | /server/statistics | Implemented |
|
|
||||||
| GET | /server/storage | Implemented |
|
|
||||||
| GET | /server/theme | Implemented |
|
|
||||||
| GET | /server/version | Implemented |
|
|
||||||
| GET | /server/version-check | Implemented |
|
|
||||||
| GET | /server/version-history | Implemented |
|
|
||||||
| GET | /sessions | Not Implemented |
|
|
||||||
| GET | /shared-links | Not Implemented |
|
|
||||||
| GET | /shared-links/me | Not Implemented |
|
|
||||||
| GET | /shared-links/{id} | Not Implemented |
|
|
||||||
| GET | /stacks | Not Implemented |
|
|
||||||
| GET | /stacks/{id} | Not Implemented |
|
|
||||||
| GET | /sync/ack | Not Implemented |
|
|
||||||
| GET | /system-config | Not Implemented |
|
|
||||||
| GET | /system-config/defaults | Not Implemented |
|
|
||||||
| GET | /system-config/storage-template-options | Not Implemented |
|
|
||||||
| GET | /system-metadata/admin-onboarding | Not Implemented |
|
|
||||||
| GET | /system-metadata/reverse-geocoding-state | Not Implemented |
|
|
||||||
| GET | /system-metadata/version-check-state | Not Implemented |
|
|
||||||
| GET | /tags | Not Implemented |
|
|
||||||
| GET | /tags/{id} | Not Implemented |
|
|
||||||
| GET | /timeline/bucket | Implemented (Candidate) |
|
|
||||||
| GET | /timeline/buckets | Implemented (Candidate) |
|
|
||||||
| GET | /users | Not Implemented |
|
|
||||||
| GET | /users/me | Not Implemented |
|
|
||||||
| GET | /users/me/license | Not Implemented |
|
|
||||||
| GET | /users/me/onboarding | Not Implemented |
|
|
||||||
| GET | /users/me/preferences | Not Implemented |
|
|
||||||
| GET | /users/{id} | Not Implemented |
|
|
||||||
| GET | /users/{id}/profile-image | Not Implemented |
|
|
||||||
| GET | /view/folder | Not Implemented |
|
|
||||||
| GET | /view/folder/unique-paths | Not Implemented |
|
|
||||||
| GET | /workflows | Not Implemented |
|
|
||||||
| GET | /workflows/{id} | Not Implemented |
|
|
||||||
| PATCH | /albums/{id} | Implemented |
|
|
||||||
| PATCH | /shared-links/{id} | Not Implemented |
|
|
||||||
| POST | /activities | Not Implemented |
|
|
||||||
| POST | /admin/auth/unlink-all | Not Implemented |
|
|
||||||
| POST | /admin/database-backups/start-restore | Not Implemented |
|
|
||||||
| POST | /admin/database-backups/upload | Not Implemented |
|
|
||||||
| POST | /admin/maintenance | Not Implemented |
|
|
||||||
| POST | /admin/maintenance/login | Not Implemented |
|
|
||||||
| POST | /admin/notifications | Not Implemented |
|
|
||||||
| POST | /admin/notifications/templates/{name} | Not Implemented |
|
|
||||||
| POST | /admin/notifications/test-email | Not Implemented |
|
|
||||||
| POST | /admin/users | Not Implemented |
|
|
||||||
| POST | /admin/users/{id}/restore | Not Implemented |
|
|
||||||
| POST | /albums | Implemented |
|
|
||||||
| POST | /api-keys | Not Implemented |
|
|
||||||
| POST | /assets | Implemented |
|
|
||||||
| POST | /assets/bulk-upload-check | Not Implemented |
|
|
||||||
| POST | /assets/exist | Not Implemented |
|
|
||||||
| POST | /assets/jobs | Not Implemented |
|
|
||||||
| POST | /auth/admin-sign-up | Not Implemented |
|
|
||||||
| POST | /auth/change-password | Not Implemented |
|
|
||||||
| POST | /auth/login | Not Implemented |
|
|
||||||
| POST | /auth/logout | Not Implemented |
|
|
||||||
| POST | /auth/pin-code | Not Implemented |
|
|
||||||
| POST | /auth/session/lock | Not Implemented |
|
|
||||||
| POST | /auth/session/unlock | Not Implemented |
|
|
||||||
| POST | /auth/validateToken | Not Implemented |
|
|
||||||
| POST | /download/archive | Not Implemented |
|
|
||||||
| POST | /download/info | Not Implemented |
|
|
||||||
| POST | /duplicates/resolve | Not Implemented |
|
|
||||||
| POST | /faces | Not Implemented |
|
|
||||||
| POST | /jobs | Not Implemented |
|
|
||||||
| POST | /libraries | Not Implemented |
|
|
||||||
| POST | /libraries/{id}/scan | Not Implemented |
|
|
||||||
| POST | /libraries/{id}/validate | Not Implemented |
|
|
||||||
| POST | /memories | Not Implemented |
|
|
||||||
| POST | /oauth/authorize | Not Implemented |
|
|
||||||
| POST | /oauth/callback | Not Implemented |
|
|
||||||
| POST | /oauth/link | Not Implemented |
|
|
||||||
| POST | /oauth/unlink | Not Implemented |
|
|
||||||
| POST | /partners | Not Implemented |
|
|
||||||
| POST | /partners/{id} | Not Implemented |
|
|
||||||
| POST | /people | Not Implemented |
|
|
||||||
| POST | /people/{id}/merge | Not Implemented |
|
|
||||||
| POST | /search/large-assets | Not Implemented |
|
|
||||||
| POST | /search/metadata | Not Implemented |
|
|
||||||
| POST | /search/random | Not Implemented |
|
|
||||||
| POST | /search/smart | Not Implemented |
|
|
||||||
| POST | /search/statistics | Not Implemented |
|
|
||||||
| POST | /sessions | Not Implemented |
|
|
||||||
| POST | /sessions/{id}/lock | Not Implemented |
|
|
||||||
| POST | /shared-links | Not Implemented |
|
|
||||||
| POST | /shared-links/login | Not Implemented |
|
|
||||||
| POST | /stacks | Not Implemented |
|
|
||||||
| POST | /sync/ack | Not Implemented |
|
|
||||||
| POST | /sync/delta-sync | Not Implemented |
|
|
||||||
| POST | /sync/full-sync | Not Implemented |
|
|
||||||
| POST | /sync/stream | Not Implemented |
|
|
||||||
| POST | /system-metadata/admin-onboarding | Not Implemented |
|
|
||||||
| POST | /tags | Not Implemented |
|
|
||||||
| POST | /trash/empty | Not Implemented |
|
|
||||||
| POST | /trash/restore | Not Implemented |
|
|
||||||
| POST | /trash/restore/assets | Not Implemented |
|
|
||||||
| POST | /users/profile-image | Not Implemented |
|
|
||||||
| POST | /workflows | Not Implemented |
|
|
||||||
| PUT | /admin/users/{id} | Not Implemented |
|
|
||||||
| PUT | /admin/users/{id}/preferences | Not Implemented |
|
|
||||||
| PUT | /albums/assets | Implemented |
|
|
||||||
| PUT | /albums/{id}/assets | Implemented |
|
|
||||||
| PUT | /albums/{id}/user/{userId} | Not Implemented |
|
|
||||||
| PUT | /albums/{id}/users | Not Implemented |
|
|
||||||
| PUT | /api-keys/{id} | Not Implemented |
|
|
||||||
| PUT | /assets | Implemented |
|
|
||||||
| PUT | /assets/copy | Not Implemented |
|
|
||||||
| PUT | /assets/metadata | Not Implemented |
|
|
||||||
| PUT | /assets/{id} | Implemented (Candidate) |
|
|
||||||
| PUT | /assets/{id}/edits | Not Implemented |
|
|
||||||
| PUT | /assets/{id}/metadata | Not Implemented |
|
|
||||||
| PUT | /assets/{id}/original | Not Implemented |
|
|
||||||
| PUT | /auth/pin-code | Not Implemented |
|
|
||||||
| PUT | /faces/{id} | Not Implemented |
|
|
||||||
| PUT | /jobs/{name} | Not Implemented |
|
|
||||||
| PUT | /libraries/{id} | Not Implemented |
|
|
||||||
| PUT | /memories/{id} | Not Implemented |
|
|
||||||
| PUT | /memories/{id}/assets | Not Implemented |
|
|
||||||
| PUT | /notifications | Not Implemented |
|
|
||||||
| PUT | /notifications/{id} | Not Implemented |
|
|
||||||
| PUT | /partners/{id} | Not Implemented |
|
|
||||||
| PUT | /people | Not Implemented |
|
|
||||||
| PUT | /people/{id} | Not Implemented |
|
|
||||||
| PUT | /people/{id}/reassign | Not Implemented |
|
|
||||||
| PUT | /queues/{name} | Not Implemented |
|
|
||||||
| PUT | /server/license | Implemented |
|
|
||||||
| PUT | /sessions/{id} | Not Implemented |
|
|
||||||
| PUT | /shared-links/{id}/assets | Not Implemented |
|
|
||||||
| PUT | /stacks/{id} | Not Implemented |
|
|
||||||
| PUT | /system-config | Not Implemented |
|
|
||||||
| PUT | /tags | Not Implemented |
|
|
||||||
| PUT | /tags/assets | Not Implemented |
|
|
||||||
| PUT | /tags/{id} | Not Implemented |
|
|
||||||
| PUT | /tags/{id}/assets | Not Implemented |
|
|
||||||
| PUT | /users/me | Not Implemented |
|
|
||||||
| PUT | /users/me/license | Not Implemented |
|
|
||||||
| PUT | /users/me/onboarding | Not Implemented |
|
|
||||||
| PUT | /users/me/preferences | Not Implemented |
|
|
||||||
| PUT | /workflows/{id} | Not Implemented |
|
|
||||||
@@ -1,10 +1,7 @@
|
|||||||
//! Assets API - Manage photos and videos
|
//! Assets API - Manage photos and videos
|
||||||
|
|
||||||
|
use std::io::Cursor;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::{io::Cursor, str::FromStr};
|
|
||||||
|
|
||||||
use mime::Mime;
|
|
||||||
use reqwest::header::CONTENT_TYPE;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Client,
|
Client,
|
||||||
@@ -17,17 +14,17 @@ use crate::{
|
|||||||
|
|
||||||
/// Response from downloading a thumbnail containing image data and metadata
|
/// Response from downloading a thumbnail containing image data and metadata
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct AssetDownload {
|
pub struct ThumbnailResponse {
|
||||||
/// The asset data as bytes
|
/// The image data as bytes
|
||||||
pub data: bytes::Bytes,
|
pub data: bytes::Bytes,
|
||||||
/// The MIME type of the asset (e.g., "image/jpeg", "image/png", "image/webp")
|
/// The MIME type of the image (e.g., "image/jpeg", "image/png", "image/webp")
|
||||||
pub mime: Mime,
|
pub content_type: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AssetDownload {
|
impl ThumbnailResponse {
|
||||||
/// Get the file extension based on content type
|
/// Get the file extension based on content type
|
||||||
pub fn extension(&self) -> Option<&str> {
|
pub fn extension(&self) -> Option<&str> {
|
||||||
match self.mime.essence_str() {
|
match self.content_type.as_str() {
|
||||||
"image/jpeg" | "image/jpg" => Some("jpg"),
|
"image/jpeg" | "image/jpg" => Some("jpg"),
|
||||||
"image/png" => Some("png"),
|
"image/png" => Some("png"),
|
||||||
"image/webp" => Some("webp"),
|
"image/webp" => Some("webp"),
|
||||||
@@ -38,8 +35,8 @@ impl AssetDownload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the content type
|
/// Get the content type
|
||||||
pub fn content_type(&self) -> &Mime {
|
pub fn content_type(&self) -> &str {
|
||||||
&self.mime
|
&self.content_type
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the data
|
/// Get the data
|
||||||
@@ -55,7 +52,7 @@ impl AssetDownload {
|
|||||||
/// Decode the image data into a DynamicImage
|
/// Decode the image data into a DynamicImage
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// Returns an error if the asset is not an image, content type is not supported, or if decoding fails
|
/// Returns an error if the content type is not supported or if decoding fails
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
@@ -72,8 +69,8 @@ impl AssetDownload {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn decode(&self) -> Result<image::DynamicImage> {
|
pub fn decode(&self) -> Result<image::DynamicImage> {
|
||||||
// Get image format from content type
|
// Get image format from content type
|
||||||
let format = image::ImageFormat::from_mime_type(&self.mime).ok_or_else(|| {
|
let format = image::ImageFormat::from_mime_type(&self.content_type).ok_or_else(|| {
|
||||||
ImmichError::Image(format!("Unsupported content type: {}", self.mime))
|
ImmichError::Image(format!("Unsupported content type: {}", self.content_type))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Create reader with the format and decode
|
// Create reader with the format and decode
|
||||||
@@ -306,10 +303,7 @@ impl UploadAssetBuilder {
|
|||||||
|
|
||||||
// Add file timestamps (required by Immich API v2)
|
// Add file timestamps (required by Immich API v2)
|
||||||
let now = chrono::Utc::now().to_rfc3339();
|
let now = chrono::Utc::now().to_rfc3339();
|
||||||
form = form.text(
|
form = form.text("fileCreatedAt", self.file_created_at.unwrap_or_else(|| now.clone()));
|
||||||
"fileCreatedAt",
|
|
||||||
self.file_created_at.unwrap_or_else(|| now.clone()),
|
|
||||||
);
|
|
||||||
form = form.text("fileModifiedAt", self.file_modified_at.unwrap_or(now));
|
form = form.text("fileModifiedAt", self.file_modified_at.unwrap_or(now));
|
||||||
|
|
||||||
let req = self.client.post("/assets").multipart(form);
|
let req = self.client.post("/assets").multipart(form);
|
||||||
@@ -392,7 +386,7 @@ impl DownloadAssetBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Execute the download
|
/// Execute the download
|
||||||
pub async fn execute(self) -> Result<AssetDownload> {
|
pub async fn execute(self) -> Result<bytes::Bytes> {
|
||||||
let path = format!("/assets/{}/original", self.id);
|
let path = format!("/assets/{}/original", self.id);
|
||||||
let mut req = self.client.get(&path);
|
let mut req = self.client.get(&path);
|
||||||
|
|
||||||
@@ -401,18 +395,8 @@ impl DownloadAssetBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let response = self.client.execute(req.build()?).await?;
|
let response = self.client.execute(req.build()?).await?;
|
||||||
|
let bytes = response.bytes().await?;
|
||||||
// Get content type from response headers
|
Ok(bytes)
|
||||||
let mime = response
|
|
||||||
.headers()
|
|
||||||
.get(CONTENT_TYPE)
|
|
||||||
.and_then(|ct| ct.to_str().ok())
|
|
||||||
.and_then(|ct| Mime::from_str(ct).ok())
|
|
||||||
.ok_or(ImmichError::Image("Missing or invalid content-type".into()))?;
|
|
||||||
|
|
||||||
let data = response.bytes().await?;
|
|
||||||
|
|
||||||
Ok(AssetDownload { data, mime })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,7 +433,7 @@ impl ThumbnailBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Execute the request
|
/// Execute the request
|
||||||
pub async fn execute(self) -> Result<AssetDownload> {
|
pub async fn execute(self) -> Result<ThumbnailResponse> {
|
||||||
let path = format!("/assets/{}/thumbnail", self.id);
|
let path = format!("/assets/{}/thumbnail", self.id);
|
||||||
let mut req = self.client.get(&path);
|
let mut req = self.client.get(&path);
|
||||||
|
|
||||||
@@ -470,15 +454,15 @@ impl ThumbnailBuilder {
|
|||||||
let response = self.client.execute(req.build()?).await?;
|
let response = self.client.execute(req.build()?).await?;
|
||||||
|
|
||||||
// Get content type from response headers
|
// Get content type from response headers
|
||||||
let mime = response
|
let content_type = response
|
||||||
.headers()
|
.headers()
|
||||||
.get(CONTENT_TYPE)
|
.get("content-type")
|
||||||
.and_then(|ct| ct.to_str().ok())
|
.and_then(|ct| ct.to_str().ok())
|
||||||
.and_then(|ct| Mime::from_str(ct).ok())
|
.map(String::from)
|
||||||
.ok_or(ImmichError::Image("Missing or invalid content-type".into()))?;
|
.unwrap_or_else(|| "application/octet-stream".to_string());
|
||||||
|
|
||||||
let data = response.bytes().await?;
|
let data = response.bytes().await?;
|
||||||
|
|
||||||
Ok(AssetDownload { data, mime })
|
Ok(ThumbnailResponse { data, content_type })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user