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)
|
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)> {
|
pub async fn get_thumbnail(&self, id: i64) -> Result<(Vec<u8>, String)> {
|
||||||
let response = self.client
|
// Étape 1 : obtenir l'URL signée
|
||||||
.get(format!("{}/{}/thumbnail", self.images_base(), id))
|
let sign_response: serde_json::Value = self.client
|
||||||
|
.get(format!("{}/{}/thumbnail-url", self.images_base(), id))
|
||||||
.header("X-API-Key", &self.api_key)
|
.header("X-API-Key", &self.api_key)
|
||||||
.send()
|
.send()
|
||||||
.await?
|
.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()?;
|
.error_for_status()?;
|
||||||
|
|
||||||
let content_type = response
|
let content_type = response
|
||||||
@@ -257,20 +277,35 @@ impl ImagoClient {
|
|||||||
Ok((data, content_type))
|
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)> {
|
pub async fn get_file(&self, id: i64) -> Result<(Vec<u8>, String)> {
|
||||||
let response = self.client
|
// Étape 1 : obtenir l'URL signée
|
||||||
.get(format!("{}/{}/file", self.images_base(), id))
|
let sign_response: serde_json::Value = self.client
|
||||||
|
.get(format!("{}/{}/download-url", self.images_base(), id))
|
||||||
.header("X-API-Key", &self.api_key)
|
.header("X-API-Key", &self.api_key)
|
||||||
.send()
|
.send()
|
||||||
.await?
|
.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()?;
|
.error_for_status()?;
|
||||||
|
|
||||||
let content_type = response
|
let content_type = response
|
||||||
.headers()
|
.headers()
|
||||||
.get("content-type")
|
.get("content-type")
|
||||||
.and_then(|v| v.to_str().ok())
|
.and_then(|v| v.to_str().ok())
|
||||||
.unwrap_or("image/png")
|
.unwrap_or("application/octet-stream")
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
let data = response.bytes().await?.to_vec();
|
let data = response.bytes().await?.to_vec();
|
||||||
|
|||||||
@@ -420,7 +420,14 @@ async fn get_thumbnail(
|
|||||||
let result = if full {
|
let result = if full {
|
||||||
client.get_file(img_id).await
|
client.get_file(img_id).await
|
||||||
} else {
|
} 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 {
|
match result {
|
||||||
|
|||||||
Reference in New Issue
Block a user