Add image receipt to the text channel
This is disturbingly useless with Empathy because it doesn't know how to display text/html parts, or plain image/png parts either :/ Time to start playing with KDE Spacebar? How does it handle them?
This commit is contained in:
@@ -43,6 +43,7 @@ impl telepathy::ChannelInterfaceMessages for Channel {
|
||||
};
|
||||
|
||||
let ctx = self.ctx.read().unwrap();
|
||||
let blobdir = ctx.get_blobdir();
|
||||
|
||||
let msg_id = match dc::chat::send_msg(&ctx, self.chat_id, &mut delta_msg) {
|
||||
Ok(msg_id) => msg_id,
|
||||
@@ -53,7 +54,7 @@ impl telepathy::ChannelInterfaceMessages for Channel {
|
||||
};
|
||||
|
||||
let token = format!("{}", msg_id.to_u32());
|
||||
let dbus_parts = convert_msg(&delta_msg);
|
||||
let dbus_parts = convert_msg(blobdir, &delta_msg).map_err(|_| MethodErr::no_arg())?;
|
||||
|
||||
let messages_sig = telepathy::ChannelInterfaceMessagesMessageSent {
|
||||
content: dbus_parts,
|
||||
@@ -90,7 +91,7 @@ impl telepathy::ChannelInterfaceMessages for Channel {
|
||||
fn supported_content_types(&self) -> Result<Vec<String>> {
|
||||
println!("Channel::supported_content_types()");
|
||||
|
||||
Ok(vec!["text/plain".to_string()]) // TODO: image support
|
||||
Ok(vec!["*/*".to_string()])
|
||||
}
|
||||
|
||||
fn message_types(&self) -> Result<Vec<u32>> {
|
||||
@@ -111,13 +112,15 @@ impl telepathy::ChannelInterfaceMessages for Channel {
|
||||
|
||||
let mut out = Vec::<Vec<HashMap<String, VarArg>>>::new();
|
||||
let ctx = self.ctx.read().unwrap();
|
||||
let blobdir = ctx.get_blobdir();
|
||||
|
||||
for msg_id in dc::chat::get_chat_msgs(&ctx, self.chat_id, 0, None) {
|
||||
if let Ok(msg) = dc::message::Message::load_from_db(&ctx, msg_id) {
|
||||
match msg.get_state() {
|
||||
MessageState::InFresh | MessageState::InNoticed => {
|
||||
println!(" A message: {:?}", msg);
|
||||
out.push(convert_msg(&msg))
|
||||
let parts = convert_msg(blobdir, &msg).map_err(|_| MethodErr::no_arg())?;
|
||||
out.push(parts);
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
|
@@ -401,6 +401,7 @@ impl Connection {
|
||||
let chans = c2.read().unwrap();
|
||||
let u_ctx = ctx.clone();
|
||||
let ctx = u_ctx.read().unwrap();
|
||||
let blobdir = ctx.get_blobdir();
|
||||
|
||||
// Autocreate channel if it doesn't already exist
|
||||
// FIXME: unknown contacts need more care than this
|
||||
@@ -453,11 +454,16 @@ impl Connection {
|
||||
continue;
|
||||
}
|
||||
|
||||
let parts = convert_msg(&msg);
|
||||
let parts = convert_msg(blobdir, &msg);
|
||||
if parts.is_err() {
|
||||
println!("can't convert, skipping: {}", parts.unwrap_err());
|
||||
continue;
|
||||
}
|
||||
|
||||
let sig =
|
||||
telepathy::ChannelInterfaceMessagesMessageReceived { message: parts }
|
||||
.to_emit_message(&chan_path);
|
||||
let sig = telepathy::ChannelInterfaceMessagesMessageReceived {
|
||||
message: parts.unwrap(),
|
||||
}
|
||||
.to_emit_message(&chan_path);
|
||||
|
||||
actq.send(DbusAction::Signal(sig)).unwrap();
|
||||
|
||||
|
@@ -1,35 +1,47 @@
|
||||
use crate::padfoot::{var_i64, var_str, var_u32, VarArg};
|
||||
use crate::padfoot::{var_bytearray, var_i64, var_str, var_u32, VarArg};
|
||||
|
||||
use deltachat::message::Message;
|
||||
use dc::constants::Viewtype as Vt;
|
||||
use dc::message::Message;
|
||||
use deltachat as dc;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
type Part = HashMap<String, VarArg>;
|
||||
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||
|
||||
// Turns a deltachat::message::Message into a Telepathy Message_Part_List
|
||||
pub fn convert_msg(msg: &Message) -> Vec<HashMap<String, VarArg>> {
|
||||
pub fn convert_msg(blobdir: &std::path::Path, msg: &Message) -> Result<Vec<Part>> {
|
||||
if msg.is_setupmessage() {
|
||||
return convert_setupmessage(msg);
|
||||
return Ok(convert_setupmessage(msg));
|
||||
}
|
||||
|
||||
let mut parts = vec![build_props(msg)];
|
||||
let mut parts = vec![make_props(msg)];
|
||||
|
||||
if let Some(text) = msg.get_text() {
|
||||
parts.push(build_plain(&text));
|
||||
}
|
||||
// TODO: Check. Can a deltachat message have multiple parts? Can an image
|
||||
// viewtype have text as well?
|
||||
let result = match msg.get_viewtype() {
|
||||
Vt::Text => build_txt(msg),
|
||||
Vt::Unknown => build_unknown(msg),
|
||||
Vt::Audio | Vt::Voice => build_snd(msg),
|
||||
Vt::Video => build_vid(msg),
|
||||
_ => build_attachment(blobdir, msg),
|
||||
};
|
||||
|
||||
// TODO: other parts. Can a deltachat message have multiple parts?
|
||||
|
||||
parts
|
||||
result.map(|mut more| {
|
||||
parts.append(&mut more);
|
||||
parts
|
||||
})
|
||||
}
|
||||
|
||||
fn convert_setupmessage(msg: &Message) -> Vec<HashMap<String, VarArg>> {
|
||||
fn convert_setupmessage(msg: &Message) -> Vec<Part> {
|
||||
let msg_id = msg.get_id();
|
||||
vec![
|
||||
build_props(msg),
|
||||
build_plain(&format!("Setup message received. To apply it, reply with:\nIMEX: {} nnnn-nnnn-nnnn-nnnn-nnnn-nnnn-nnnn-nnnn-nnnn\nNo whitespace in the setup-code!", msg_id.to_u32())),
|
||||
make_props(msg),
|
||||
make_plain(&format!("Setup message received. To apply it, reply with:\nIMEX: {} nnnn-nnnn-nnnn-nnnn-nnnn-nnnn-nnnn-nnnn-nnnn\nNo whitespace in the setup-code!", msg_id.to_u32())),
|
||||
]
|
||||
}
|
||||
|
||||
fn build_props(msg: &Message) -> HashMap<String, VarArg> {
|
||||
fn make_props(msg: &Message) -> Part {
|
||||
let msg_id = msg.get_id();
|
||||
let mut out = HashMap::new();
|
||||
|
||||
@@ -63,14 +75,65 @@ fn build_props(msg: &Message) -> HashMap<String, VarArg> {
|
||||
out
|
||||
}
|
||||
|
||||
fn build_plain(text: &str) -> HashMap<String, VarArg> {
|
||||
fn make_plain(text: &str) -> Part {
|
||||
make_content("text/plain", None, var_str(text.to_string()))
|
||||
}
|
||||
|
||||
fn make_content(type_: &str, id: Option<&str>, content: VarArg) -> Part {
|
||||
let mut out = HashMap::new();
|
||||
|
||||
out.insert(
|
||||
"content-type".to_string(),
|
||||
var_str("text/plain".to_string()),
|
||||
);
|
||||
out.insert("content".to_string(), var_str(text.to_string()));
|
||||
out.insert("content-type".to_string(), var_str(type_.to_string()));
|
||||
out.insert("content".to_string(), content);
|
||||
|
||||
id.map(|txt| out.insert("identifier".to_string(), var_str(txt.to_string())));
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
fn build_snd(_msg: &Message) -> Result<Vec<Part>> {
|
||||
Ok(vec![make_plain("(a sound file was received)")])
|
||||
}
|
||||
|
||||
fn build_txt(msg: &Message) -> Result<Vec<Part>> {
|
||||
Ok(vec![make_plain(
|
||||
&msg.get_text().unwrap_or_else(|| "".to_string()),
|
||||
)])
|
||||
}
|
||||
|
||||
fn build_unknown(_msg: &Message) -> Result<Vec<Part>> {
|
||||
Ok(vec![make_plain("(a message of unknown type was received)")])
|
||||
}
|
||||
|
||||
fn build_vid(_msg: &Message) -> Result<Vec<Part>> {
|
||||
Ok(vec![make_plain("(a video was received)")])
|
||||
}
|
||||
|
||||
// The message contains a file. Detect the content-type and construct a part
|
||||
// containing the data in full.
|
||||
fn build_attachment(blobdir: &std::path::Path, msg: &Message) -> Result<Vec<Part>> {
|
||||
let mime = msg
|
||||
.get_filemime()
|
||||
.unwrap_or_else(|| "application/octet-stream".to_string());
|
||||
let filename = msg.get_filename().ok_or("Failed to get filename")?;
|
||||
|
||||
let path: std::path::PathBuf = [blobdir, &std::path::Path::new(&filename)].iter().collect();
|
||||
// let mut path = std::path::PathBuf::from(blobdir);
|
||||
// path.push(filename);
|
||||
|
||||
let data =
|
||||
std::fs::read(&path).map_err(|e| format!("Failed to read file {:?}: {}", path, e))?;
|
||||
|
||||
println!("MIME type for attachment: {}", mime);
|
||||
|
||||
let html = make_content(
|
||||
"text/html",
|
||||
None,
|
||||
var_str("<img src=\"cid:picture\" />".to_string()),
|
||||
);
|
||||
|
||||
let txt = make_plain("(an image was sent but cannot be displayed)");
|
||||
|
||||
let blob = make_content(&mime, Some("picture"), var_bytearray(data));
|
||||
|
||||
Ok(vec![html, txt, blob])
|
||||
}
|
||||
|
@@ -20,6 +20,10 @@ pub fn var_bool(item: bool) -> VarArg {
|
||||
var_arg(Box::new(item))
|
||||
}
|
||||
|
||||
pub fn var_bytearray(item: std::vec::Vec<u8>) -> VarArg {
|
||||
var_arg(Box::new(item))
|
||||
}
|
||||
|
||||
pub fn var_u32(item: u32) -> VarArg {
|
||||
var_arg(Box::new(item))
|
||||
}
|
||||
|
Reference in New Issue
Block a user