rewrite using tokio-xmpp
This commit is contained in:
parent
96278a310e
commit
be37b512a5
1414
Cargo.lock
generated
1414
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
20
Cargo.toml
20
Cargo.toml
@ -10,12 +10,16 @@ keywords = ["xmpp"]
|
|||||||
license = "GPL-3.0+"
|
license = "GPL-3.0+"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
#xmpp = { git = "https://gitlab.com/lumi/xmpp-rs.git" }
|
toml = "0.4.10"
|
||||||
xmpp = { path = "xmpp-rs", version = "0.2.0" }
|
serde_derive = "1.0.85"
|
||||||
#xmpp = "0.2.0"
|
serde = "1.0.85"
|
||||||
toml = "0.4.4"
|
gumdrop = "0.5.0"
|
||||||
serde_derive = "1.0.11"
|
gumdrop_derive = "0.5.0"
|
||||||
serde = "1.0.11"
|
dirs = "1.0.4"
|
||||||
gumdrop = "0.3.0"
|
tokio-xmpp = "0.2.3"
|
||||||
gumdrop_derive = "0.3.0"
|
futures = "0.1"
|
||||||
|
tokio = "0.1"
|
||||||
|
xmpp-parsers = "0.12.2"
|
||||||
|
118
src/main.rs
118
src/main.rs
@ -1,25 +1,19 @@
|
|||||||
#[macro_use]
|
|
||||||
extern crate serde_derive;
|
|
||||||
extern crate toml;
|
|
||||||
extern crate gumdrop;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate gumdrop_derive;
|
|
||||||
extern crate xmpp;
|
|
||||||
|
|
||||||
use xmpp::jid::Jid;
|
|
||||||
use xmpp::client::ClientBuilder;
|
|
||||||
use xmpp::plugins::messaging::MessagingPlugin;
|
|
||||||
|
|
||||||
use std::time::Duration;
|
|
||||||
use std::thread;
|
|
||||||
use std::env;
|
|
||||||
use std::iter::Iterator;
|
|
||||||
use std::io::{Read, stdin};
|
|
||||||
use std::fs::File;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use std::env::args;
|
use std::env::args;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{stdin, Read};
|
||||||
|
use std::iter::Iterator;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use gumdrop::Options;
|
use gumdrop::Options;
|
||||||
|
use serde_derive::Deserialize;
|
||||||
|
|
||||||
|
use futures::{future, Sink, Stream};
|
||||||
|
use tokio::runtime::current_thread::Runtime;
|
||||||
|
use tokio_xmpp::Client;
|
||||||
|
use xmpp_parsers::message::{Body, Message};
|
||||||
|
use xmpp_parsers::{Element, Jid};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Config {
|
struct Config {
|
||||||
@ -34,12 +28,12 @@ fn parse_cfg<P: AsRef<Path>>(path: P) -> Option<Config> {
|
|||||||
match f.read_to_string(&mut input) {
|
match f.read_to_string(&mut input) {
|
||||||
Ok(_) => match toml::from_str(&input) {
|
Ok(_) => match toml::from_str(&input) {
|
||||||
Ok(toml) => Some(toml),
|
Ok(toml) => Some(toml),
|
||||||
Err(_) => None
|
Err(_) => None,
|
||||||
},
|
},
|
||||||
Err(_) => None
|
Err(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => None
|
Err(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +45,9 @@ struct MyOptions {
|
|||||||
#[options(help = "show this help message and exit")]
|
#[options(help = "show this help message and exit")]
|
||||||
help: bool,
|
help: bool,
|
||||||
|
|
||||||
#[options(help = "path to config file. default: ~/.config/sendxmpp.toml with fallback to /etc/sendxmpp/sendxmpp.toml")]
|
#[options(
|
||||||
|
help = "path to config file. default: ~/.config/sendxmpp.toml with fallback to /etc/sendxmpp/sendxmpp.toml"
|
||||||
|
)]
|
||||||
config: Option<String>,
|
config: Option<String>,
|
||||||
|
|
||||||
#[options(help = "Force OpenPGP encryption for all recipients", short = "e")]
|
#[options(help = "Force OpenPGP encryption for all recipients", short = "e")]
|
||||||
@ -83,33 +79,77 @@ fn main() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let recipients: Vec<Jid> = opts.recipients.iter().map(|s| s.parse::<Jid>().expect("invalid recipient jid")).collect();
|
let recipients: Vec<Jid> = opts
|
||||||
|
.recipients
|
||||||
|
.iter()
|
||||||
|
.map(|s| s.parse::<Jid>().expect("invalid recipient jid"))
|
||||||
|
.collect();
|
||||||
|
let recipients = &recipients;
|
||||||
|
|
||||||
let cfg = match opts.config {
|
let cfg = match opts.config {
|
||||||
Some(config) => parse_cfg(&config).expect("provided config cannot be found/parsed"),
|
Some(config) => parse_cfg(&config).expect("provided config cannot be found/parsed"),
|
||||||
None => parse_cfg(env::home_dir().expect("cannot find home directory").join(".config/sendxmpp.toml"))
|
None => parse_cfg(
|
||||||
.or_else(|| parse_cfg("/etc/sendxmpp/sendxmpp.toml")).expect("valid config file not found")
|
dirs::config_dir()
|
||||||
|
.expect("cannot find home directory")
|
||||||
|
.join("sendxmpp.toml"),
|
||||||
|
)
|
||||||
|
.or_else(|| parse_cfg("/etc/sendxmpp/sendxmpp.toml"))
|
||||||
|
.expect("valid config file not found"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let jid: Jid = cfg.jid.parse().expect("invalid jid in config file");
|
|
||||||
|
|
||||||
let mut data = String::new();
|
let mut data = String::new();
|
||||||
stdin().read_to_string(&mut data).expect("error reading from stdin");
|
stdin()
|
||||||
|
.read_to_string(&mut data)
|
||||||
|
.expect("error reading from stdin");
|
||||||
|
let data = data.trim();
|
||||||
|
|
||||||
let mut client = ClientBuilder::new(jid)
|
// tokio_core context
|
||||||
.password(cfg.password)
|
let mut rt = Runtime::new().unwrap();
|
||||||
.connect()
|
// Client instance
|
||||||
.expect("client cannot connect");
|
let client = Client::new(&cfg.jid, &cfg.password).expect("could not connect to xmpp server");
|
||||||
|
|
||||||
client.register_plugin(MessagingPlugin::new());
|
// Make the two interfaces for sending and receiving independent
|
||||||
|
// of each other so we can move one into a closure.
|
||||||
|
let (mut sink, stream) = client.split();
|
||||||
|
// Wrap sink in Option so that we can take() it for the send(self)
|
||||||
|
// to consume and return it back when ready.
|
||||||
|
let mut send = move |stanza| {
|
||||||
|
sink.start_send(stanza).expect("start_send");
|
||||||
|
};
|
||||||
|
// Main loop, processes events
|
||||||
|
let done = stream.for_each(|event| {
|
||||||
|
if event.is_online() {
|
||||||
|
for recipient in recipients {
|
||||||
|
let reply = make_reply(recipient.clone(), &data);
|
||||||
|
send(reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for recipient in recipients {
|
Box::new(future::ok(()))
|
||||||
client.plugin::<MessagingPlugin>().send_message(&recipient, &data).expect("error sending message");
|
});
|
||||||
}
|
|
||||||
|
|
||||||
thread::spawn(|| {
|
thread::spawn(|| {
|
||||||
thread::sleep(Duration::from_millis(4000));
|
thread::sleep(Duration::from_millis(4000));
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
});
|
});
|
||||||
client.main().expect("error during client main")
|
|
||||||
|
// Start polling `done`
|
||||||
|
match rt.block_on(done) {
|
||||||
|
Ok(_) => {
|
||||||
|
println!("successful exiting");
|
||||||
|
std::process::exit(0);
|
||||||
|
//()
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("Fatal: {}", e);
|
||||||
|
()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a chat <message/>
|
||||||
|
fn make_reply(to: Jid, body: &str) -> Element {
|
||||||
|
let mut message = Message::new(Some(to));
|
||||||
|
message.bodies.insert(String::new(), Body(body.to_owned()));
|
||||||
|
message.into()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user