Skip to content

Commit

Permalink
fix(ark-metadata): handle non-standard metadata (#432)
Browse files Browse the repository at this point in the history
## Description

This pull request adds support for handling non-standard metadata
structures in our application. Previously, the code assumed that all
metadata followed a standard format with specific fields such as
trait_type and value. However, some metadata structures differ, using
fields like trait instead of trait_type.
  • Loading branch information
remiroyc committed Sep 2, 2024
1 parent ff919d9 commit b214503
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 164 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
15 changes: 15 additions & 0 deletions crates/ark-metadata/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use serde_derive::{Deserialize, Serialize};
use serde_json::Number;
use std::str::FromStr;
use std::{collections::HashMap, fmt};

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -39,6 +40,20 @@ pub enum DisplayType {
Date,
}

impl FromStr for DisplayType {
type Err = ();

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"number" => Ok(DisplayType::Number),
"boost_percentage" => Ok(DisplayType::BoostPercentage),
"boost_number" => Ok(DisplayType::BoostNumber),
"date" => Ok(DisplayType::Date),
_ => Err(()),
}
}
}

impl fmt::Display for DisplayType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Expand Down
Loading

0 comments on commit b214503

Please sign in to comment.