api(deltachat-jsonrpc): return vcard contact directly in MessageObject

This commit is contained in:
link2xt
2024-05-17 21:52:57 +00:00
parent 0c7dad961d
commit 37d61e41ca
3 changed files with 28 additions and 1 deletions

View File

@@ -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.

View File

@@ -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<JSONRPCReactions>,
vcard_contact: Option<VcardContact>,
}
#[derive(Serialize, TypeDef, schemars::JsonSchema)]
@@ -173,6 +176,13 @@ impl MessageObject {
Some(reactions.into())
};
let vcard_contacts: Vec<VcardContact> = 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(),
})
}
}

View File

@@ -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<Vec<VcardContact>> {
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")?;