Save all post attachments to IPFS in make_permanent()

This commit is contained in:
silverpill 2022-05-10 18:43:22 +00:00
parent 75a4dec009
commit 0268f6edc8
3 changed files with 17 additions and 12 deletions

View file

@ -5,6 +5,8 @@ use uuid::Uuid;
use super::utils::get_ipfs_url; use super::utils::get_ipfs_url;
const IPFS_LOGO: &str = "bafybeihc4hti5ix4ds2tefhy35qd4c7n5as5cazdmksrxj7ipvcxm64h54";
/// ERC-721 custom attribute as defined by OpenSea guidelines. /// ERC-721 custom attribute as defined by OpenSea guidelines.
#[derive(Serialize)] #[derive(Serialize)]
struct Attribute { struct Attribute {
@ -32,8 +34,10 @@ impl PostMetadata {
post_url: &str, post_url: &str,
content: &str, content: &str,
created_at: &DateTime<Utc>, created_at: &DateTime<Utc>,
image_cid: &str, image_cid: Option<&str>,
) -> Self { ) -> Self {
// Use IPFS logo if there's no image
let image_cid = image_cid.unwrap_or(IPFS_LOGO);
let created_at_attr = Attribute { let created_at_attr = Attribute {
trait_type: "Created at".to_string(), trait_type: "Created at".to_string(),
value: json!(created_at.timestamp()), value: json!(created_at.timestamp()),
@ -67,7 +71,7 @@ mod tests {
post_url, post_url,
&post.content, &post.content,
&post.created_at, &post.created_at,
image_cid, Some(image_cid),
); );
assert_eq!(post_metadata.name, format!("Post {}", post.id)); assert_eq!(post_metadata.name, format!("Post {}", post.id));

View file

@ -1,7 +1,5 @@
use regex::Regex; use regex::Regex;
pub const IPFS_LOGO: &str = "bafybeihc4hti5ix4ds2tefhy35qd4c7n5as5cazdmksrxj7ipvcxm64h54";
pub fn get_ipfs_url(cid: &str) -> String { pub fn get_ipfs_url(cid: &str) -> String {
format!("ipfs://{}", cid) format!("ipfs://{}", cid)
} }

View file

@ -20,7 +20,7 @@ use crate::errors::{DatabaseError, HttpError, ValidationError};
use crate::ethereum::nft::create_mint_signature; use crate::ethereum::nft::create_mint_signature;
use crate::ipfs::store as ipfs_store; use crate::ipfs::store as ipfs_store;
use crate::ipfs::posts::PostMetadata; use crate::ipfs::posts::PostMetadata;
use crate::ipfs::utils::{IPFS_LOGO, get_ipfs_url}; use crate::ipfs::utils::get_ipfs_url;
use crate::mastodon_api::oauth::auth::get_current_user; use crate::mastodon_api::oauth::auth::get_current_user;
use crate::models::attachments::queries::set_attachment_ipfs_cid; use crate::models::attachments::queries::set_attachment_ipfs_cid;
use crate::models::posts::helpers::can_view_post; use crate::models::posts::helpers::can_view_post;
@ -400,26 +400,24 @@ async fn make_permanent(
let ipfs_api_url = config.ipfs_api_url.as_ref() let ipfs_api_url = config.ipfs_api_url.as_ref()
.ok_or(HttpError::NotSupported)?; .ok_or(HttpError::NotSupported)?;
let post_image_cid = if let Some(attachment) = post.attachments.first() { for attachment in post.attachments.iter_mut() {
// Add attachment to IPFS // Add attachment to IPFS
let image_path = config.media_dir().join(&attachment.file_name); let image_path = config.media_dir().join(&attachment.file_name);
let image_data = std::fs::read(image_path) let image_data = std::fs::read(image_path)
.map_err(|_| HttpError::InternalError)?; .map_err(|_| HttpError::InternalError)?;
let image_cid = ipfs_store::add(ipfs_api_url, image_data).await let image_cid = ipfs_store::add(ipfs_api_url, image_data).await
.map_err(|_| HttpError::InternalError)?; .map_err(|_| HttpError::InternalError)?;
set_attachment_ipfs_cid(db_client, &attachment.id, &image_cid).await?; attachment.ipfs_cid = Some(image_cid);
image_cid
} else {
// Use IPFS logo if there's no image
IPFS_LOGO.to_string()
}; };
let post_url = post.get_object_id(&config.instance_url()); let post_url = post.get_object_id(&config.instance_url());
let maybe_post_image_cid = post.attachments.first()
.and_then(|attachment| attachment.ipfs_cid.as_deref());
let post_metadata = PostMetadata::new( let post_metadata = PostMetadata::new(
&post.id, &post.id,
&post_url, &post_url,
&post.content, &post.content,
&post.created_at, &post.created_at,
&post_image_cid, maybe_post_image_cid,
); );
let post_metadata_json = serde_json::to_string(&post_metadata) let post_metadata_json = serde_json::to_string(&post_metadata)
.map_err(|_| HttpError::InternalError)? .map_err(|_| HttpError::InternalError)?
@ -428,6 +426,11 @@ async fn make_permanent(
.map_err(|_| HttpError::InternalError)?; .map_err(|_| HttpError::InternalError)?;
// Update post // Update post
for attachment in &post.attachments {
let image_cid = attachment.ipfs_cid.as_ref()
.ok_or(HttpError::InternalError)?;
set_attachment_ipfs_cid(db_client, &attachment.id, image_cid).await?;
};
post.ipfs_cid = Some(post_metadata_cid); post.ipfs_cid = Some(post_metadata_cid);
update_post(db_client, &post).await?; update_post(db_client, &post).await?;