diff --git a/src/imago_client.rs b/src/imago_client.rs index 4dbef79..85f1fa0 100644 --- a/src/imago_client.rs +++ b/src/imago_client.rs @@ -237,13 +237,33 @@ impl ImagoClient { Ok(detail) } - /// Récupère le thumbnail d'une image (raw bytes) + /// Récupère le thumbnail d'une image via URL signée pub async fn get_thumbnail(&self, id: i64) -> Result<(Vec, String)> { - let response = self.client - .get(format!("{}/{}/thumbnail", self.images_base(), id)) + // Étape 1 : obtenir l'URL signée + let sign_response: serde_json::Value = self.client + .get(format!("{}/{}/thumbnail-url", self.images_base(), id)) .header("X-API-Key", &self.api_key) .send() .await? + .error_for_status()? + .json() + .await?; + + let signed_url = sign_response["url"] + .as_str() + .ok_or_else(|| anyhow::anyhow!("URL signée manquante dans la réponse"))?; + + // Si c'est un placeholder (pas de thumbnail), retourner une erreur propre + if signed_url.contains("placeholder") { + return Err(anyhow::anyhow!("Thumbnail non disponible (placeholder)")); + } + + // Étape 2 : télécharger depuis l'URL signée + let full_url = format!("{}{}", self.base_url.trim_end_matches('/'), signed_url); + let response = self.client + .get(&full_url) + .send() + .await? .error_for_status()?; let content_type = response @@ -257,20 +277,35 @@ impl ImagoClient { Ok((data, content_type)) } - /// Récupère le fichier original (raw bytes) + /// Récupère le fichier original via URL signée pub async fn get_file(&self, id: i64) -> Result<(Vec, String)> { - let response = self.client - .get(format!("{}/{}/file", self.images_base(), id)) + // Étape 1 : obtenir l'URL signée + let sign_response: serde_json::Value = self.client + .get(format!("{}/{}/download-url", self.images_base(), id)) .header("X-API-Key", &self.api_key) .send() .await? + .error_for_status()? + .json() + .await?; + + let signed_url = sign_response["url"] + .as_str() + .ok_or_else(|| anyhow::anyhow!("URL signée manquante dans la réponse"))?; + + // Étape 2 : télécharger depuis l'URL signée + let full_url = format!("{}{}", self.base_url.trim_end_matches('/'), signed_url); + let response = self.client + .get(&full_url) + .send() + .await? .error_for_status()?; let content_type = response .headers() .get("content-type") .and_then(|v| v.to_str().ok()) - .unwrap_or("image/png") + .unwrap_or("application/octet-stream") .to_string(); let data = response.bytes().await?.to_vec(); diff --git a/src/server/routes.rs b/src/server/routes.rs index 0b5a9d7..20b91dd 100644 --- a/src/server/routes.rs +++ b/src/server/routes.rs @@ -420,7 +420,14 @@ async fn get_thumbnail( let result = if full { client.get_file(img_id).await } else { - client.get_thumbnail(img_id).await + // Essayer le thumbnail d'abord, fallback vers le fichier original + match client.get_thumbnail(img_id).await { + Ok(t) => Ok(t), + Err(_) => { + tracing::info!("Thumbnail fallback -> fichier original pour id={}", id); + client.get_file(img_id).await + } + } }; match result {