From 37d61e41ca8ac621ed176fe129ffba5a5ee79466 Mon Sep 17 00:00:00 2001 From: link2xt Date: Fri, 17 May 2024 21:52:57 +0000 Subject: [PATCH] api(deltachat-jsonrpc): return vcard contact directly in MessageObject --- deltachat-jsonrpc/src/api/types/contact.rs | 2 +- deltachat-jsonrpc/src/api/types/message.rs | 12 ++++++++++++ src/message.rs | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/deltachat-jsonrpc/src/api/types/contact.rs b/deltachat-jsonrpc/src/api/types/contact.rs index 0530a16fe..54f68dcc3 100644 --- a/deltachat-jsonrpc/src/api/types/contact.rs +++ b/deltachat-jsonrpc/src/api/types/contact.rs @@ -89,7 +89,7 @@ impl ContactObject { } } -#[derive(Serialize, TypeDef, schemars::JsonSchema)] +#[derive(Clone, Serialize, TypeDef, schemars::JsonSchema)] #[serde(rename_all = "camelCase")] pub struct VcardContact { /// Email address. diff --git a/deltachat-jsonrpc/src/api/types/message.rs b/deltachat-jsonrpc/src/api/types/message.rs index 95742cc52..cb6cb640b 100644 --- a/deltachat-jsonrpc/src/api/types/message.rs +++ b/deltachat-jsonrpc/src/api/types/message.rs @@ -1,3 +1,4 @@ +use crate::api::VcardContact; use anyhow::{Context as _, Result}; use deltachat::chat::Chat; use deltachat::chat::ChatItem; @@ -87,6 +88,8 @@ pub struct MessageObject { download_state: DownloadState, reactions: Option, + + vcard_contact: Option, } #[derive(Serialize, TypeDef, schemars::JsonSchema)] @@ -173,6 +176,13 @@ impl MessageObject { Some(reactions.into()) }; + let vcard_contacts: Vec = message + .vcard_contacts(context) + .await? + .into_iter() + .map(Into::into) + .collect(); + Ok(MessageObject { id: msg_id.to_u32(), chat_id: message.get_chat_id().to_u32(), @@ -232,6 +242,8 @@ impl MessageObject { download_state, reactions, + + vcard_contact: vcard_contacts.first().cloned(), }) } } diff --git a/src/message.rs b/src/message.rs index 1163b8d62..6d69299de 100644 --- a/src/message.rs +++ b/src/message.rs @@ -4,6 +4,7 @@ use std::collections::BTreeSet; use std::path::{Path, PathBuf}; use anyhow::{ensure, format_err, Context as _, Result}; +use deltachat_contact_tools::{parse_vcard, VcardContact}; use deltachat_derive::{FromSql, ToSql}; use serde::{Deserialize, Serialize}; use tokio::{fs, io}; @@ -607,6 +608,20 @@ impl Message { self.param.get_path(Param::File, context).unwrap_or(None) } + /// Returns vector of vcards if the file has a vCard attachment. + pub async fn vcard_contacts(&self, context: &Context) -> Result> { + if self.viewtype != Viewtype::Vcard { + return Ok(Vec::new()); + } + + let path = self + .get_file(context) + .context("vCard message does not have an attachment")?; + let bytes = tokio::fs::read(path).await?; + let vcard_contents = std::str::from_utf8(&bytes).context("vCard is not a valid UTF-8")?; + Ok(parse_vcard(vcard_contents)) + } + /// Save file copy at the user-provided path. pub async fn save_file(&self, context: &Context, path: &Path) -> Result<()> { let path_src = self.get_file(context).context("No file")?;