Skip to content

Commit

Permalink
fix(ark-metadata): upload file
Browse files Browse the repository at this point in the history
  • Loading branch information
remiroyc committed Sep 2, 2024
1 parent 37316df commit 0ecb780
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 50 deletions.
79 changes: 47 additions & 32 deletions crates/ark-metadata/src/metadata_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use reqwest::Client as ReqwestClient;
use starknet::core::types::{BlockId, BlockTag, FieldElement};
use starknet::macros::selector;
use std::{str::FromStr, time::Duration};
use tracing::{debug, error, trace};
use tracing::{debug, error, trace, warn};

/// `MetadataManager` is responsible for managing metadata information related to tokens.
/// It works with the underlying storage and Starknet client to fetch and update token metadata.
Expand Down Expand Up @@ -285,43 +285,58 @@ impl<'a, T: Storage, C: StarknetClient, F: FileManager, E: ElasticsearchManager>
.timeout(timeout)
.send()
.await?;

if !response.status().is_success() {
warn!("Failed to fetch image from URL: {}", url);
return Err(anyhow!("Failed to fetch image from URL: {}", url));
}

let headers = response.headers().clone();
let bytes = response.bytes().await?;
let (content_type_from_headers, content_length) =
extract_metadata_from_headers(&headers)?;

let (file_ext, content_type): (&str, &str) = match url.split('.').last() {
Some(fe) => {
let content_type = get_content_type_from_extension(fe);
(fe, content_type)
}
None => {
let file_extension =
file_extension_from_mime_type(content_type_from_headers.as_str());
(file_extension, content_type_from_headers.as_str())
}
};

debug!(
"Image: Content-Type={}, Content-Length={:?}, File-Ext={}",
content_type, content_length, file_ext
);

let media_key = self
.file_manager
.save(&FileInfo {
name: format!("{}.{}", token_id, file_ext),
content: bytes.to_vec(),
dir_path: None,
if let Some(last_part) = url.split('/').last() {
let (file_name, content_type) = if last_part.contains('.') {
if let Some(file_extension) = last_part.split('.').last() {
let content_type = get_content_type_from_extension(file_extension);
(file_extension.to_string(), content_type.to_string())
} else {
return Err(anyhow!("Failed to extract file extension from URL"));
}
} else {
match file_extension_from_mime_type(content_type_from_headers.as_str()) {
Some(file_extension) => {
let file_name = format!("{}.{}", token_id, file_extension);
(file_name, file_extension.to_string())
}
None => (token_id.to_string(), content_type_from_headers),
}
};

debug!(
"Image: Content-Type={}, Content-Length={:?}, Filename={:?}",
content_type, content_length, file_name
);

let media_key = self
.file_manager
.save(&FileInfo {
name: file_name.clone(),
content: bytes.to_vec(),
dir_path: None,
})
.await?;

Ok(MetadataMedia {
file_type: content_type,
content_length,
is_cache_updated: true,
media_key: Some(media_key),
})
.await?;

Ok(MetadataMedia {
file_type: content_type.to_string(),
content_length,
is_cache_updated: true,
media_key: Some(media_key),
})
} else {
Err(anyhow!("Failed to extract file name from URL"))
}
}
}
}
Expand Down
41 changes: 23 additions & 18 deletions crates/ark-metadata/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use reqwest::Client;
use serde_json::Value;
use std::str::FromStr;
use std::time::Duration;
use tracing::{debug, error, trace};
use tracing::{debug, error, trace, warn};

pub async fn get_token_metadata(
client: &Client,
Expand All @@ -19,7 +19,8 @@ pub async fn get_token_metadata(
request_timeout_duration: Duration,
request_referrer: &str,
) -> Result<TokenMetadata> {
let metadata_type = get_metadata_type(uri);
let parsed_uri = uri.replace("https://gateway.pinata.cloud/ipfs/", "ipfs://");
let metadata_type = get_metadata_type(parsed_uri.as_str());
let metadata = match metadata_type {
MetadataType::Ipfs(uri) => {
let ipfs_hash = uri.trim_start_matches("ipfs://");
Expand Down Expand Up @@ -129,22 +130,25 @@ async fn fetch_metadata(
}
}

pub fn file_extension_from_mime_type(mime_type: &str) -> &str {
pub fn file_extension_from_mime_type(mime_type: &str) -> Option<&str> {
match mime_type {
"model/gltf-binary" => "glb",
"image/png" => "png",
"image/jpeg" => "jpg",
"image/gif" => "gif",
"image/bmp" => "bmp",
"image/webp" => "webp",
"image/svg+xml" => "svg",
"video/mp4" => "mp4",
"video/quicktime" => "mov",
"video/x-msvideo" => "avi",
"video/x-matroska" => "mkv",
"video/ogg" => "ogv",
"video/webm" => "webm",
_ => "",
"model/gltf-binary" => Some("glb"),
"image/png" => Some("png"),
"image/jpeg" => Some("jpg"),
"image/gif" => Some("gif"),
"image/bmp" => Some("bmp"),
"image/webp" => Some("webp"),
"image/svg+xml" => Some("svg"),
"video/mp4" => Some("mp4"),
"video/quicktime" => Some("mov"),
"video/x-msvideo" => Some("avi"),
"video/x-matroska" => Some("mkv"),
"video/ogg" => Some("ogv"),
"video/webm" => Some("webm"),
_ => {
warn!("Unknown MIME type: {}", mime_type);
None
}
}
}

Expand Down Expand Up @@ -194,7 +198,8 @@ fn fetch_onchain_metadata(uri: &str) -> Result<TokenMetadata> {
image: json_value
.get("image")
.and_then(|v| v.as_str())
.map(String::from),
.map(String::from)
.map(|image| image.replace("https://gateway.pinata.cloud/ipfs/", "ipfs://")),
description: json_value
.get("description")
.and_then(|v| v.as_str())
Expand Down

0 comments on commit 0ecb780

Please sign in to comment.