Compare commits

..

26 Commits

Author SHA1 Message Date
7707242d10 Merge branch 'async' 2020-05-28 09:38:48 +01:00
bd76603c54 Upgrade to Delta v1.33.0
Despite the incremental version number, this is a backward-incompatible
change, switching code to async. It does allow us to reduce the number
of threads significantly, though.
2020-05-28 09:37:50 +01:00
9e764d72a1 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?
2020-05-27 01:19:43 +01:00
b9faad742b Partial implementation of contact removal
Empathy needs you to cycle the connection before it notices.
2020-05-24 00:24:15 +01:00
370f5076a1 Add and set the "Bcc self" option. 2020-05-23 23:52:42 +01:00
373311e826 HAXXX: A crude form of setup message acceptance 2020-05-23 22:49:15 +01:00
67a8715a25 Add an (untested) service file 2020-05-23 17:57:37 +01:00
c773146b26 It's called Mobian, not Moblin 2020-05-23 17:51:39 +01:00
7b1b8bdc83 cargo-about output 2020-05-23 17:48:13 +01:00
d06badfc96 *sobbing subsides* 2020-05-23 16:05:05 +01:00
8dbd023718 More sobbing 2020-05-23 14:48:35 +01:00
7cee6348fd Cry in public 2020-05-23 14:35:26 +01:00
14aa639a4b Fight with mobile linux for a bit 2020-05-22 10:29:10 +01:00
efe97a33c4 Fix messages on self-initiated channels 2020-05-21 11:06:07 +01:00
d77d04e9b1 Fix messages on remote-initiated chats 2020-05-21 10:49:33 +01:00
db7ecc6d98 Add the ContactList interface to the manager file 2020-05-21 10:49:15 +01:00
15174ea03f Add a very broken ContactList + outgoing channel implementation
Right now, messages don't show on the padfoot side any more, but they
do get sent and received successfully on the other side, and empathy
can manage contacts now, so I'm calling it an overall win.
2020-05-21 02:30:47 +01:00
aae7607c7f Pin to the same version of rust nightly as delta 2020-05-19 00:16:01 +01:00
825f5d90ed Update compile and install instructions 2020-05-18 23:40:43 +01:00
a95be7ee4b Implement sending text messages
This works in a very simplistic way, but it's enough for two-way
communication. Hurrah!
2020-05-18 23:08:11 +01:00
72947bc99d Allow incoming messages to be seen by Empathy
MDNs don't work because the sender is not in a "real chat" yet- it's
coming from an unknown user - but we mark them as seen anyway.
2020-05-18 21:15:56 +01:00
b511dd873b Make text messages show on incoming 2020-05-18 19:37:35 +01:00
667eb3b3f6 By hook or by crook, amke empathy open a window 2020-05-18 01:57:22 +01:00
cb463336bc Rework automatic code generation 2020-05-17 23:23:45 +01:00
1e481d4c9a Wire up the additional channel interfaces a bit 2020-05-17 22:49:41 +01:00
e5e06c55f9 Reorder Channel::new args 2020-05-17 22:37:25 +01:00
145 changed files with 11031 additions and 986 deletions

812
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -9,8 +9,9 @@ license = "MIT"
[dependencies]
anyhow = "1.0"
async-std = "1.6"
dbus = "0.8"
deltachat = { git = "https://github.com/deltachat/deltachat-core-rust", tag="1.31.0" }
deltachat = { git = "https://github.com/deltachat/deltachat-core-rust", tag="1.34.0" }
directories = "2.0"
rand = "0.7"

146
README.md
View File

@@ -33,10 +33,10 @@ Here's where we're at right now:
- [x] Appear as online in Empathy
- [x] Disconnect!
- [ ] Set up an account manually
- [ ] Contacts handling
- [~] Text messages
- [~] Contacts handling
- [x] Text messages
- [ ] Multimedia messages
- [ ] Setup messages
- [~] Setup messages
- [ ] Import/Export
- [ ] Group chats
- [ ] Geolocation messages
@@ -52,9 +52,143 @@ learning exercise!
## How
### Compiling
This project is written in Rust, so you'll need a rust compiler to build it.
[Rustup]() comes highly recommended. Deltachat is also written in Rust and it
needs the `nightly` version, so follow the instructions for that.
[Rustup](https://github.com/rust-lang/rustup) comes highly recommended.
There is a [`rust-toolchain`](rust-toolchain) file that I try to keep synced
with the version of rust that
[`deltachat-core-rust`](https://github.com/deltachat/deltachat-core-rust)
uses.
Once you have a working rust compiler, just:
```
$ cargo build --release
```
to get a `telepathy-padfoot binary. Drop the release flag to make it build fast.
### Cross-compiling amd64 -> i386
If you need a 32-bit binary and you're on an am64 bit system, this seems to
work, as long as you have 32-bit versions of `libdbus-1` and `libssl` installed.
On Debian, the full sequence looks like:
```
$ dpkg --print-architecture
amd64
# dpkg --add-architecture i386
$ dpkg --print-foreign-architectures
i386
# apt update
# apt install libdbus-1-dev:i386 libssl-dev:i386
$ rustup target install i686-unknown-linux-gnu
$ PKG_CONFIG_ALLOW_CROSS=1 cargo build --target=i686-unknown-linux-gnu --release
```
This creates a 32-bit executable at `target/i686-unknown-linux-gnu/release/telepathy-padfoot`
I don't have a 32-bit machine to test this on, but happy to take fixes for it.
### Cross-compiling amd64 -> aarch64
This is a handy thing to do for linux phones, most of which use telepathy. Rust
is quite heavy to compile - it's a pain even on a pinebook pro, which is the
same architecture. Setup on a Debian machine is quite simple:
```
$ dpkg --print-architecture
amd64
# dpkg --add-architecture arm64
$ dpkg --print-foreign-architectures
arm64
# apt update
# apt install libdbus-1-dev:arm64 libssl-dev:arm64 gcc-aarch64-linux-gnu
$ rustup target install aarch64-unknown-linux-gnu
$ RUSTFLAGS="-C linker=aarch64-linux-gnu-gcc" PKG_CONFIG_ALLOW_CROSS=1 cargo build --target=aarch64-unknown-linux-gnu --release
```
We have to specify the linker because of [this bug](https://github.com/rust-lang/cargo/issues/4133).
Note that this doesn't create a static binary, so you'll need to match versions
for the shared libraries that are on the phone. In theory we can create static
binaries with musl, but openssl makes it hard. If you get it working, tell me
how!
UBTouch uses an ancient version of OpenSSL: 1.0.2g. KDE Neon does much better
with 1.1.1, so is easier to compile against.
An alternative approach to using multiarch (as above) is to use `debootstrap`
(or a similar tool) to get a sysroot containing libraries of all the right
versions. E.g. You can then add `-C link-args=--sysroot=/path/to/sysroot` to
`RUSTFLAGS` to use those libraries. Ufff. I've not got this working yet either.
...I'm compiling it directly on the phone. Not ideal. Add swap.
Compiling directly on the phone, using KDE Neon, I can get Padfoot running at
the same time as [Spacebar](https://invent.kde.org/plasma-mobile/spacebar),
which is a Telepathy client. I can see that Padfoot is checked for protocols,
but I don't see a way to start a connection with it yet. Next step for this is
to get Spacebar built and running locally, for a better debugging experience.
postmarketOS is more difficult. It's an `aarch64...musl` target. Rustup doesn't
support this, and the `rustc` included in the repositories is stable, not
nightly, so compiling directly on the phone is very difficult. Cross-compile is
likely the way to go here, in the end, but I need to get one of the two tries
above working first. Spacebar is available, but Empathy is not.
Phosh uses Chatty, which is based on libpurple, so doesn't work with Padfoot.
In the end, I tried Mobian. This is regular ordinary Debian Bullseye, plus a few
Phosh packages. Installing Empathy and Padfoot together (Chatty is bundled but
doesn't work), I have a working setup \o/ - although there are many warts, I can
use Deltachat on Linux Mobile in at least one configuration.
I'll probably keep Mobian for a while though, it's exactly what I want in a
mobile phone. Yes, I am peculiar.
### Installing
There is a `share/` directory in this project that contains a bunch of files.
They should be placed into `/usr/share`, following the same layout. Then put
the binary into `/usr/lib/telepathy/telepathy-padfoot`.
I should probably put this into the makefile.
### Running
D-Bus activation is not enabled yet, since it gets in the way of disaster-driven
development. Just run the `telepathy-padfoot` binary as the same user that your
chat client will be running as. It registers to the DBUS **session bus**, and
will be picked up next time your chat client scans (which may need a restart).
### Setup messages
If you send an autocrypt setup message while a padfoot connection is up, it will
notice it and open a channel asking you to reply with a message like:
```
IMEX: <id> nnnn-nnnn-nnnn-nnnn-nnnn-nnnn-nnnn-nnnn-nnnn
```
The ID is the delta-generated message ID, while the rest is the setup code. No
whitespace!
This bit is still extremely janky; it should instead be a magic channel type or
action button of some kind. It is, however, functional.
Delta wants us to enable the "Send copy to self" option in settings. That's
exposed as "Bcc self" in the advanced options in Empathy. Once enabled, messages
you send via Padfoot will appear in other clients. However, messages you send
from other clients don't appear in Padfoot yet because it mostly ignores self
messages as a dirty hack to avoid double-showing messages. Progess though.
### Autogenerated telepathy DBUS bindings
It makes use of the `dbus-codegen-rust` crate to convert the
[telepathy interface specs](https://github.com/TelepathyIM/telepathy-spec) into
@@ -70,4 +204,4 @@ $ ./scripts/dbus-codegen
`dbus-codegen-rust` doesn't seem to handle namespaced attributes properly, so
we modify the XML files in `telepathy-spec`... with `sed`. The `tp:type`
attribute is renamed to `tp:typehint`.
attribute is renamed to `tp:typehint`. This will be fixed in the next release.

70
about.hbs Normal file
View File

@@ -0,0 +1,70 @@
<html>
<head>
<style>
@media (prefers-color-scheme: dark) {
body {
background: #333;
color: white;
}
a {
color: skyblue;
}
}
.container {
font-family: sans-serif;
max-width: 800px;
margin: 0 auto;
}
.intro {
text-align: center;
}
.licenses-list {
list-style-type: none;
margin: 0;
padding: 0;
}
.license-used-by {
margin-top: -10px;
}
.license-text {
max-height: 200px;
overflow-y: scroll;
white-space: pre-wrap;
}
</style>
</head>
<body>
<main class="container">
<div class="intro">
<h1>Third Party Licenses</h1>
<p>This page lists the licenses of the projects used in telepathy-padfoot.</p>
</div>
<h2>Overview of licenses:</h2>
<ul class="licenses-overview">
{{#each overview}}
<li><a href="#{{id}}">{{name}}</a> ({{count}})</li>
{{/each}}
</ul>
<h2>All license text:</h2>
<ul class="licenses-list">
{{#each licenses}}
<li class="license">
<h3 id="{{id}}">{{name}}</h3>
<h4>Used by:</h4>
<ul class="license-used-by">
{{#each used_by}}
<li><a href="{{#if crate.repository}} {{crate.repository}} {{else}} https://crates.io/crates/{{crate.name}} {{/if}}">{{crate.name}} {{crate.version}}</a></li>
{{/each}}
</ul>
<pre class="license-text">{{text}}</pre>
</li>
{{/each}}
</ul>
</main>
</body>
</html>

11
about.toml Normal file
View File

@@ -0,0 +1,11 @@
accepted = [
"0BSD",
"Apache-2.0",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"CC0-1.0",
"MIT",
"MPL-2.0",
"Zlib"
]

9555
license.html Normal file

File diff suppressed because it is too large Load Diff

1
rust-toolchain Normal file
View File

@@ -0,0 +1 @@
nightly-2020-03-12

View File

@@ -31,11 +31,9 @@ for file in $(ls -a $specs/*.xml); do
-a AsRefClosure \
-o "$out"
sed -i '1s/^/#![allow(clippy::all)]\n\n/' "$out"
rustfmt "$out"
echo "\nmod $name;\npub use self::$name::*;" >> "$modfile"
echo "\n#[allow(clippy::all)]\nmod $name;\npub use self::$name::*;" >> "$modfile"
done
git -C telepathy-spec checkout -- .

View File

@@ -5,21 +5,22 @@ BusName=org.freedesktop.Telepathy.ConnectionManager.padfoot
ObjectPath=/org/freedesktop/Telepathy/ConnectionManager/padfoot
[Protocol delta]
Interfaces=org.freedesktop.Telepathy.Protocol.Interface.Presence;
param-account=s required
param-password=s required secret
param-bcc-self=b
status-available=2 settable
status-offline = 1 settable
AuthenticationTypes=org.freedesktop.Telepathy.Channel.Type.ServerTLSConnection;
ConnectionInterfaces=org.freedesktop.Telepathy.Connection.Interface.Avatars;org.freedesktop.Telepathy.Connection.Interface.Contacts;org.freedesktop.Telepathy.Connection.Interface.Requests;org.freedesktop.Telepathy.Connection.Interface.SimplePresence;
ConnectionInterfaces=org.freedesktop.Telepathy.Connection.Interface.Avatars;org.freedesktop.Telepathy.Connection.Interface.Contacts;org.freedesktop.Telepathy.Connection.Interface.ContactList;org.freedesktop.Telepathy.Connection.Interface.Requests;org.freedesktop.Telepathy.Connection.Interface.SimplePresence;
EnglishName=Delta Chat
Icon=im-delta
Interfaces=
Interfaces=org.freedesktop.Telepathy.Protocol;org.freedesktop.Telepathy.Protocol.Interface.Presence;
RequestableChannelClasses=text;
VCardField=email
[text]
Interfaces=org.freedesktop.Telepathy.Channel.Interface.Messages;
org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text
org.freedesktop.Telepathy.Channel.TargetHandleType u=1
allowed=org.freedesktop.Telepathy.Channel.TargetHandle;org.freedesktop.Telepathy.Channel.TargetID;
allowed=org.freedesktop.Telepathy.Channel.TargetHandle;org.freedesktop.Telepathy.Channel.TargetID;org.freedesktop.Telepathy.Channel.Interface.Messages;

View File

@@ -7,6 +7,9 @@ pub use self::connection::*;
mod connection_manager;
pub use self::connection_manager::*;
mod message;
pub use self::message::*;
mod protocol;
pub use self::protocol::*;

View File

@@ -8,11 +8,14 @@ pub use messages::*;
mod type_text;
pub use type_text::*;
use crate::padfoot::DbusAction;
use crate::padfoot::{var_bool, var_str, var_str_vec, var_u32, DbusAction, VarArg};
use crate::telepathy;
use async_std::task::block_on;
use deltachat as dc;
use std::sync::{mpsc, Arc, RwLock};
use std::collections::HashMap;
use std::sync::{mpsc, Arc};
type Result<T> = std::result::Result<T, dbus::tree::MethodErr>;
@@ -31,9 +34,12 @@ pub const HANDLE_TYPE_GROUP: HandleType = 4; // Deprecated
// FIXME: I'm assuming that all channels will be of type text and 1-1 for now.
#[derive(Debug)]
pub struct Channel {
ctx: Arc<RwLock<dc::context::Context>>,
actq: mpsc::Sender<DbusAction>,
chat_id: dc::chat::ChatId,
ctx: Arc<dc::context::Context>,
initiator_handle: u32,
path: dbus::Path<'static>,
requested: bool,
target_handle: u32, // Who we're talking to
}
@@ -44,19 +50,66 @@ pub fn channel_interfaces() -> Vec<String> {
impl Channel {
pub fn new(
ctx: Arc<RwLock<dc::context::Context>>,
path: dbus::Path<'static>,
target_handle: u32,
actq: mpsc::Sender<DbusAction>,
chat_id: dc::chat::ChatId,
ctx: Arc<dc::context::Context>,
initiator_handle: u32,
path: dbus::Path<'static>,
requested: bool,
target_handle: u32,
) -> Self {
Channel {
ctx,
path,
target_handle,
actq,
chat_id,
ctx,
initiator_handle,
path,
requested,
target_handle,
}
}
// FIXME: we should be able to introspect this already???
pub fn chan_props(&self) -> HashMap<String, VarArg> {
let mut out = HashMap::<String, VarArg>::new();
out.insert(
"org.freedesktop.Telepathy.Channel.ChannelType".to_string(),
var_str(self.chan_type()),
);
out.insert(
"org.freedesktop.Telepathy.Channel.TargetHandleType".to_string(),
var_u32(self.handle_type()),
);
out.insert(
"org.freedesktop.Telepathy.Channel.InitiatorHandle".to_string(),
var_u32(self.initiator_handle),
);
out.insert(
"org.freedesktop.Telepathy.Channel.InitiatorID".to_string(),
var_str(self.initiator_contact().unwrap().get_addr().to_string()),
);
out.insert(
"org.freedesktop.Telepathy.Channel.TargetHandle".to_string(),
var_u32(self.target_handle),
);
out.insert(
"org.freedesktop.Telepathy.Channel.TargetID".to_string(),
var_str(self.target_contact().unwrap().get_addr().to_string()),
);
out.insert(
"org.freedesktop.Telepathy.Channel.Requested".to_string(),
var_bool(self.requested),
);
out.insert(
"org.freedesktop.Telepathy.Channel.Interfaces".to_string(),
var_str_vec(vec![
"org.freedesktop.Telepathy.Channel.Interface.Messages".to_string()
]),
);
out
}
pub fn path(&self) -> dbus::Path<'static> {
self.path.clone()
}
@@ -73,16 +126,20 @@ impl Channel {
self.target_handle
}
fn target_contact(&self) -> Option<dc::contact::Contact> {
let ctx = self.ctx.read().unwrap();
dc::contact::Contact::get_by_id(&ctx, self.handle()).ok()
pub fn target_contact(&self) -> Option<dc::contact::Contact> {
block_on(dc::contact::Contact::get_by_id(&self.ctx, self.handle())).ok()
}
fn initiator_contact(&self) -> Option<dc::contact::Contact> {
let ctx = self.ctx.read().unwrap();
pub fn initiator_contact(&self) -> Option<dc::contact::Contact> {
block_on(dc::contact::Contact::get_by_id(
&self.ctx,
self.initiator_handle,
))
.ok() // FIXME: this will be wrong for outbound channels
}
dc::contact::Contact::get_by_id(&ctx, self.handle()).ok() // FIXME: this will be wrong for outbound channels
pub fn requested(&self) -> bool {
self.requested
}
pub fn build_object_path(
@@ -106,4 +163,35 @@ impl Channel {
.add(messages_iface)
.add(type_text_iface)
}
fn try_process_setupmsg(self: &Self, text: String) {
if !text.starts_with("IMEX: ") {
return;
};
// Expected form: "IMEX: <msg-id> <setupcode>
let mut iter = text.split_whitespace();
iter.next(); // Ignore the prefix
let msg_id = match iter.next() {
Some(txt) => match txt.parse::<u32>() {
Ok(id) => id,
_ => return,
},
_ => return,
};
let setup_code = match iter.next() {
Some(txt) => txt,
_ => return,
};
if let Err(e) = block_on(dc::imex::continue_key_transfer(
&self.ctx,
dc::message::MsgId::new(msg_id),
&setup_code,
)) {
println!("Failed to apply setup code {}: {}", msg_id, e);
}
}
}

View File

@@ -77,7 +77,7 @@ impl telepathy::Channel for Channel {
fn requested(&self) -> Result<bool> {
println!("Channel::requested()");
Ok(false) // FIXME: channels initiated by ourselves *will* be requested
Ok(self.requested) // FIXME: channels initiated by ourselves *will* be requested
}
fn initiator_handle(&self) -> Result<u32> {

View File

@@ -1,7 +1,12 @@
use crate::padfoot::VarArg;
use crate::padfoot::{convert_msg, DbusAction, VarArg};
use crate::telepathy;
use async_std::task::block_on;
use dbus::message::SignalArgs;
use dbus::tree::MethodErr;
use dc::constants::Viewtype;
use dc::message::{Message, MessageState};
use deltachat as dc;
use std::collections::HashMap;
use super::{Channel, Result};
@@ -13,9 +18,63 @@ impl AsRef<dyn telepathy::ChannelInterfaceMessages + 'static> for std::sync::Arc
}
impl telepathy::ChannelInterfaceMessages for Channel {
fn send_message(&self, message: Vec<HashMap<&str, VarArg>>, flags: u32) -> Result<String> {
println!("Channel::send_message({:?}, {})", message, flags);
Err(MethodErr::no_arg())
fn send_message(&self, parts: Vec<HashMap<&str, VarArg>>, flags: u32) -> Result<String> {
println!("Channel::send_message({:?}, {})", parts, flags);
if parts.len() != 2 {
return Err(MethodErr::no_arg());
}
let _meta = &parts[0];
let content = &parts[1];
let content_type = content["content-type"].0.as_str().unwrap();
if content_type != "text/plain" {
println!("FIXME: can only send text/plain messages right now");
return Err(MethodErr::no_arg());
}
let text_opt = content["content"].0.as_str().map(|s| s.to_string());
let mut delta_msg = Message::new(Viewtype::Text); // FIXME: this won't always be plaintext
delta_msg.set_text(text_opt.clone());
if let Some(text) = text_opt.clone() {
self.try_process_setupmsg(text);
};
let ctx = &self.ctx;
let blobdir = ctx.get_blobdir();
let msg_id = match block_on(dc::chat::send_msg(&ctx, self.chat_id, &mut delta_msg)) {
Ok(msg_id) => msg_id,
Err(e) => {
println!(" Failed to send message: {}", e);
return Err(MethodErr::no_arg());
}
};
let token = format!("{}", msg_id.to_u32());
let dbus_parts = convert_msg(blobdir, &delta_msg).map_err(|_| MethodErr::no_arg())?;
let messages_sig = telepathy::ChannelInterfaceMessagesMessageSent {
content: dbus_parts,
flags: 0,
message_token: token.clone(),
}
.to_emit_message(&self.path());
let text_sig = telepathy::ChannelTypeTextSent {
timestamp: delta_msg.get_timestamp() as u32,
type_: 0,
text: text_opt.or_else(|| Some("".to_string())).unwrap(),
}
.to_emit_message(&self.path());
self.actq.send(DbusAction::Signal(messages_sig)).unwrap();
self.actq.send(DbusAction::Signal(text_sig)).unwrap();
Ok(token)
}
fn get_pending_message_content(
@@ -32,26 +91,49 @@ impl telepathy::ChannelInterfaceMessages for Channel {
fn supported_content_types(&self) -> Result<Vec<String>> {
println!("Channel::supported_content_types()");
Err(MethodErr::no_arg())
Ok(vec!["*/*".to_string()])
}
fn message_types(&self) -> Result<Vec<u32>> {
println!("Channel::message_types()");
Err(MethodErr::no_arg())
Ok(vec![0]) // Normal messages. FIXME: MDNs too
}
fn message_part_support_flags(&self) -> Result<u32> {
println!("Channel::message_part_support_flags()");
Err(MethodErr::no_arg())
Ok(0) // FIXME: support multipart messages
}
// Return value is an array of array of message parts
fn pending_messages(&self) -> Result<Vec<Vec<HashMap<String, VarArg>>>> {
println!("Channel::pending_messages()");
Err(MethodErr::no_arg())
let mut out = Vec::<Vec<HashMap<String, VarArg>>>::new();
let ctx = &self.ctx;
let blobdir = ctx.get_blobdir();
for msg_id in block_on(dc::chat::get_chat_msgs(ctx, self.chat_id, 0, None)) {
if let Ok(msg) = block_on(dc::message::Message::load_from_db(ctx, msg_id)) {
match msg.get_state() {
MessageState::InFresh | MessageState::InNoticed => {
println!(" A message: {:?}", msg);
let parts = convert_msg(blobdir, &msg).map_err(|_| MethodErr::no_arg())?;
out.push(parts);
}
_ => continue,
}
}
}
Ok(out) // FIXME: check for pending messages
}
fn delivery_reporting_support(&self) -> Result<u32> {
println!("Channel::delivery_reporting_support()");
Err(MethodErr::no_arg())
Ok(0) // FIXME: MDNs
}
}

View File

@@ -1,5 +1,12 @@
use crate::padfoot::DbusAction;
use crate::telepathy;
use crate::telepathy::ChannelInterfaceMessages;
use async_std::task::block_on;
use dbus::message::SignalArgs;
use dbus::tree::MethodErr;
use dc::message::MsgId;
use deltachat as dc;
use super::{Channel, Result};
@@ -21,18 +28,42 @@ type PendingMessagesSpec = (
// Most of these methods are deprecated, so should be implemented in terms of
// the mandatory Messages interface.
impl telepathy::ChannelTypeText for Channel {
// ids is a list of deltachat msg_ids
fn acknowledge_pending_messages(&self, ids: Vec<u32>) -> Result<()> {
println!("Channel::acknowledge_pending_messages({:?})", ids);
Err(MethodErr::no_arg())
let mut msg_ids = Vec::<MsgId>::new();
for msg_id in &ids {
msg_ids.push(MsgId::new(*msg_id));
}
print!(" Marking messages as seen...");
let result = block_on(dc::message::markseen_msgs(&self.ctx, msg_ids));
if result {
println!("OK!");
// Emit a PendingMessagesRemoved signal only if all have been removed
let sig =
telepathy::ChannelInterfaceMessagesPendingMessagesRemoved { message_ids: ids }
.to_emit_message(&self.path());
self.actq.send(DbusAction::Signal(sig)).unwrap();
} else {
println!("FAILED!");
}
Ok(())
}
fn get_message_types(&self) -> Result<Vec<u32>> {
println!("Channel::get_message_types()");
Err(MethodErr::no_arg())
self.message_types()
}
fn list_pending_messages(&self, clear: bool) -> Result<Vec<PendingMessagesSpec>> {
println!("Channel::list_pending_messages({})", clear);
Err(MethodErr::no_arg())
}

View File

@@ -20,9 +20,10 @@ pub use self::requests::*;
mod simple_presence;
pub use self::simple_presence::*;
use crate::padfoot::{Channel, VarArg};
use crate::padfoot::{convert_msg, Channel, VarArg};
use crate::telepathy;
use async_std::task::block_on;
use dbus::blocking::{stdintf::org_freedesktop_dbus::RequestNameReply, LocalConnection};
use dbus::channel::{MatchingReceiver, Sender};
use dbus::message::SignalArgs;
@@ -35,6 +36,7 @@ use deltachat as dc;
use std::collections::{HashMap, HashSet};
use std::sync::{mpsc, Arc, Mutex, RwLock};
use std::thread;
use std::time::Duration;
pub const CONN_BUS_NAME: &str = "org.freedesktop.Telepathy.Connection.padfoot.delta";
@@ -66,7 +68,7 @@ pub struct Connection {
// Owned by the CM. Remove ourselves from this when done
conns: Arc<Mutex<HashSet<dbus::Path<'static>>>>,
ctx: Arc<RwLock<Context>>,
ctx: Arc<Context>, // Delta contexts are threadsafe
settings: ConnSettings,
state: Arc<RwLock<ConnState>>,
}
@@ -75,6 +77,7 @@ pub struct Connection {
pub struct ConnSettings {
account: String,
password: String,
bcc_self: bool,
id: String,
}
@@ -100,9 +103,24 @@ impl ConnSettings {
None => return err,
};
let bcc_self = match params.get("bcc-self") {
Some(variant) => match variant.0.as_u64() {
Some(i) => i != 0,
None => {
println!("0!");
return err;
}
},
None => {
println!("1!");
false
}
};
Ok(Self {
account,
password,
bcc_self,
id,
})
}
@@ -125,9 +143,11 @@ impl Connection {
settings: ConnSettings,
conns: Arc<Mutex<HashSet<dbus::Path<'static>>>>,
) -> Result<(Self, mpsc::Receiver<DbusAction>), MethodErr> {
let mut dbfile = directories::ProjectDirs::from("gs", "ur", "telepathy-padfoot")
.ok_or_else(MethodErr::no_arg)
.and_then(|p| Ok(p.data_local_dir().to_path_buf()))?;
let proj_dir = directories::ProjectDirs::from("gs", "ur", "telepathy-padfoot")
.ok_or_else(MethodErr::no_arg)?;
let mut dbfile = async_std::path::PathBuf::new();
dbfile.push(proj_dir.data_local_dir().to_str().unwrap());
dbfile.push(settings.id());
dbfile.push("db.sqlite3");
@@ -135,98 +155,104 @@ impl Connection {
let (q_s, q_r) = mpsc::channel::<DbusAction>();
let id = settings.id();
// The closure is shared between several different threads in delta, and
// we can't Send *or* clone the mpsc sender across them, so just wrap it
// in a mutex for now
let queue = Mutex::new(q_s.clone());
let f = move |_c: &Context, e: Event| {
match e {
Event::Info(msg) => println!("Connection<{}>: INFO: {}", id, msg),
Event::Warning(msg) => println!("Connection<{}>: WARN : {}", id, msg),
Event::Error(msg) | Event::ErrorNetwork(msg) | Event::ErrorSelfNotInGroup(msg) => {
println!("Connection<{}>: ERR : {}", id, msg)
}
Event::ConfigureProgress(progress) => {
println!("Connection<{}>: Configuration progress: {}", id, progress)
}
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
);
queue
.lock()
.unwrap()
.send(DbusAction::IncomingMessage(chat_id, msg_id))
.unwrap();
}
Event::IncomingMsg { chat_id, msg_id } => {
println!(
"Connection<{}>: Incoming message for {}: {}",
id, chat_id, msg_id
);
queue
.lock()
.unwrap()
.send(DbusAction::IncomingMessage(chat_id, msg_id))
.unwrap();
}
/* Unhandled messages:
SmtpMessageSent(String),
ImapMessageDeleted(String),
ImapFolderEmptied(String),
NewBlobFile(String),
DeletedBlobFile(String),
MsgDelivered
MsgFailed
MsgRead
ChatModified(ChatId),
ContactsChanged(Option<u32>),
LocationChanged(Option<u32>),
ImexProgress(usize),
ImexFileWritten(PathBuf),
SecurejoinInviterProgress
SecurejoinJoinerProgress
*/
Event::ImapMessageMoved(_) | Event::ImapMessageDeleted(_) => {}
_ => println!("Connection<{}>: unhandled event received: {:?}", id, e),
};
};
let ctx =
Context::new(Box::new(f), "telepathy-padfoot".to_string(), dbfile).map_err(|e| {
let ctx = Arc::new(
block_on(Context::new("telepathy-padfoot".to_string(), dbfile)).map_err(|e| {
println!(
"Connection<{}>::new(): couldn't get delta context: {}",
settings.id(),
e
);
MethodErr::no_arg() // FIXME: better error handling
})?;
})?,
);
ctx.set_config(Config::Addr, Some(&settings.account))
let e_ctx = ctx.clone();
let e_queue = q_s.clone();
thread::spawn(move || {
let emitter = e_ctx.get_event_emitter();
while let Some(e) = emitter.recv_sync() {
match e {
Event::Info(msg) => println!("Connection<{}>: INFO: {}", id, msg),
Event::Warning(msg) => println!("Connection<{}>: WARN : {}", id, msg),
Event::Error(msg)
| Event::ErrorNetwork(msg)
| Event::ErrorSelfNotInGroup(msg) => {
println!("Connection<{}>: ERR : {}", id, msg)
}
Event::ConfigureProgress(progress) => {
println!("Connection<{}>: Configuration progress: {}", id, progress)
}
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
);
e_queue
.send(DbusAction::IncomingMessage(chat_id, msg_id))
.unwrap();
}
Event::IncomingMsg { chat_id, msg_id } => {
println!(
"Connection<{}>: Incoming message for {}: {}",
id, chat_id, msg_id
);
e_queue
.send(DbusAction::IncomingMessage(chat_id, msg_id))
.unwrap();
}
/* Unhandled messages:
SmtpMessageSent(String),
ImapMessageDeleted(String),
ImapFolderEmptied(String),
NewBlobFile(String),
DeletedBlobFile(String),
MsgDelivered
MsgFailed
MsgRead
ChatModified(ChatId),
ContactsChanged(Option<u32>),
LocationChanged(Option<u32>),
ImexProgress(usize),
ImexFileWritten(PathBuf),
SecurejoinInviterProgress
SecurejoinJoinerProgress
*/
Event::ImapMessageMoved(_) | Event::ImapMessageDeleted(_) => {}
_ => println!("Connection<{}>: unhandled event received: {:?}", id, e),
};
}
});
block_on(ctx.set_config(Config::Addr, Some(&settings.account)))
.map_err(|_e| MethodErr::no_arg())?;
ctx.set_config(Config::MailPw, Some(&settings.password))
.map_err(|_e| MethodErr::no_arg())?;
ctx.set_config(Config::SentboxWatch, Some(&"Sent"))
block_on(ctx.set_config(Config::MailPw, Some(&settings.password)))
.map_err(|_e| MethodErr::no_arg())?;
if !ctx.is_configured() {
ctx.configure();
if settings.bcc_self {
block_on(ctx.set_config(Config::BccSelf, Some(&"1")))
.map_err(|_e| MethodErr::no_arg())?;
} else {
block_on(ctx.set_config(Config::BccSelf, Some(&"0")))
.map_err(|_e| MethodErr::no_arg())?;
}
if !block_on(ctx.is_configured()) {
block_on(ctx.configure()).unwrap();
};
Ok((
Connection {
conns,
settings,
actq: q_s,
channels: Arc::new(RwLock::new(
HashMap::<dbus::Path<'static>, Arc<Channel>>::new(),
)),
ctx: Arc::new(RwLock::new(ctx)),
conns,
ctx,
settings,
state: Arc::new(RwLock::new(ConnState::Initial)),
},
q_r,
@@ -309,7 +335,7 @@ impl Connection {
while let Some(act) = queue_receiver.try_recv().ok() {
match act {
DbusAction::Signal(msg) => {
print!("*** Connection<{}>: Sending message...", id);
print!("*** Connection<{}>: Sending signal: {:?}...", id, msg);
match c.send(msg) {
Err(e) => println!("error! {:?}", e), // FIXME: handle error better?
@@ -321,6 +347,7 @@ impl Connection {
let handle_type = channel.handle_type();
let handle = channel.handle();
let chan_path = channel.path().clone();
let chan_props = channel.chan_props();
let rc_channel = Arc::new(channel);
println!("*** Creating channel {}", chan_path);
@@ -336,7 +363,7 @@ impl Connection {
t2.lock().unwrap().insert(op);
let requests_sig = telepathy::ConnectionInterfaceRequestsNewChannels {
channels: vec![(chan_path.clone(), HashMap::new())],
channels: vec![(chan_path.clone(), chan_props)],
};
let legacy_sig = telepathy::ConnectionNewChannel {
@@ -373,52 +400,89 @@ impl Connection {
DbusAction::IncomingMessage(chat_id, msg_id) => {
println!("*** Incoming message: {} {}", chat_id, msg_id);
// TODO: check if we have a channel for the chat
let chan_path = dbus::strings::Path::new(format!(
"{}/{}",
path.clone(),
chat_id.to_u32()
))
.unwrap();
let chan_path = Connection::build_channel_path(path.clone(), chat_id);
let c2 = Arc::clone(&chans);
let chans = c2.read().unwrap();
//let u_ctx = ctx.clone();
let ctx = ctx.clone();
let blobdir = ctx.get_blobdir();
// Autocreate channel if it doesn't already exist
// FIXME: unknown contacts need more care than this
if chans.contains_key(&chan_path) {
println!(
"Message {} received for {}, passing it on is TODO!",
msg_id, chan_path
);
} else {
if !chans.contains_key(&chan_path) {
print!("Channel for {} doesn't exist yet, creating it...", chat_id);
let contacts =
dc::chat::get_chat_contacts(&ctx.clone().read().unwrap(), chat_id);
if contacts.is_empty() {
println!("empty chat! ignoring");
let contacts = block_on(dc::chat::get_chat_contacts(&ctx, chat_id));
if contacts.len() > 1 {
println!("...{} contacts in chat, ignoring!", contacts.len());
continue;
}
if contacts.len() > 1 {
println!("...{} contacts in chat, ignoring!", contacts.len())
}
let handle = contacts.first().unwrap();
let chan = Channel::new(ctx.clone(), chan_path, *handle, actq.clone());
// FIXME: device-specific chat isn't really a self-chat
let handle = contacts
.first()
.unwrap_or(&dc::constants::DC_CONTACT_ID_SELF);
let chan = Channel::new(
actq.clone(),
chat_id,
ctx.clone(),
*handle, // initiator is the remote contact
chan_path,
false, // FIXME: this needs to handle requested channels
*handle, // target is always the other party
);
actq.send(DbusAction::NewChannel(chan)).unwrap();
actq.send(act).unwrap();
println!("OK");
continue;
}
// Since the channel exists, emit new message signals
print!("Message {} received for {}...", msg_id, chan_path);
let msg = match block_on(dc::message::Message::load_from_db(&ctx, msg_id)) {
Ok(m) => m,
Err(e) => {
println!("Can't load from database, skipping: {}", e);
continue;
}
};
// Ignore messages that are self-originated.
// FIXME: special-case self-chats
if msg.get_from_id() == dc::constants::DC_CONTACT_ID_SELF
&& !msg.is_setupmessage()
{
println!("from ourselves, skipping");
continue;
}
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.unwrap(),
}
.to_emit_message(&chan_path);
actq.send(DbusAction::Signal(sig)).unwrap();
// FIXME: We MUST also send a Text.Received signal
println!("OK!");
}
DbusAction::FreshMessages => {
println!("*** FRESH MESSAGES");
let ctx_rc = ctx.clone();
let ctx = ctx_rc.read().unwrap();
let ctx = ctx.clone();
for msg_id in dc::context::Context::get_fresh_msgs(&ctx) {
for msg_id in block_on(dc::context::Context::get_fresh_msgs(&ctx)) {
println!(" FRESH MESSAGE: {}", msg_id);
match dc::message::Message::load_from_db(&ctx, msg_id) {
match block_on(dc::message::Message::load_from_db(&ctx, msg_id)) {
Ok(msg) => {
actq.send(DbusAction::IncomingMessage(
msg.get_chat_id(),
@@ -452,6 +516,15 @@ impl Connection {
self.settings.path()
}
fn build_channel_path(
path: dbus::Path<'static>,
chat_id: dc::chat::ChatId,
) -> dbus::strings::Path<'static> {
let path = format!("{}/{}", path, chat_id.to_u32());
dbus::strings::Path::new(path).expect("Must be valid")
}
fn build_tree(self) -> Arc<Mutex<dbus::tree::Tree<dbus::tree::MTFn, ()>>> {
let path = self.path();
let c_rc = std::rc::Rc::new(self);
@@ -470,7 +543,7 @@ impl Connection {
telepathy::connection_interface_contacts_server(&f, (), move |_| c_rc3.clone());
let _c_rc4 = c_rc.clone();
let _contact_list_iface =
let contact_list_iface =
telepathy::connection_interface_contact_list_server(&f, (), move |_| _c_rc4.clone());
let c_rc5 = c_rc.clone();
@@ -486,7 +559,7 @@ impl Connection {
.add(conn_iface)
.add(avatars_iface)
.add(contacts_iface)
// .add(contact_list_iface)
.add(contact_list_iface)
.add(requests_iface)
.add(simple_presence_iface),
);

View File

@@ -1,8 +1,14 @@
use crate::telepathy;
use crate::telepathy::{ConnectionInterfaceContacts, ConnectionInterfaceRequests}; // Non-deprecated channel methods
use async_std::task::block_on;
use dbus::message::SignalArgs;
use dbus::tree::MethodErr;
use dc::contact::Contact;
use deltachat as dc;
use std::collections::HashMap;
use std::convert::TryInto;
use std::thread;
use super::{Connection, DbusAction};
@@ -24,12 +30,18 @@ type ChannelInfo = (
u32, // Handle
);
type ContactSubscription = (
u32, // Subscribe state
u32, // Publish state
String, // Publish-request message
);
pub fn connection_interfaces() -> Vec<String> {
vec![
"org.freedesktop.Telepathy.Connection".to_string(),
"org.freedesktop.Telepathy.Connection.Interface.Avatars".to_string(),
"org.freedesktop.Telepathy.Connection.Interface.Contacts".to_string(),
// "org.freedesktop.Telepathy.Connection.Interface.ContactList".to_string(),
"org.freedesktop.Telepathy.Connection.Interface.ContactList".to_string(),
"org.freedesktop.Telepathy.Connection.Interface.Requests".to_string(),
"org.freedesktop.Telepathy.Connection.Interface.SimplePresence".to_string(),
]
@@ -46,64 +58,12 @@ impl telepathy::Connection for Connection {
fn connect(&self) -> Result<()> {
println!("Connection<{}>::connect()", self.id());
let inbox_ctx = self.ctx.clone();
let state = self.state.clone();
let id = self.id();
let _inbox_thread = thread::spawn(move || {
while *state.read().unwrap() != ConnState::Disconnected {
dc::job::perform_inbox_jobs(&inbox_ctx.read().unwrap());
if *state.read().unwrap() != ConnState::Disconnected {
dc::job::perform_inbox_fetch(&inbox_ctx.read().unwrap());
let io_ctx = self.ctx.clone();
let io_id = self.id();
let _io_thread = thread::spawn(move || {
block_on(io_ctx.start_io());
if *state.read().unwrap() != ConnState::Disconnected {
dc::job::perform_inbox_idle(&inbox_ctx.read().unwrap());
}
}
}
println!("Connection<{}>::connect(): inbox thread exited", id);
});
let smtp_ctx = self.ctx.clone();
let state = self.state.clone();
let id = self.id();
let _smtp_thread = thread::spawn(move || {
while *state.read().unwrap() != ConnState::Disconnected {
dc::job::perform_smtp_jobs(&smtp_ctx.read().unwrap());
if *state.read().unwrap() != ConnState::Disconnected {
dc::job::perform_smtp_idle(&smtp_ctx.read().unwrap());
}
}
println!("Connection<{}>::connect(): smtp thread exited", id);
});
let mvbox_ctx = self.ctx.clone();
let state = self.state.clone();
let id = self.id();
let _mvbox_thread = thread::spawn(move || {
while *state.read().unwrap() != ConnState::Disconnected {
dc::job::perform_mvbox_fetch(&mvbox_ctx.read().unwrap());
if *state.read().unwrap() != ConnState::Disconnected {
dc::job::perform_mvbox_idle(&mvbox_ctx.read().unwrap());
}
}
println!("Connection<{}>::connect(): mvbox thread exited", id);
});
let sentbox_ctx = self.ctx.clone();
let state = self.state.clone();
let id = self.id();
let _sentbox_thread = thread::spawn(move || {
while *state.read().unwrap() != ConnState::Disconnected {
dc::job::perform_sentbox_fetch(&sentbox_ctx.read().unwrap());
if *state.read().unwrap() != ConnState::Disconnected {
dc::job::perform_sentbox_idle(&sentbox_ctx.read().unwrap());
}
}
println!("Connection<{}>::connect(): sentbox thread exited", id);
println!("Connection<{}>::connect(): I/O thread exited", io_id);
});
// Just pretend to be connected all the time for now. Tracking IMAP+SMTP
@@ -111,35 +71,60 @@ impl telepathy::Connection for Connection {
let state = self.state.clone();
let mut w = state.write().unwrap();
*w = ConnState::Connected;
let ctx = self.ctx.clone();
// Emit a StatusChanged signal for the benefit of others, but the caller
// learns from our RPC response
let sig = telepathy::ConnectionStatusChanged {
let connected_sig = telepathy::ConnectionStatusChanged {
status: 0, // Connected
reason: 1, // Requested
};
}
.to_emit_message(&self.path());
self.actq
.send(DbusAction::Signal(sig.to_emit_message(&self.path())))
.unwrap();
self.actq.send(DbusAction::Signal(connected_sig)).unwrap();
self.actq.send(DbusAction::FreshMessages).unwrap();
// If we can, emit signals on connect about the contact list
if let Ok(handles) = block_on(Contact::get_all(
&ctx,
(dc::constants::DC_GCL_ADD_SELF as usize)
.try_into()
.unwrap(),
None::<String>,
)) {
println!(" HANDLES: {:?}", handles);
let mut changes = HashMap::<u32, ContactSubscription>::new();
for handle in handles {
println!(" *** Handle: {}", handle);
changes.insert(handle, (4, 4, "".to_string())); // FIXME: hardcoded lies
}
// TODO: the old signal is deprecated. The new signal requires us to
// send identifiers with it, which is a bit of a lookup here.
// let cl_sig_new = telepathy::ConnectionInterfaceContactsChangedWithID {
// }.to_emit_message(&self.path());
let cl_sig_old = telepathy::ConnectionInterfaceContactListContactsChanged {
changes,
removals: Vec::new(),
}
.to_emit_message(&self.path());
// self.actq.send(DbusAction::Signal(cl_sig_new)).unwrap();
self.actq.send(DbusAction::Signal(cl_sig_old)).unwrap();
};
Ok(())
}
fn disconnect(&self) -> Result<()> {
println!("Connection<{}>::disconnect()", self.id());
let ctx = self.ctx.read().unwrap();
block_on(self.ctx.stop_io());
let state = self.state.clone();
let mut w = state.write().unwrap();
*w = ConnState::Disconnected;
dc::job::interrupt_inbox_idle(&ctx);
dc::job::interrupt_smtp_idle(&ctx);
dc::job::interrupt_sentbox_idle(&ctx);
dc::job::interrupt_mvbox_idle(&ctx);
// FIXME: we need to signal to the CM that they should remove the
// connection from the active list
@@ -174,7 +159,7 @@ impl telepathy::Connection for Connection {
fn get_self_handle(&self) -> Result<u32> {
println!("Connection<{}>::get_self_handle()", self.id());
self.get_self_handle()
self.self_handle()
}
fn status(&self) -> Result<u32> {
@@ -287,7 +272,43 @@ impl telepathy::Connection for Connection {
identifiers
);
Err(MethodErr::no_arg()) // FIXME: should be NotImplemented?
match handle_type {
crate::padfoot::HANDLE_TYPE_CONTACT => {
let ctx = &self.ctx;
let mut out = Vec::<u32>::new();
// Identifiers is a list of email addresses. These can be
// contact IDs, although we may have to create contacts to get
// the ID.
//
// FIXME: will it be faster to get all and filter?
for addr in identifiers {
let id = block_on(Contact::lookup_id_by_addr(
ctx,
addr,
dc::contact::Origin::Unknown,
));
match id {
0 => {
// No contact exists for this address yet. Try to
// add one so we can have an ID.
match block_on(Contact::create(ctx, &addr, &addr)) {
Ok(new_id) => out.push(new_id),
Err(e) => {
println!("Failed to add contact {}: {}", addr, e);
return Err(MethodErr::no_arg());
}
}
}
_ => out.push(id),
}
}
Ok(out)
}
_ => Err(MethodErr::no_arg()), // FIXME: should be NotImplemented?
}
}
fn add_client_interest(&self, tokens: Vec<&str>) -> Result<()> {
@@ -311,10 +332,10 @@ impl telepathy::Connection for Connection {
fn self_id(&self) -> Result<String> {
println!("Connection<{}>::self_id()", self.id());
let contact = match dc::contact::Contact::get_by_id(
&self.ctx.read().unwrap(),
let contact = match block_on(dc::contact::Contact::get_by_id(
&self.ctx,
dc::constants::DC_CONTACT_ID_SELF,
) {
)) {
Ok(c) => c,
Err(e) => {
println!(" err: {}", e);

View File

@@ -1,9 +1,11 @@
use crate::padfoot::VarArg;
use crate::telepathy;
use async_std::task::block_on;
use dbus::tree::MethodErr;
use deltachat::constants::DC_GCL_ADD_SELF;
use deltachat::contact::Contact;
use dc::constants::DC_GCL_ADD_SELF;
use dc::contact::Contact;
use deltachat as dc;
use std::collections::HashMap;
use std::convert::TryInto;
use telepathy::ConnectionInterfaceContacts; // for get_contact_attributes
@@ -30,8 +32,11 @@ impl telepathy::ConnectionInterfaceContactList for Connection {
hold
);
let ctx = &self.ctx.read().unwrap();
let ids = match Contact::get_all(ctx, DC_GCL_ADD_SELF.try_into().unwrap(), None::<String>) {
let ids = match block_on(Contact::get_all(
&self.ctx,
DC_GCL_ADD_SELF.try_into().unwrap(),
None::<String>,
)) {
Ok(c) => c,
Err(e) => {
println!(" err: {}", e);
@@ -39,6 +44,7 @@ impl telepathy::ConnectionInterfaceContactList for Connection {
}
};
// FIXME: swap implementations so Contacts depends on ContactList?
self.get_contact_attributes(ids, vec![], true)
}
@@ -62,6 +68,17 @@ impl telepathy::ConnectionInterfaceContactList for Connection {
}
fn remove_contacts(&self, contacts: Vec<u32>) -> Result<(), MethodErr> {
println!("Connection<{}>::remove_contacts({:?})", self.id(), contacts);
for contact_id in contacts {
// FIXME: don't ignore errors
if let Err(e) = block_on(Contact::delete(&self.ctx, contact_id)) {
println!(" Deleting contact {} failed: {}", contact_id, e);
}
}
// FIXME: signals MUST be emitted before this method returns
// FIXME: emitting signals at all would be great
Ok(())
}
fn unsubscribe(&self, contacts: Vec<u32>) -> Result<(), MethodErr> {
@@ -76,6 +93,8 @@ impl telepathy::ConnectionInterfaceContactList for Connection {
fn download(&self) -> Result<(), MethodErr> {
println!("Connection<{}>::download()", self.id());
// This can be a no-op since we store the contacts list in delta's DB
Ok(())
}
@@ -91,7 +110,7 @@ impl telepathy::ConnectionInterfaceContactList for Connection {
fn can_change_contact_list(&self) -> Result<bool, MethodErr> {
println!("Connection<{}>::can_change_contact_list()", self.id());
Ok(false)
Ok(true)
}
fn request_uses_message(&self) -> Result<bool, MethodErr> {
println!("Connection<{}>::request_uses_message()", self.id());
@@ -100,6 +119,11 @@ impl telepathy::ConnectionInterfaceContactList for Connection {
fn download_at_connection(&self) -> Result<bool, MethodErr> {
println!("Connection<{}>::download_at_connection()", self.id());
Ok(false)
// TODO: https://telepathy.freedesktop.org/spec/Connection_Interface_Contact_List.html#Property:DownloadAtConnection
// Connections ... SHOULD provide a corresponding parameter named
// org.freedesktop.Telepathy.Connection.Interface.ContactList.DownloadAtConnection
// with the DBus_Property flag
Ok(true)
}
}

View File

@@ -1,6 +1,7 @@
use crate::padfoot::{var_str, VarArg};
use crate::padfoot::{var_str, var_u32, VarArg};
use crate::telepathy;
use async_std::task::block_on;
use dbus::tree::MethodErr;
use deltachat::contact::{Contact, Origin};
use std::collections::HashMap;
@@ -31,7 +32,7 @@ impl telepathy::ConnectionInterfaceContacts for Connection {
let mut out = HashMap::<u32, HashMap<String, VarArg>>::new();
for id in handles.iter() {
// FIXME: work out how to use get_all
let contact = match Contact::get_by_id(&self.ctx.read().unwrap(), *id) {
let contact = match block_on(Contact::get_by_id(&self.ctx, *id)) {
Ok(c) => c,
Err(_e) => continue, // Invalid IDs are silently ignored
};
@@ -48,18 +49,17 @@ impl telepathy::ConnectionInterfaceContacts for Connection {
"org.freedesktop.Telepathy.Connection.Interface.Avatars/token".to_string(),
var_str("".to_string()),
);
/*
// TODO: we need to publish DBUS services on these endpoints
props.insert(
"org.freedesktop.Telepathy.Connection.Interface.ContactList/publish".to_string(),
var_arg(Box::new(4)),
);
props.insert(
"org.freedesktop.Telepathy.Connection.Interface.ContactList/subscribe".to_string(),
var_arg(Box::new(4)),
);
*/
props.insert(
"org.freedesktop.Telepathy.Connection.Interface.ContactList/publish".to_string(),
var_u32(4), // YES (faking it for now)
);
props.insert(
"org.freedesktop.Telepathy.Connection.Interface.ContactList/subscribe".to_string(),
var_u32(4), // YES (faking it for now)
);
out.insert(*id, props);
}
@@ -78,10 +78,11 @@ impl telepathy::ConnectionInterfaceContacts for Connection {
interfaces
);
let id = {
let ctx = &self.ctx.read().unwrap();
Contact::lookup_id_by_addr(ctx, identifier, Origin::Unknown)
};
let id = block_on(Contact::lookup_id_by_addr(
&self.ctx,
identifier,
Origin::Unknown,
));
if id == 0 {
return Err(MethodErr::no_arg()); // FIXME: should be InvalidHandle
@@ -101,7 +102,7 @@ impl telepathy::ConnectionInterfaceContacts for Connection {
Ok(vec![
"org.freedesktop.Telepathy.Connection".to_string(),
"org.freedesktop.Telepathy.Connection.Interface.Avatars".to_string(),
// "org.freedesktop.Telepathy.Connection.Interface.ContactList".to_string(),
"org.freedesktop.Telepathy.Connection.Interface.ContactList".to_string(),
])
}
}

View File

@@ -1,7 +1,11 @@
use crate::padfoot::{requestables, VarArg};
use crate::padfoot::{get_var_str, get_var_u32, requestables, Channel, DbusAction, VarArg};
use crate::telepathy;
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;
@@ -35,8 +39,81 @@ impl telepathy::ConnectionInterfaceRequests for Connection {
&self,
request: HashMap<&str, VarArg>,
) -> Result<(bool, dbus::Path<'static>, HashMap<String, VarArg>)> {
let path = self.path().clone();
println!("Connection<{}>::ensure_channel({:?})", self.id(), request);
Err(MethodErr::no_arg()) // FIXME: should be NotImplemented?
// 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 target_handle = block_on(Contact::lookup_id_by_addr(
&self.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
let chat_id = block_on(dc::chat::create_by_contact_id(&self.ctx, target_handle)).unwrap();
let channel = Channel::new(
self.actq.clone(),
chat_id,
self.ctx.clone(),
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))
}
fn channels(&self) -> Result<Vec<ChannelSpec>> {

138
src/padfoot/message.rs Normal file
View File

@@ -0,0 +1,138 @@
use crate::padfoot::{var_bytearray, var_i64, var_str, var_u32, VarArg};
use async_std::path::{Path, PathBuf};
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(blobdir: &Path, msg: &Message) -> Result<Vec<Part>> {
if msg.is_setupmessage() {
return Ok(convert_setupmessage(msg));
}
let mut parts = vec![make_props(msg)];
// 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),
};
result.map(|mut more| {
parts.append(&mut more);
parts
})
}
fn convert_setupmessage(msg: &Message) -> Vec<Part> {
let msg_id = msg.get_id();
vec![
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 make_props(msg: &Message) -> Part {
let msg_id = msg.get_id();
let mut out = HashMap::new();
out.insert(
"message-token".to_string(),
var_str(format!("{}", msg_id.to_u32())),
);
out.insert("message-sent".to_string(), var_i64(msg.get_timestamp()));
out.insert(
"message-received".to_string(),
var_i64(msg.get_received_timestamp()),
);
out.insert("message-sender".to_string(), var_u32(msg.get_from_id()));
// props.insert("message-sender-id", var_str()); // This doesn't need to be sent
// props.insert("sender-nickname", var_str()); // Can we get away without this one?
out.insert("message-type".to_string(), var_u32(0)); // normal
// These relate to superseded messages
// props.insert("supersedes", var_str());
// props.insert("original-message-sent", var_i64());
// props.insert("original-message-received", var_i64());
out.insert("pending-message-id".to_string(), var_u32(msg_id.to_u32()));
// Don't need these
// props.insert("interface", var_str());
// props.insert("scrollback", var_vool());
// props.insert("silent", var_bool());
// props.insert("rescued", var_bool());
out
}
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(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: &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: PathBuf = [blobdir, &Path::new(&filename)].iter().collect();
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])
}

View File

@@ -1,4 +1,4 @@
use crate::padfoot::{var_str, var_u32, VarArg};
use crate::padfoot::{var_bool, var_str, var_u32, VarArg};
use crate::telepathy;
use dbus::tree::MethodErr;
@@ -49,6 +49,7 @@ pub fn parameters() -> Vec<ParamSpec> {
"s".to_string(),
var_str("".to_string()),
),
("bcc-self".to_string(), 0, "b".to_string(), var_bool(false)),
]
}

View File

@@ -1,5 +1,7 @@
use dbus::arg::{RefArg, Variant};
use std::convert::TryInto;
pub type VarArg = Variant<Box<dyn RefArg + 'static>>;
pub fn var_arg(item: Box<dyn RefArg + 'static>) -> VarArg {
@@ -14,6 +16,26 @@ pub fn var_str_vec(item: Vec<String>) -> VarArg {
var_arg(Box::new(item))
}
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))
}
pub fn var_i64(item: i64) -> VarArg {
var_arg(Box::new(item))
}
pub fn get_var_str(from: &VarArg) -> String {
from.0.as_str().unwrap().to_string()
}
pub fn get_var_u32(from: &VarArg) -> u32 {
from.0.as_u64().unwrap().try_into().unwrap()
}

View File

@@ -1,364 +1,485 @@
#![allow(unused)]
#[allow(clippy::all)]
mod account_interface_addressing;
pub use self::account_interface_addressing::*;
#[allow(clippy::all)]
mod account_interface_avatar;
pub use self::account_interface_avatar::*;
#[allow(clippy::all)]
mod account_interface_external_password_storage;
pub use self::account_interface_external_password_storage::*;
#[allow(clippy::all)]
mod account_interface_hidden;
pub use self::account_interface_hidden::*;
#[allow(clippy::all)]
mod account_interface_storage;
pub use self::account_interface_storage::*;
#[allow(clippy::all)]
mod account_manager_interface_hidden;
pub use self::account_manager_interface_hidden::*;
#[allow(clippy::all)]
mod account_manager;
pub use self::account_manager::*;
#[allow(clippy::all)]
mod account;
pub use self::account::*;
#[allow(clippy::all)]
mod all;
pub use self::all::*;
#[allow(clippy::all)]
mod authentication_tls_certificate;
pub use self::authentication_tls_certificate::*;
#[allow(clippy::all)]
mod call_content_interface_audio_control;
pub use self::call_content_interface_audio_control::*;
#[allow(clippy::all)]
mod call_content_interface_dtmf;
pub use self::call_content_interface_dtmf::*;
#[allow(clippy::all)]
mod call_content_interface_media;
pub use self::call_content_interface_media::*;
#[allow(clippy::all)]
mod call_content_interface_video_control;
pub use self::call_content_interface_video_control::*;
#[allow(clippy::all)]
mod call_content_media_description_interface_rtcp_extended_reports;
pub use self::call_content_media_description_interface_rtcp_extended_reports::*;
#[allow(clippy::all)]
mod call_content_media_description_interface_rtcp_feedback;
pub use self::call_content_media_description_interface_rtcp_feedback::*;
#[allow(clippy::all)]
mod call_content_media_description_interface_rtp_header_extensions;
pub use self::call_content_media_description_interface_rtp_header_extensions::*;
#[allow(clippy::all)]
mod call_content_media_description;
pub use self::call_content_media_description::*;
#[allow(clippy::all)]
mod call_content;
pub use self::call_content::*;
#[allow(clippy::all)]
mod call_interface_mute;
pub use self::call_interface_mute::*;
#[allow(clippy::all)]
mod call_stream_endpoint;
pub use self::call_stream_endpoint::*;
#[allow(clippy::all)]
mod call_stream_interface_media;
pub use self::call_stream_interface_media::*;
#[allow(clippy::all)]
mod call_stream;
pub use self::call_stream::*;
#[allow(clippy::all)]
mod channel_bundle;
pub use self::channel_bundle::*;
#[allow(clippy::all)]
mod channel_dispatcher_interface_messages1;
pub use self::channel_dispatcher_interface_messages1::*;
#[allow(clippy::all)]
mod channel_dispatcher_interface_operation_list;
pub use self::channel_dispatcher_interface_operation_list::*;
#[allow(clippy::all)]
mod channel_dispatcher;
pub use self::channel_dispatcher::*;
#[allow(clippy::all)]
mod channel_dispatch_operation;
pub use self::channel_dispatch_operation::*;
#[allow(clippy::all)]
mod channel_future;
pub use self::channel_future::*;
#[allow(clippy::all)]
mod channel_handler;
pub use self::channel_handler::*;
#[allow(clippy::all)]
mod channel_interface_addressing;
pub use self::channel_interface_addressing::*;
#[allow(clippy::all)]
mod channel_interface_anonymity;
pub use self::channel_interface_anonymity::*;
#[allow(clippy::all)]
mod channel_interface_call_state;
pub use self::channel_interface_call_state::*;
#[allow(clippy::all)]
mod channel_interface_captcha_authentication;
pub use self::channel_interface_captcha_authentication::*;
#[allow(clippy::all)]
mod channel_interface_chat_state;
pub use self::channel_interface_chat_state::*;
#[allow(clippy::all)]
mod channel_interface_conference;
pub use self::channel_interface_conference::*;
#[allow(clippy::all)]
mod channel_interface_credentials_storage;
pub use self::channel_interface_credentials_storage::*;
#[allow(clippy::all)]
mod channel_interface_destroyable;
pub use self::channel_interface_destroyable::*;
#[allow(clippy::all)]
mod channel_interface_dtmf;
pub use self::channel_interface_dtmf::*;
#[allow(clippy::all)]
mod channel_interface_file_transfer_metadata;
pub use self::channel_interface_file_transfer_metadata::*;
#[allow(clippy::all)]
mod channel_interface_group;
pub use self::channel_interface_group::*;
#[allow(clippy::all)]
mod channel_interface_hold;
pub use self::channel_interface_hold::*;
#[allow(clippy::all)]
mod channel_interface_html;
pub use self::channel_interface_html::*;
#[allow(clippy::all)]
mod channel_interface_media_signalling;
pub use self::channel_interface_media_signalling::*;
#[allow(clippy::all)]
mod channel_interface_mergeable_conference;
pub use self::channel_interface_mergeable_conference::*;
#[allow(clippy::all)]
mod channel_interface_messages;
pub use self::channel_interface_messages::*;
#[allow(clippy::all)]
mod channel_interface_password;
pub use self::channel_interface_password::*;
#[allow(clippy::all)]
mod channel_interface_picture;
pub use self::channel_interface_picture::*;
#[allow(clippy::all)]
mod channel_interface_room_config;
pub use self::channel_interface_room_config::*;
#[allow(clippy::all)]
mod channel_interface_room;
pub use self::channel_interface_room::*;
#[allow(clippy::all)]
mod channel_interface_sasl_authentication;
pub use self::channel_interface_sasl_authentication::*;
#[allow(clippy::all)]
mod channel_interface_securable;
pub use self::channel_interface_securable::*;
#[allow(clippy::all)]
mod channel_interface_service_point;
pub use self::channel_interface_service_point::*;
#[allow(clippy::all)]
mod channel_interface_sms;
pub use self::channel_interface_sms::*;
#[allow(clippy::all)]
mod channel_interface_splittable;
pub use self::channel_interface_splittable::*;
#[allow(clippy::all)]
mod channel_interface_subject;
pub use self::channel_interface_subject::*;
#[allow(clippy::all)]
mod channel_interface_transfer;
pub use self::channel_interface_transfer::*;
#[allow(clippy::all)]
mod channel_interface_tube;
pub use self::channel_interface_tube::*;
#[allow(clippy::all)]
mod channel_request;
pub use self::channel_request::*;
#[allow(clippy::all)]
mod channel_type_call;
pub use self::channel_type_call::*;
#[allow(clippy::all)]
mod channel_type_contact_list;
pub use self::channel_type_contact_list::*;
#[allow(clippy::all)]
mod channel_type_contact_search;
pub use self::channel_type_contact_search::*;
#[allow(clippy::all)]
mod channel_type_dbus_tube;
pub use self::channel_type_dbus_tube::*;
#[allow(clippy::all)]
mod channel_type_file_transfer;
pub use self::channel_type_file_transfer::*;
#[allow(clippy::all)]
mod channel_type_room_list;
pub use self::channel_type_room_list::*;
#[allow(clippy::all)]
mod channel_type_server_authentication;
pub use self::channel_type_server_authentication::*;
#[allow(clippy::all)]
mod channel_type_server_tls_connection;
pub use self::channel_type_server_tls_connection::*;
#[allow(clippy::all)]
mod channel_type_streamed_media;
pub use self::channel_type_streamed_media::*;
#[allow(clippy::all)]
mod channel_type_stream_tube;
pub use self::channel_type_stream_tube::*;
#[allow(clippy::all)]
mod channel_type_text;
pub use self::channel_type_text::*;
#[allow(clippy::all)]
mod channel_type_tubes;
pub use self::channel_type_tubes::*;
#[allow(clippy::all)]
mod channel;
pub use self::channel::*;
#[allow(clippy::all)]
mod client_approver;
pub use self::client_approver::*;
#[allow(clippy::all)]
mod client_handler_future;
pub use self::client_handler_future::*;
#[allow(clippy::all)]
mod client_handler;
pub use self::client_handler::*;
#[allow(clippy::all)]
mod client_interface_requests;
pub use self::client_interface_requests::*;
#[allow(clippy::all)]
mod client_observer;
pub use self::client_observer::*;
#[allow(clippy::all)]
mod client;
pub use self::client::*;
#[allow(clippy::all)]
mod connection_interface_addressing;
pub use self::connection_interface_addressing::*;
#[allow(clippy::all)]
mod connection_interface_aliasing;
pub use self::connection_interface_aliasing::*;
#[allow(clippy::all)]
mod connection_interface_anonymity;
pub use self::connection_interface_anonymity::*;
#[allow(clippy::all)]
mod connection_interface_avatars;
pub use self::connection_interface_avatars::*;
#[allow(clippy::all)]
mod connection_interface_balance;
pub use self::connection_interface_balance::*;
#[allow(clippy::all)]
mod connection_interface_capabilities;
pub use self::connection_interface_capabilities::*;
#[allow(clippy::all)]
mod connection_interface_cellular;
pub use self::connection_interface_cellular::*;
#[allow(clippy::all)]
mod connection_interface_client_types;
pub use self::connection_interface_client_types::*;
#[allow(clippy::all)]
mod connection_interface_communication_policy;
pub use self::connection_interface_communication_policy::*;
#[allow(clippy::all)]
mod connection_interface_contact_blocking;
pub use self::connection_interface_contact_blocking::*;
#[allow(clippy::all)]
mod connection_interface_contact_capabilities;
pub use self::connection_interface_contact_capabilities::*;
#[allow(clippy::all)]
mod connection_interface_contact_groups;
pub use self::connection_interface_contact_groups::*;
#[allow(clippy::all)]
mod connection_interface_contact_info;
pub use self::connection_interface_contact_info::*;
#[allow(clippy::all)]
mod connection_interface_contact_list;
pub use self::connection_interface_contact_list::*;
#[allow(clippy::all)]
mod connection_interface_contacts;
pub use self::connection_interface_contacts::*;
#[allow(clippy::all)]
mod connection_interface_forwarding;
pub use self::connection_interface_forwarding::*;
#[allow(clippy::all)]
mod connection_interface_irc_command1;
pub use self::connection_interface_irc_command1::*;
#[allow(clippy::all)]
mod connection_interface_keepalive;
pub use self::connection_interface_keepalive::*;
#[allow(clippy::all)]
mod connection_interface_location;
pub use self::connection_interface_location::*;
#[allow(clippy::all)]
mod connection_interface_mail_notification;
pub use self::connection_interface_mail_notification::*;
#[allow(clippy::all)]
mod connection_interface_power_saving;
pub use self::connection_interface_power_saving::*;
#[allow(clippy::all)]
mod connection_interface_presence;
pub use self::connection_interface_presence::*;
#[allow(clippy::all)]
mod connection_interface_privacy;
pub use self::connection_interface_privacy::*;
#[allow(clippy::all)]
mod connection_interface_renaming;
pub use self::connection_interface_renaming::*;
#[allow(clippy::all)]
mod connection_interface_requests;
pub use self::connection_interface_requests::*;
#[allow(clippy::all)]
mod connection_interface_resources;
pub use self::connection_interface_resources::*;
#[allow(clippy::all)]
mod connection_interface_service_point;
pub use self::connection_interface_service_point::*;
#[allow(clippy::all)]
mod connection_interface_sidecars1;
pub use self::connection_interface_sidecars1::*;
#[allow(clippy::all)]
mod connection_interface_simple_presence;
pub use self::connection_interface_simple_presence::*;
#[allow(clippy::all)]
mod connection_manager_interface_account_storage;
pub use self::connection_manager_interface_account_storage::*;
#[allow(clippy::all)]
mod connection_manager;
pub use self::connection_manager::*;
#[allow(clippy::all)]
mod connection;
pub use self::connection::*;
#[allow(clippy::all)]
mod debug;
pub use self::debug::*;
#[allow(clippy::all)]
mod errors;
pub use self::errors::*;
#[allow(clippy::all)]
mod generic_types;
pub use self::generic_types::*;
#[allow(clippy::all)]
mod media_session_handler;
pub use self::media_session_handler::*;
#[allow(clippy::all)]
mod media_stream_handler;
pub use self::media_stream_handler::*;
#[allow(clippy::all)]
mod properties_interface;
pub use self::properties_interface::*;
#[allow(clippy::all)]
mod protocol_interface_addressing;
pub use self::protocol_interface_addressing::*;
#[allow(clippy::all)]
mod protocol_interface_avatars;
pub use self::protocol_interface_avatars::*;
#[allow(clippy::all)]
mod protocol_interface_presence;
pub use self::protocol_interface_presence::*;
#[allow(clippy::all)]
mod protocol;
pub use self::protocol::*;
#[allow(clippy::all)]
mod template;
pub use self::template::*;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Account.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/account.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Account_Interface_Addressing.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/account_interface_addressing.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Account_Interface_Avatar.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/account_interface_avatar.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Account_Interface_External_Password_Storage.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/account_interface_external_password_storage.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Account_Interface_Hidden.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/account_interface_hidden.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Account_Interface_Storage.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/account_interface_storage.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Account_Manager.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/account_manager.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Account_Manager_Interface_Hidden.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/account_manager_interface_hidden.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/all.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/all.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Authentication_TLS_Certificate.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/authentication_tls_certificate.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Call_Content.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/call_content.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Call_Content_Interface_Audio_Control.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/call_content_interface_audio_control.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Call_Content_Interface_DTMF.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/call_content_interface_dtmf.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Call_Content_Interface_Media.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/call_content_interface_media.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Call_Content_Interface_Video_Control.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/call_content_interface_video_control.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Call_Content_Media_Description.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/call_content_media_description.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Call_Content_Media_Description_Interface_RTCP_Extended_Reports.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/call_content_media_description_interface_rtcp_extended_reports.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Call_Content_Media_Description_Interface_RTCP_Feedback.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/call_content_media_description_interface_rtcp_feedback.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Call_Content_Media_Description_Interface_RTP_Header_Extensions.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/call_content_media_description_interface_rtp_header_extensions.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Call_Interface_Mute.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/call_interface_mute.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Call_Stream.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/call_stream.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Call_Stream_Endpoint.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/call_stream_endpoint.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Call_Stream_Interface_Media.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/call_stream_interface_media.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Bundle.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_bundle.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Dispatch_Operation.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_dispatch_operation.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Dispatcher.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_dispatcher.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Dispatcher_Interface_Messages1.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_dispatcher_interface_messages1.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Dispatcher_Interface_Operation_List.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_dispatcher_interface_operation_list.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Future.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_future.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Handler.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_handler.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Addressing.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_addressing.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Anonymity.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_anonymity.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Call_State.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_call_state.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Captcha_Authentication.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_captcha_authentication.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Chat_State.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_chat_state.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Conference.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_conference.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Credentials_Storage.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_credentials_storage.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Destroyable.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_destroyable.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_DTMF.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_dtmf.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_File_Transfer_Metadata.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_file_transfer_metadata.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Group.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_group.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Hold.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_hold.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_HTML.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_html.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Media_Signalling.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_media_signalling.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Mergeable_Conference.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_mergeable_conference.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Messages.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_messages.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Password.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_password.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Picture.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_picture.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Room.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_room.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Room_Config.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_room_config.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_SASL_Authentication.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_sasl_authentication.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Securable.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_securable.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Service_Point.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_service_point.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_SMS.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_sms.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Splittable.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_splittable.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Subject.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_subject.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Transfer.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_transfer.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Interface_Tube.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_interface_tube.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Request.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_request.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Type_Call.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_type_call.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Type_Contact_List.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_type_contact_list.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Type_Contact_Search.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_type_contact_search.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Type_DBus_Tube.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_type_dbus_tube.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Type_File_Transfer.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_type_file_transfer.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Type_Room_List.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_type_room_list.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Type_Server_Authentication.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_type_server_authentication.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Type_Server_TLS_Connection.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_type_server_tls_connection.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Type_Stream_Tube.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_type_stream_tube.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Type_Streamed_Media.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_type_streamed_media.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Type_Text.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_type_text.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Channel_Type_Tubes.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/channel_type_tubes.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Client.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/client.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Client_Approver.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/client_approver.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Client_Handler.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/client_handler.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Client_Handler_Future.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/client_handler_future.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

View File

@@ -1,5 +1,3 @@
#![allow(clippy::all)]
// This code was autogenerated with `dbus-codegen-rust --file telepathy-spec/spec/Client_Interface_Requests.xml -i org.freedesktop.Telepathy -a AsRefClosure -o src/telepathy/client_interface_requests.rs`, see https://github.com/diwic/dbus-rs
use dbus;
use dbus::arg;

Some files were not shown because too many files have changed in this diff Show More