Compare commits
24 Commits
1e481d4c9a
...
main
Author | SHA1 | Date | |
---|---|---|---|
7707242d10 | |||
bd76603c54 | |||
9e764d72a1 | |||
b9faad742b | |||
370f5076a1 | |||
373311e826 | |||
67a8715a25 | |||
c773146b26 | |||
7b1b8bdc83 | |||
d06badfc96 | |||
8dbd023718 | |||
7cee6348fd | |||
14aa639a4b | |||
efe97a33c4 | |||
d77d04e9b1 | |||
db7ecc6d98 | |||
15174ea03f | |||
aae7607c7f | |||
825f5d90ed | |||
a95be7ee4b | |||
72947bc99d | |||
b511dd873b | |||
667eb3b3f6 | |||
cb463336bc |
812
Cargo.lock
generated
812
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -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
146
README.md
@@ -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
70
about.hbs
Normal 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
11
about.toml
Normal 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
9555
license.html
Normal file
File diff suppressed because it is too large
Load Diff
1
rust-toolchain
Normal file
1
rust-toolchain
Normal file
@@ -0,0 +1 @@
|
||||
nightly-2020-03-12
|
@@ -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 -- .
|
||||
|
@@ -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;
|
||||
|
@@ -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::*;
|
||||
|
||||
|
@@ -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>;
|
||||
|
||||
@@ -32,7 +35,9 @@ pub const HANDLE_TYPE_GROUP: HandleType = 4; // Deprecated
|
||||
#[derive(Debug)]
|
||||
pub struct Channel {
|
||||
actq: mpsc::Sender<DbusAction>,
|
||||
ctx: Arc<RwLock<dc::context::Context>>,
|
||||
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
|
||||
@@ -46,20 +51,65 @@ pub fn channel_interfaces() -> Vec<String> {
|
||||
impl Channel {
|
||||
pub fn new(
|
||||
actq: mpsc::Sender<DbusAction>,
|
||||
ctx: Arc<RwLock<dc::context::Context>>,
|
||||
chat_id: dc::chat::ChatId,
|
||||
ctx: Arc<dc::context::Context>,
|
||||
initiator_handle: u32,
|
||||
path: dbus::Path<'static>,
|
||||
requested: bool,
|
||||
target_handle: u32,
|
||||
) -> Self {
|
||||
Channel {
|
||||
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()
|
||||
}
|
||||
@@ -76,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(
|
||||
@@ -109,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -77,7 +77,7 @@ impl telepathy::Channel for Channel {
|
||||
fn requested(&self) -> Result<bool> {
|
||||
println!("Channel::requested()");
|
||||
|
||||
Ok(true) // 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> {
|
||||
|
@@ -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(
|
||||
@@ -33,7 +92,7 @@ impl telepathy::ChannelInterfaceMessages for Channel {
|
||||
fn supported_content_types(&self) -> Result<Vec<String>> {
|
||||
println!("Channel::supported_content_types()");
|
||||
|
||||
Ok(vec!["text/plain".to_string()]) // TODO: image support
|
||||
Ok(vec!["*/*".to_string()])
|
||||
}
|
||||
|
||||
fn message_types(&self) -> Result<Vec<u32>> {
|
||||
@@ -48,10 +107,28 @@ impl telepathy::ChannelInterfaceMessages for Channel {
|
||||
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()");
|
||||
|
||||
Ok(vec![]) // FIXME: check for pending messages
|
||||
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> {
|
||||
|
@@ -1,6 +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};
|
||||
|
||||
@@ -22,9 +28,31 @@ 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>> {
|
||||
@@ -35,6 +63,7 @@ impl telepathy::ChannelTypeText for Channel {
|
||||
|
||||
fn list_pending_messages(&self, clear: bool) -> Result<Vec<PendingMessagesSpec>> {
|
||||
println!("Channel::list_pending_messages({})", clear);
|
||||
|
||||
Err(MethodErr::no_arg())
|
||||
}
|
||||
|
||||
|
@@ -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,58 +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();
|
||||
// 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,
|
||||
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(),
|
||||
@@ -458,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);
|
||||
@@ -476,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();
|
||||
@@ -492,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),
|
||||
);
|
||||
|
@@ -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);
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
|
@@ -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(),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
@@ -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
138
src/padfoot/message.rs
Normal 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])
|
||||
}
|
@@ -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)),
|
||||
]
|
||||
}
|
||||
|
||||
|
@@ -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()
|
||||
}
|
||||
|
121
src/telepathy.rs
121
src/telepathy.rs
@@ -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::*;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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
Reference in New Issue
Block a user