fix: affichage des images via URLs signées Imago
- ImagoClient::get_thumbnail() utilise maintenant /thumbnail-url (URL signée) - ImagoClient::get_file() utilise maintenant /download-url (URL signée) - Fallback automatique thumbnail → fichier original si thumbnail indisponible - Les images s'affichent dans la gallery même sans thumbnail généré
This commit is contained in:
+42
-7
@@ -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<u8>, 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<u8>, 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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user