From b814a9aab033dd82849290f5429c48f535077a06 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Sun, 17 May 2020 03:01:21 +0100 Subject: [PATCH] Partially on the way to receiving an incoming message This is getting really ugly, but let's run with it for now. --- src/padfoot/channel.rs | 28 +++++------- src/padfoot/channel/channel.rs | 2 +- src/padfoot/channel/messages.rs | 2 +- src/padfoot/channel/type_text.rs | 2 +- src/padfoot/connection.rs | 76 ++++++++++++++++++++++++++------ 5 files changed, 77 insertions(+), 33 deletions(-) diff --git a/src/padfoot/channel.rs b/src/padfoot/channel.rs index f291469..b19992d 100644 --- a/src/padfoot/channel.rs +++ b/src/padfoot/channel.rs @@ -9,6 +9,7 @@ mod type_text; pub use type_text::*; use crate::telepathy; +use std::sync::Arc; // FIXME: I'm assuming that all channels will be of type text and 1-1 for now. #[derive(Debug)] @@ -24,29 +25,24 @@ pub fn channel_interfaces() -> Vec { type Result = std::result::Result; impl Channel { - fn build_tree(self) -> dbus::tree::Tree { - let c_rc = std::rc::Rc::new(self); + pub fn build_object_path( + channel: Arc, + ) -> dbus::tree::ObjectPath { let f = dbus::tree::Factory::new_fn::<()>(); - let mut tree = f.tree(()); - let c_rc1 = c_rc.clone(); + let c_rc1 = channel.clone(); let chan_iface = telepathy::channel_server(&f, (), move |_| c_rc1.clone()); - let c_rc2 = c_rc.clone(); + let c_rc2 = channel.clone(); let messages_iface = telepathy::channel_interface_messages_server(&f, (), move |_| c_rc2.clone()); - let type_text_iface = telepathy::channel_type_text_server(&f, (), move |_| c_rc.clone()); + let type_text_iface = telepathy::channel_type_text_server(&f, (), move |_| channel.clone()); - tree = tree.add( - f.object_path("", ()) - .introspectable() - .add(chan_iface) - .add(messages_iface) - .add(type_text_iface), - ); - tree = tree.add(f.object_path("/", ()).introspectable()); - - tree + f.object_path("", ()) + .introspectable() + .add(chan_iface) + .add(messages_iface) + .add(type_text_iface) } } diff --git a/src/padfoot/channel/channel.rs b/src/padfoot/channel/channel.rs index 751b0ae..02d491a 100644 --- a/src/padfoot/channel/channel.rs +++ b/src/padfoot/channel/channel.rs @@ -4,7 +4,7 @@ use dbus::tree::MethodErr; use super::{Channel, Result}; -impl AsRef for std::rc::Rc { +impl AsRef for std::sync::Arc { fn as_ref(&self) -> &(dyn telepathy::Channel + 'static) { &**self } diff --git a/src/padfoot/channel/messages.rs b/src/padfoot/channel/messages.rs index a6ab398..eb25fd5 100644 --- a/src/padfoot/channel/messages.rs +++ b/src/padfoot/channel/messages.rs @@ -6,7 +6,7 @@ use std::collections::HashMap; use super::{Channel, Result}; -impl AsRef for std::rc::Rc { +impl AsRef for std::sync::Arc { fn as_ref(&self) -> &(dyn telepathy::ChannelInterfaceMessages + 'static) { &**self } diff --git a/src/padfoot/channel/type_text.rs b/src/padfoot/channel/type_text.rs index 883806f..a6bbdea 100644 --- a/src/padfoot/channel/type_text.rs +++ b/src/padfoot/channel/type_text.rs @@ -3,7 +3,7 @@ use dbus::tree::MethodErr; use super::{Channel, Result}; -impl AsRef for std::rc::Rc { +impl AsRef for std::sync::Arc { fn as_ref(&self) -> &(dyn telepathy::ChannelTypeText + 'static) { &**self } diff --git a/src/padfoot/connection.rs b/src/padfoot/connection.rs index 4ba00e9..cf2dd2b 100644 --- a/src/padfoot/connection.rs +++ b/src/padfoot/connection.rs @@ -24,7 +24,7 @@ use crate::padfoot::{Channel, VarArg}; use crate::telepathy; use dbus::blocking::{stdintf::org_freedesktop_dbus::RequestNameReply, LocalConnection}; -use dbus::channel::Sender; +use dbus::channel::{MatchingReceiver, Sender}; use dbus::tree::MethodErr; use dc::config::Config; @@ -43,9 +43,12 @@ pub const CONN_OBJECT_PATH: &str = "/org/freedesktop/Telepathy/Connection/padfoo // outside of method return values requires one of these to be added to actq #[derive(Debug)] enum DbusAction { - Signal(dbus::Message), // Generic signal to send + Signal(dbus::Message), // Generic signal to send + NewChannel(Channel), // Add this channel CloseChannel(dbus::Path<'static>), // Close this channel + + IncomingMessage(dc::chat::ChatId, dc::message::MsgId), // Look at this \o/ } #[derive(Debug)] @@ -55,7 +58,7 @@ pub struct Connection { actq: Arc>>, // Channels we own - channels: Arc, Channel>>>, + channels: Arc, Arc>>>, // Owned by the CM. Remove ourselves from this when done conns: Arc>>, @@ -131,7 +134,7 @@ impl Connection { let id = settings.id(); // Use this if we need to send messages in response to DC events: - // let acqt2 = actq.clone(); + let queue = actq.clone(); let f = move |_c: &Context, e: Event| { match e { Event::Info(msg) => println!("Connection<{}>: INFO: {}", id, msg), @@ -145,15 +148,33 @@ impl Connection { Event::ImapConnected(msg) | Event::SmtpConnected(msg) => { println!("Connection<{}>: Network: {}", id, msg); } + Event::MsgsChanged { chat_id, msg_id } => { + println!( + "Connection<{}>: Messages changed for {}: {}", + id, chat_id, msg_id + ); + let q = queue.clone(); + q.lock() + .unwrap() + .push_back(DbusAction::IncomingMessage(chat_id, msg_id)); + } + Event::IncomingMsg { chat_id, msg_id } => { + println!( + "Connection<{}>: Incoming message for {}: {}", + id, chat_id, msg_id + ); + let q = queue.clone(); + q.lock() + .unwrap() + .push_back(DbusAction::IncomingMessage(chat_id, msg_id)); + } + /* Unhandled messages: SmtpMessageSent(String), ImapMessageDeleted(String), - ImapMessageMoved(String), ImapFolderEmptied(String), NewBlobFile(String), DeletedBlobFile(String), - MsgsChanged - IncomingMsg MsgDelivered MsgFailed MsgRead @@ -165,6 +186,7 @@ impl Connection { SecurejoinInviterProgress SecurejoinJoinerProgress */ + Event::ImapMessageMoved(_) | Event::ImapMessageDeleted(_) => {} _ => println!("Connection<{}>: unhandled event received: {:?}", id, e), }; }; @@ -194,7 +216,9 @@ impl Connection { conns, settings, actq, - channels: Arc::new(RwLock::new(HashMap::, Channel>::new())), + channels: Arc::new(RwLock::new( + HashMap::, Arc>::new(), + )), ctx: Arc::new(RwLock::new(ctx)), state: Arc::new(RwLock::new(ConnState::Initial)), }) @@ -225,7 +249,19 @@ impl Connection { } }; - tree.start_receive(&c); + let tc = tree.clone(); + c.start_receive( + dbus::message::MatchRule::new_method_call(), + Box::new(move |msg, c| { + let tree = tc.lock().unwrap(); + if let Some(replies) = tree.handle(&msg) { + for r in replies { + let _ = c.send(r); + } + } + true + }), + ); match c.request_name(bus.clone(), false, false, true) { Ok(RequestNameReply::Exists) => { @@ -267,20 +303,32 @@ impl Connection { } } DbusAction::NewChannel(channel) => { + let path = channel.path.clone(); + let rc_channel = Arc::new(channel); + Arc::clone(&chans) .write() .unwrap() - .insert(channel.path.clone(), channel); + .insert(path.clone(), rc_channel.clone()); - // TODO: add channel to tree + let t2 = tree.clone(); + let op = Channel::build_object_path(rc_channel); + + t2.lock().unwrap().insert(op); // TODO: emit signals } DbusAction::CloseChannel(path) => { let _chan = Arc::clone(&chans).write().unwrap().remove(&path); + let t2 = tree.clone(); - // TODO: add channel to tree + t2.lock().unwrap().remove(&path); // TODO: emit signals } + DbusAction::IncomingMessage(_chat_id, _msg_id) => { + // TODO: check if we have a channel for the chat + // If not, create one + // If we do, send the message down it + } } } } @@ -303,7 +351,7 @@ impl Connection { self.settings.path() } - fn build_tree(self) -> dbus::tree::Tree { + fn build_tree(self) -> Arc>> { let path = self.path(); let c_rc = std::rc::Rc::new(self); let f = dbus::tree::Factory::new_fn::<()>(); @@ -343,6 +391,6 @@ impl Connection { ); tree = tree.add(f.object_path("/", ()).introspectable()); - tree + Arc::new(Mutex::new(tree)) } }