Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Implement IdentityImage #338

Merged
merged 14 commits into from
Oct 21, 2023
8 changes: 4 additions & 4 deletions extensions/warp-ipfs/examples/identity-interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ async fn main() -> anyhow::Result<()> {
}
};

if let Err(e) = account.update_identity(IdentityUpdate::Picture(picture.to_string())).await {
if let Err(e) = account.update_identity(IdentityUpdate::Picture(picture.as_bytes().to_vec())).await {
writeln!(stdout, "Error updating picture: {e}")?;
continue;
}
Expand All @@ -690,7 +690,7 @@ async fn main() -> anyhow::Result<()> {
}
};

if let Err(e) = account.update_identity(IdentityUpdate::Banner(banner.to_string())).await {
if let Err(e) = account.update_identity(IdentityUpdate::Banner(banner.as_bytes().to_vec())).await {
writeln!(stdout, "Error updating banner: {e}")?;
continue;
}
Expand Down Expand Up @@ -765,8 +765,8 @@ async fn main() -> anyhow::Result<()> {
created.to_string(),
modified.to_string(),
identity.status_message().unwrap_or_default(),
(!profile_banner.is_empty()).to_string(),
(!profile_picture.is_empty()).to_string(),
(!profile_banner.data().is_empty()).to_string(),
(!profile_picture.data().is_empty()).to_string(),
platform.to_string(),
format!("{status:?}"),
]);
Expand Down
4 changes: 2 additions & 2 deletions extensions/warp-ipfs/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{
str::FromStr,
time::Duration,
};
use warp::multipass::identity::Identity;
use warp::{multipass::identity::Identity, constellation::file::FileType};

#[derive(Default, Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
Expand Down Expand Up @@ -250,7 +250,7 @@ pub enum UpdateEvents {
}

pub type DefaultPfpFn =
std::sync::Arc<dyn Fn(&Identity) -> Result<Vec<u8>, std::io::Error> + Send + Sync + 'static>;
std::sync::Arc<dyn Fn(&Identity) -> Result<(Vec<u8>, FileType), std::io::Error> + Send + Sync + 'static>;

#[derive(Clone, Serialize, Deserialize)]
pub struct StoreSetting {
Expand Down
110 changes: 81 additions & 29 deletions extensions/warp-ipfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ use ipfs::{DhtMode, Ipfs, Keypair, PeerId, Protocol, UninitializedIpfs};
use warp::crypto::{KeyMaterial, DID};
use warp::error::Error;
use warp::multipass::identity::{
Identifier, Identity, IdentityProfile, IdentityUpdate, Relationship,
Identifier, Identity, IdentityImage, IdentityProfile, IdentityUpdate, Relationship,
};
use warp::multipass::{
identity, Friends, FriendsEvent, IdentityImportOption, IdentityInformation, ImportLocation,
Expand Down Expand Up @@ -689,15 +689,31 @@ impl MultiPass for WarpIpfs {

trace!("image size = {}", len);

let cid = store
.store_photo(
futures::stream::iter(Ok::<_, std::io::Error>(Ok(serde_json::to_vec(
&data,
)?)))
.boxed(),
Some(2 * 1024 * 1024),
)
.await?;
let (data, format) = tokio::task::spawn_blocking(move || {
let cursor = std::io::Cursor::new(data);

let image = image::io::Reader::new(cursor).with_guessed_format()?;

let format = image
.format()
.and_then(|format| ExtensionType::try_from(format).ok())
.unwrap_or(ExtensionType::Other);

let inner = image.into_inner();

let data = inner.into_inner();
Ok::<_, Error>((data, format))
})
.await
.map_err(anyhow::Error::from)??;

let cid = store::document::image_dag::store_photo(
&self.ipfs()?,
futures::stream::iter(Ok::<_, std::io::Error>(Ok(data))).boxed(),
format.into(),
Some(2 * 1024 * 1024),
)
.await?;

debug!("Image cid: {cid}");

Expand All @@ -724,7 +740,7 @@ impl MultiPass for WarpIpfs {
)));
}

let file = tokio::fs::File::open(path).await?;
let file = tokio::fs::File::open(&path).await?;

let metadata = file.metadata().await?;

Expand All @@ -739,6 +755,12 @@ impl MultiPass for WarpIpfs {
});
}

let extension = path
.extension()
.and_then(OsStr::to_str)
.map(ExtensionType::from)
.unwrap_or(ExtensionType::Other);

trace!("image size = {}", len);

let stream = async_stream::stream! {
Expand All @@ -760,9 +782,13 @@ impl MultiPass for WarpIpfs {
}
};

let cid = store
.store_photo(stream.boxed(), Some(2 * 1024 * 1024))
.await?;
let cid = store::document::image_dag::store_photo(
&self.ipfs()?,
stream.boxed(),
extension.into(),
Some(2 * 1024 * 1024),
)
.await?;

debug!("Image cid: {cid}");

Expand Down Expand Up @@ -802,15 +828,31 @@ impl MultiPass for WarpIpfs {

trace!("image size = {}", len);

let cid = store
.store_photo(
futures::stream::iter(Ok::<_, std::io::Error>(Ok(serde_json::to_vec(
&data,
)?)))
.boxed(),
Some(2 * 1024 * 1024),
)
.await?;
let (data, format) = tokio::task::spawn_blocking(move || {
let cursor = std::io::Cursor::new(data);

let image = image::io::Reader::new(cursor).with_guessed_format()?;

let format = image
.format()
.and_then(|format| ExtensionType::try_from(format).ok())
.unwrap_or(ExtensionType::Other);

let inner = image.into_inner();

let data = inner.into_inner();
Ok::<_, Error>((data, format))
})
.await
.map_err(anyhow::Error::from)??;

let cid = store::document::image_dag::store_photo(
&self.ipfs()?,
futures::stream::iter(Ok::<_, std::io::Error>(Ok(data))).boxed(),
format.into(),
Some(2 * 1024 * 1024),
)
.await?;

debug!("Image cid: {cid}");

Expand All @@ -837,7 +879,7 @@ impl MultiPass for WarpIpfs {
)));
}

let file = tokio::fs::File::open(path).await?;
let file = tokio::fs::File::open(&path).await?;

let metadata = file.metadata().await?;

Expand All @@ -852,6 +894,12 @@ impl MultiPass for WarpIpfs {
});
}

let extension = path
.extension()
.and_then(OsStr::to_str)
.map(ExtensionType::from)
.unwrap_or(ExtensionType::Other);

trace!("image size = {}", len);

let stream = async_stream::stream! {
Expand All @@ -873,9 +921,13 @@ impl MultiPass for WarpIpfs {
}
};

let cid = store
.store_photo(stream.boxed(), Some(2 * 1024 * 1024))
.await?;
let cid = store::document::image_dag::store_photo(
&self.ipfs()?,
stream.boxed(),
extension.into(),
Some(2 * 1024 * 1024),
)
.await?;

debug!("Image cid: {cid}");

Expand Down Expand Up @@ -1147,12 +1199,12 @@ impl FriendsEvent for WarpIpfs {

#[async_trait::async_trait]
impl IdentityInformation for WarpIpfs {
async fn identity_picture(&self, did: &DID) -> Result<String, Error> {
async fn identity_picture(&self, did: &DID) -> Result<IdentityImage, Error> {
let store = self.identity_store(true).await?;
store.identity_picture(did).await
}

async fn identity_banner(&self, did: &DID) -> Result<String, Error> {
async fn identity_banner(&self, did: &DID) -> Result<IdentityImage, Error> {
let store = self.identity_store(true).await?;
store.identity_banner(did).await
}
Expand Down
1 change: 1 addition & 0 deletions extensions/warp-ipfs/src/store/document.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod cache;
pub mod conversation;
pub mod identity;
pub mod image_dag;
pub mod root;
pub mod utils;

Expand Down
5 changes: 3 additions & 2 deletions extensions/warp-ipfs/src/store/document/identity.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use chrono::{DateTime, Utc};
use futures::{StreamExt, TryStreamExt};
use libipld::Cid;
use rust_ipfs::{Ipfs, IpfsPath};
use rust_ipfs::{Ipfs, IpfsPath, PeerId};
use serde::{Deserialize, Serialize};
use std::{hash::Hash, time::Duration};
use warp::{
Expand Down Expand Up @@ -196,14 +196,15 @@ pub async fn unixfs_fetch(
ipfs: &Ipfs,
cid: Cid,
timeout: Option<Duration>,
peers: &[PeerId],
local: bool,
limit: Option<usize>,
) -> Result<Vec<u8>, Error> {
let timeout = timeout.or(Some(std::time::Duration::from_secs(15)));

let mut stream = ipfs
.unixfs()
.cat(IpfsPath::from(cid), None, &[], local, timeout)
.cat(IpfsPath::from(cid), None, peers, local, timeout)
.await
.map_err(anyhow::Error::from)?
.boxed();
Expand Down
Loading