Files
telepathy-padfoot/src/padfoot/connection/requests.rs

137 lines
4.6 KiB
Rust
Raw Normal View History

use crate::padfoot::{get_var_str, get_var_u32, requestables, Channel, DbusAction, VarArg};
use crate::telepathy;
2020-05-28 02:15:25 +01:00
use async_std::task::block_on;
use dbus::tree::MethodErr;
use dc::contact::Contact;
use deltachat as dc;
use std::collections::HashMap;
use super::Connection;
2020-05-17 00:49:46 +01:00
type ChannelSpec = (
dbus::Path<'static>, // Object path on this connection
HashMap<String, VarArg>, // Map of channel property -> value
);
type RequestableChannelSpec = (HashMap<String, VarArg>, Vec<String>);
type Result<T> = std::result::Result<T, MethodErr>;
impl AsRef<dyn telepathy::ConnectionInterfaceRequests + 'static> for std::rc::Rc<Connection> {
fn as_ref(&self) -> &(dyn telepathy::ConnectionInterfaceRequests + 'static) {
&**self
}
}
impl telepathy::ConnectionInterfaceRequests for Connection {
fn create_channel(
&self,
request: HashMap<&str, VarArg>,
2020-05-17 00:49:46 +01:00
) -> Result<(dbus::Path<'static>, HashMap<String, VarArg>)> {
println!("Connection<{}>::create_channel({:?})", self.id(), request);
Err(MethodErr::no_arg()) // FIXME: should be NotImplemented?
}
fn ensure_channel(
&self,
request: HashMap<&str, VarArg>,
2020-05-17 00:49:46 +01:00
) -> Result<(bool, dbus::Path<'static>, HashMap<String, VarArg>)> {
let path = self.path().clone();
println!("Connection<{}>::ensure_channel({:?})", self.id(), request);
// Empathy sends this for the request:
//
// {
// "org.freedesktop.Telepathy.Channel.TargetID": Variant("me@example.com"),
// "org.freedesktop.Telepathy.Channel.TargetHandleType": Variant(1),
// "org.freedesktop.Telepathy.Channel.ChannelType": Variant("org.freedesktop.Telepathy.Channel.Type.Text")
// }
// FIXME: life would be easier with TargetHandle
let target_id = request
.get("org.freedesktop.Telepathy.Channel.TargetID")
.map(|va| get_var_str(va))
.unwrap();
let target_handle_type = request
.get("org.freedesktop.Telepathy.Channel.TargetHandleType")
.map(|va| get_var_u32(va))
.unwrap();
let channel_type = request
.get("org.freedesktop.Telepathy.Channel.ChannelType")
.map(|va| get_var_str(va))
.unwrap();
// Text only
if channel_type != "org.freedesktop.Telepathy.Channel.Type.Text" {
println!(" Wrong channel type: {:?}", channel_type);
return Err(MethodErr::no_arg());
};
// IMs only
if target_handle_type != 1 {
println!(" Wrong target handle type: {:?}", target_handle_type);
return Err(MethodErr::no_arg());
};
let ctx = self.ctx.read().unwrap();
let target_handle =
2020-05-28 02:15:25 +01:00
block_on(Contact::lookup_id_by_addr(&ctx, target_id.clone(), dc::contact::Origin::Unknown));
if target_handle == 0 {
println!("Couldn't find target handle for {}", target_id);
return Err(MethodErr::no_arg());
};
let chat_id = dc::chat::ChatId::new(target_handle);
let channel_path = Connection::build_channel_path(path, chat_id);
// Return an existing channel if it already exists
let chans = self.channels.read().unwrap();
if let Some(channel) = chans.get(&channel_path) {
return Ok((false, channel_path, channel.chan_props()));
}
// Now we need to discover or create a chat id for the contact
2020-05-28 02:15:25 +01:00
let chat_id = block_on(dc::chat::create_by_contact_id(&ctx, target_handle)).unwrap();
let channel = Channel::new(
self.actq.clone(),
chat_id,
self.ctx.clone(),
2020-05-21 10:49:33 +01:00
dc::constants::DC_CONTACT_ID_SELF, // initiator is self in this case
channel_path.clone(),
true, // requested
target_handle,
);
let response = channel.chan_props(); // FIXME: fill with data about the channel
// Send signal
self.actq.send(DbusAction::NewChannel(channel)).unwrap();
Ok((true, channel_path, response))
}
2020-05-17 00:49:46 +01:00
fn channels(&self) -> Result<Vec<ChannelSpec>> {
println!("Connection<{}>::channels()", self.id());
2020-05-17 00:49:46 +01:00
let mut out = Vec::<ChannelSpec>::new();
for channel in self.channels.read().unwrap().values() {
out.push((
channel.path(),
2020-05-17 00:49:46 +01:00
HashMap::<String, VarArg>::new(), // FIXME: work out what props should be shown
));
}
Ok(out)
}
2020-05-17 00:49:46 +01:00
fn requestable_channel_classes(&self) -> Result<Vec<RequestableChannelSpec>> {
println!("Connection<{}>::requestable_channel_classes()", self.id());
2020-05-16 22:11:38 +01:00
Ok(requestables())
}
}