Partially on the way to receiving an incoming message

This is getting really ugly, but let's run with it for now.
This commit is contained in:
2020-05-17 03:01:21 +01:00
parent 49362a6606
commit b814a9aab0
5 changed files with 77 additions and 33 deletions

View File

@@ -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<String> {
type Result<T> = std::result::Result<T, dbus::tree::MethodErr>;
impl Channel {
fn build_tree(self) -> dbus::tree::Tree<dbus::tree::MTFn, ()> {
let c_rc = std::rc::Rc::new(self);
pub fn build_object_path(
channel: Arc<Channel>,
) -> dbus::tree::ObjectPath<dbus::tree::MTFn, ()> {
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)
}
}

View File

@@ -4,7 +4,7 @@ use dbus::tree::MethodErr;
use super::{Channel, Result};
impl AsRef<dyn telepathy::Channel + 'static> for std::rc::Rc<Channel> {
impl AsRef<dyn telepathy::Channel + 'static> for std::sync::Arc<Channel> {
fn as_ref(&self) -> &(dyn telepathy::Channel + 'static) {
&**self
}

View File

@@ -6,7 +6,7 @@ use std::collections::HashMap;
use super::{Channel, Result};
impl AsRef<dyn telepathy::ChannelInterfaceMessages + 'static> for std::rc::Rc<Channel> {
impl AsRef<dyn telepathy::ChannelInterfaceMessages + 'static> for std::sync::Arc<Channel> {
fn as_ref(&self) -> &(dyn telepathy::ChannelInterfaceMessages + 'static) {
&**self
}

View File

@@ -3,7 +3,7 @@ use dbus::tree::MethodErr;
use super::{Channel, Result};
impl AsRef<dyn telepathy::ChannelTypeText + 'static> for std::rc::Rc<Channel> {
impl AsRef<dyn telepathy::ChannelTypeText + 'static> for std::sync::Arc<Channel> {
fn as_ref(&self) -> &(dyn telepathy::ChannelTypeText + 'static) {
&**self
}

View File

@@ -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<Mutex<VecDeque<DbusAction>>>,
// Channels we own
channels: Arc<RwLock<HashMap<dbus::Path<'static>, Channel>>>,
channels: Arc<RwLock<HashMap<dbus::Path<'static>, Arc<Channel>>>>,
// Owned by the CM. Remove ourselves from this when done
conns: Arc<Mutex<HashSet<String>>>,
@@ -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::<dbus::Path<'static>, Channel>::new())),
channels: Arc::new(RwLock::new(
HashMap::<dbus::Path<'static>, Arc<Channel>>::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<dbus::tree::MTFn, ()> {
fn build_tree(self) -> Arc<Mutex<dbus::tree::Tree<dbus::tree::MTFn, ()>>> {
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))
}
}