Compare commits

...

1 Commits

Author SHA1 Message Date
Simon Laux
8e47e50a7e feat: add message parser api to jsonrpc and cffi
api: cffi add `dc_parse_message_text_to_ast_json` and `dc_msg_get_parsed_text_as_json

api: jsonrpc: add `get_parsed_message_text_ast_json` and `parse_text_to_ast_json`
2023-10-10 00:54:58 +00:00
8 changed files with 153 additions and 5 deletions

19
Cargo.lock generated
View File

@@ -1118,6 +1118,7 @@ dependencies = [
"chrono",
"criterion",
"deltachat_derive",
"deltachat_message_parser",
"email",
"encoded-words",
"escaper",
@@ -1259,6 +1260,18 @@ dependencies = [
"yerpc",
]
[[package]]
name = "deltachat_message_parser"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826f80f4b32f51457773351b2d821dc1f45273a38235e8fd3bdf662b67b70bcd"
dependencies = [
"nom",
"serde",
"serde_derive",
"unic-idna-punycode",
]
[[package]]
name = "der"
version = "0.6.1"
@@ -5221,6 +5234,12 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
[[package]]
name = "unic-idna-punycode"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06feaedcbf9f1fc259144d833c0d630b8b15207b0486ab817d29258bc89f2f8a"
[[package]]
name = "unicode-bidi"
version = "0.3.13"

View File

@@ -94,6 +94,7 @@ toml = "0.7"
trust-dns-resolver = "0.22"
url = "2"
uuid = { version = "1", features = ["serde", "v4"] }
deltachat_message_parser = "0.8.0"
[dev-dependencies]
ansi_term = "0.12.0"
@@ -154,8 +155,4 @@ harness = false
[features]
default = ["vendored"]
internals = []
vendored = [
"async-native-tls/vendored",
"rusqlite/bundled-sqlcipher-vendored-openssl",
"reqwest/native-tls-vendored"
]
vendored = ["async-native-tls/vendored", "rusqlite/bundled-sqlcipher-vendored-openssl", "reqwest/native-tls-vendored"]

View File

@@ -3993,6 +3993,36 @@ int64_t dc_msg_get_sort_timestamp (const dc_msg_t* msg);
char* dc_msg_get_text (const dc_msg_t* msg);
#define MESSAGE_PARSER_MODE_ONLY_TEXT 0x00
#define MESSAGE_PARSER_MODE_DESKTOP_SET 0x01
#define MESSAGE_PARSER_MODE_MARKDOWN 0x02
/**
* Parse text with the message parser.
*
* @memberof dc_context_t
* @param input The text to parse.
* @param mode Sets the parsing mode, you can choose between MESSAGE_PARSER_MODE_ONLY_TEXT, MESSAGE_PARSER_MODE_DESKTOP_SET and MESSAGE_PARSER_MODE_MARKDOWN.
* Look at https://github.com/deltachat/message-parser/blob/master/spec.md#modes-of-the-parser to learn more about the parser modes.
* @return Abstract Syntax Tree for your message that you can use to display parts of a message specially like links.
* This ast is returned in json (look at the sourcecode for reference for the format: https://github.com/deltachat/message-parser/blob/master/src/parser/mod.rs#L11)
*/
char* dc_parse_message_text_to_ast_json (const char* input, int mode);
/**
* Parse the text of a message with the message parser.
*
* @memberof dc_msg_t
* @param msg The message object.
* @param mode Sets the parsing mode, you can choose between MESSAGE_PARSER_MODE_ONLY_TEXT, MESSAGE_PARSER_MODE_DESKTOP_SET and MESSAGE_PARSER_MODE_MARKDOWN.
* Look at https://github.com/deltachat/message-parser/blob/master/spec.md#modes-of-the-parser to learn more about the parser modes.
* @return Abstract Syntax Tree for your message that you can use to display parts of a message specially like links.
* This ast is returned in json (look at the sourcecode for reference for the format: https://github.com/deltachat/message-parser/blob/master/src/parser/mod.rs#L11)
*/
char* dc_msg_get_parsed_text_as_json (const dc_msg_t* msg, int mode);
/**
* Get the subject of the e-mail.
* If there is no subject associated with the message, an empty string is returned.

View File

@@ -31,6 +31,7 @@ use deltachat::ephemeral::Timer as EphemeralTimer;
use deltachat::imex::BackupProvider;
use deltachat::key::{DcKey, DcSecretKey};
use deltachat::message::MsgId;
use deltachat::message_parser::parser;
use deltachat::net::read_url_blob;
use deltachat::qr_code_generator::{generate_backup_qr, get_securejoin_qr_svg};
use deltachat::reaction::{get_msg_reactions, send_reaction, Reactions};
@@ -3356,6 +3357,58 @@ pub unsafe extern "C" fn dc_msg_get_text(msg: *mut dc_msg_t) -> *mut libc::c_cha
ffi_msg.message.get_text().strdup()
}
#[no_mangle]
pub unsafe extern "C" fn dc_parse_message_text_to_ast_json(
text: *const libc::c_char,
mode: u32,
) -> *mut libc::c_char {
if text.is_null() {
eprintln!("ignoring careless call to dc_parse_message_text_to_ast_json()");
}
let text = to_string_lossy(text);
let result = match mode {
0 /* OnlyText */ => parser::parse_only_text(&text),
1 /* DesktopSet */ => parser::parse_desktop_set(&text),
2 /* Markdown */ => parser::parse_markdown_text(&text),
_ => {
eprintln!("ignoring careless call to dc_parse_message_text_to_ast_json() - invalid mode");
return "".strdup();
}
};
if let Ok(result) = serde_json::to_string(&result) {
result.strdup()
} else {
"".strdup()
}
}
#[no_mangle]
pub unsafe extern "C" fn dc_msg_get_parsed_text_as_json(
msg: *mut dc_msg_t,
mode: u32,
) -> *mut libc::c_char {
if msg.is_null() {
eprintln!("ignoring careless call to dc_msg_get_parsed_text_as_json()");
return "".strdup();
}
let ffi_msg = &*msg;
let text = ffi_msg.message.get_text();
let result = match mode {
0 /* OnlyText */ => parser::parse_only_text(&text),
1 /* DesktopSet */ => parser::parse_desktop_set(&text),
2 /* Markdown */ => parser::parse_markdown_text(&text),
_ => {
eprintln!("ignoring careless call to dc_msg_get_parsed_text_as_json() - invalid mode");
return "".strdup();
}
};
if let Ok(result) = serde_json::to_string(&result) {
result.strdup()
} else {
"".strdup()
}
}
#[no_mangle]
pub unsafe extern "C" fn dc_msg_get_subject(msg: *mut dc_msg_t) -> *mut libc::c_char {
if msg.is_null() {

View File

@@ -43,11 +43,13 @@ use types::contact::ContactObject;
use types::events::Event;
use types::http::HttpResponse;
use types::message::{MessageData, MessageObject, MessageReadReceipt};
use types::message_parser;
use types::provider_info::ProviderInfo;
use types::reactions::JSONRPCReactions;
use types::webxdc::WebxdcMessageInfo;
use self::types::message::MessageLoadResult;
use self::types::message_parser::MessageParserMode;
use self::types::{
chat::{BasicChat, JSONRPCChatVisibility, MuteDuration},
location::JsonrpcLocation,
@@ -1081,6 +1083,31 @@ impl CommandApi {
MsgId::new(message_id).get_html(&ctx).await
}
// no specific typings because of https://github.com/dbeckwith/rust-typescript-type-def/issues/18
async fn get_parsed_message_text_ast_json(
&self,
account_id: u32,
message_id: u32,
mode: MessageParserMode,
) -> Result<serde_json::Value> {
let ctx = self.get_context(account_id).await?;
let msg_text = Message::load_from_db(&ctx, MsgId::new(message_id))
.await?
.get_text();
let result = message_parser::parse_text(&msg_text, mode);
Ok(serde_json::to_value(result)?)
}
// no specific typings because of https://github.com/dbeckwith/rust-typescript-type-def/issues/18
async fn parse_text_to_ast_json(
&self,
text: String,
mode: MessageParserMode,
) -> Result<serde_json::Value> {
let result = message_parser::parse_text(&text, mode);
Ok(serde_json::to_value(result)?)
}
/// get multiple messages in one call,
/// if loading one message fails the error is stored in the result object in it's place.
///

View File

@@ -0,0 +1,19 @@
use deltachat::message_parser::parser::{self, Element};
use serde::{Deserialize, Serialize};
use typescript_type_def::TypeDef;
#[repr(u8)]
#[derive(Serialize, Deserialize, TypeDef, schemars::JsonSchema)]
pub enum MessageParserMode {
OnlyText,
DesktopSet,
Markdown,
}
pub fn parse_text(input: &str, mode: MessageParserMode) -> std::vec::Vec<Element> {
match mode {
MessageParserMode::OnlyText => parser::parse_only_text(input),
MessageParserMode::DesktopSet => parser::parse_desktop_set(input),
MessageParserMode::Markdown => parser::parse_markdown_text(input),
}
}

View File

@@ -6,6 +6,7 @@ pub mod events;
pub mod http;
pub mod location;
pub mod message;
pub mod message_parser;
pub mod provider_info;
pub mod qr;
pub mod reactions;

View File

@@ -110,6 +110,8 @@ pub mod tools;
pub mod accounts;
pub mod reaction;
pub use deltachat_message_parser as message_parser;
/// If set IMAP/incoming and SMTP/outgoing MIME messages will be printed.
pub const DCC_MIME_DEBUG: &str = "DCC_MIME_DEBUG";