"rand 0.7.3", | "rand 0.7.3", | ||||
"serde", | "serde", | ||||
"sha2", | "sha2", | ||||
"tokio 0.2.25", | |||||
"tokio 1.8.1", | |||||
"tokio-inotify", | "tokio-inotify", | ||||
"toml", | "toml", | ||||
"url", | "url", | ||||
"opaque-debug", | "opaque-debug", | ||||
] | ] | ||||
[[package]] | |||||
name = "signal-hook-registry" | |||||
version = "1.4.0" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" | |||||
dependencies = [ | |||||
"libc", | |||||
] | |||||
[[package]] | [[package]] | ||||
name = "signature" | name = "signature" | ||||
version = "1.3.1" | version = "1.3.1" | ||||
"futures-core", | "futures-core", | ||||
"iovec", | "iovec", | ||||
"lazy_static", | "lazy_static", | ||||
"libc", | |||||
"memchr", | "memchr", | ||||
"mio 0.6.23", | "mio 0.6.23", | ||||
"mio-uds", | |||||
"pin-project-lite 0.1.12", | "pin-project-lite 0.1.12", | ||||
"slab", | "slab", | ||||
] | ] | ||||
"libc", | "libc", | ||||
"memchr", | "memchr", | ||||
"mio 0.7.13", | "mio 0.7.13", | ||||
"num_cpus", | |||||
"once_cell", | |||||
"parking_lot 0.11.1", | |||||
"pin-project-lite 0.2.7", | "pin-project-lite 0.2.7", | ||||
"signal-hook-registry", | |||||
"tokio-macros", | |||||
"winapi 0.3.9", | "winapi 0.3.9", | ||||
] | ] | ||||
"log", | "log", | ||||
] | ] | ||||
[[package]] | |||||
name = "tokio-macros" | |||||
version = "1.3.0" | |||||
source = "registry+https://github.com/rust-lang/crates.io-index" | |||||
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" | |||||
dependencies = [ | |||||
"proc-macro2 1.0.27", | |||||
"quote 1.0.9", | |||||
"syn 1.0.73", | |||||
] | |||||
[[package]] | [[package]] | ||||
name = "tokio-native-tls" | name = "tokio-native-tls" | ||||
version = "0.3.0" | version = "0.3.0" |
[dependencies] | [dependencies] | ||||
argh = "*" | argh = "*" | ||||
futures = { version = "0.3.4", features = ["compat"] } | |||||
futures = { version = "0.3.15", features = ["compat"] } | |||||
hex = "*" | hex = "*" | ||||
hyper = "0.13.2" | hyper = "0.13.2" | ||||
hyper-tls = "0.4.1" | hyper-tls = "0.4.1" | ||||
matrix-sdk = { version = "0.3", features = ["markdown"] } | matrix-sdk = { version = "0.3", features = ["markdown"] } | ||||
serde = { version = "1", features = ["derive"] } | serde = { version = "1", features = ["derive"] } | ||||
sha2 = "0.9" | sha2 = "0.9" | ||||
tokio = { version = "0.2.16", features = ["fs", "io-driver", "net", "rt-core", "sync"] } | |||||
tokio = { version = "1.8", features = ["full"] } | |||||
tokio-inotify = "0.4.1" | tokio-inotify = "0.4.1" | ||||
toml = "0.5.6" | toml = "0.5.6" | ||||
url = "2.1.1" | url = "2.1.1" |
use std::path::PathBuf; | use std::path::PathBuf; | ||||
use std::sync::Arc; | use std::sync::Arc; | ||||
use futures::compat::Stream01CompatExt; | |||||
use futures::prelude::*; | |||||
use tokio::io::{AsyncRead, AsyncReadExt}; | |||||
use tokio::sync::mpsc; | use tokio::sync::mpsc; | ||||
use futures::prelude::*; | |||||
//use ruma_client::Client; | //use ruma_client::Client; | ||||
//use ruma_client_api::r0::message as rumamessage; | //use ruma_client_api::r0::message as rumamessage; | ||||
//use ruma_events::{self, room::message::*}; | //use ruma_events::{self, room::message::*}; |
use std::path::PathBuf; | use std::path::PathBuf; | ||||
use futures::prelude::*; | use futures::prelude::*; | ||||
use futures::stream::TryStreamExt; | |||||
use tokio::fs as tokiofs; | use tokio::fs as tokiofs; | ||||
use tokio::prelude::*; | |||||
use tokio::io::{AsyncRead, AsyncReadExt}; | |||||
use toml; | use toml; | ||||
use serde::Deserialize; | use serde::Deserialize; | ||||
} | } | ||||
pub async fn find_configs(search_dir: &PathBuf) -> Result<Vec<PathBuf>, Error> { | pub async fn find_configs(search_dir: &PathBuf) -> Result<Vec<PathBuf>, Error> { | ||||
let items: Vec<tokiofs::DirEntry> = tokiofs::read_dir(search_dir).await?.try_collect().await?; | |||||
let mut items: Vec<tokiofs::DirEntry> = Vec::new(); | |||||
let mut rd = tokiofs::read_dir(search_dir).await?; | |||||
while let Some(dent) = rd.next_entry().await? { | |||||
items.push(dent); | |||||
} | |||||
Ok(items | Ok(items | ||||
.into_iter() | .into_iter() | ||||
.filter(|de| { | .filter(|de| { |
} | } | ||||
let mut rt = make_runtime(); | let mut rt = make_runtime(); | ||||
rt.block_on(main_inner(opts)); | |||||
} | |||||
async fn main_inner(opts: Opts) { | |||||
// Figure out which files we want to configure. | // Figure out which files we want to configure. | ||||
let mut confs = Vec::new(); | let mut confs = Vec::new(); | ||||
if let Some(main) = opts.conf { | if let Some(main) = opts.conf { | ||||
confs.push(main.clone()); | confs.push(main.clone()); | ||||
} | } | ||||
if let Some(dir) = opts.conf_dir { | if let Some(dir) = opts.conf_dir { | ||||
match rt.block_on(find_configs(&dir)) { | |||||
match find_configs(&dir).await { | |||||
Ok(paths) => confs.extend(paths), | Ok(paths) => confs.extend(paths), | ||||
Err(e) => { | Err(e) => { | ||||
eprintln!("[init] error reading configuration: {:?}", e); | eprintln!("[init] error reading configuration: {:?}", e); | ||||
// Process configuration. | // Process configuration. | ||||
// TODO Remove all these cases of `block_on` except for a final toplevel task. | // TODO Remove all these cases of `block_on` except for a final toplevel task. | ||||
let config = match rt.block_on(parse_configs(&confs)) { | |||||
let config = match parse_configs(&confs).await { | |||||
Ok(c) => c, | Ok(c) => c, | ||||
Err(e) => { | Err(e) => { | ||||
eprintln!("[init] error parsing configuration: {:?}", e); | eprintln!("[init] error parsing configuration: {:?}", e); | ||||
// Init each account and put outgoing channels into a table for later reference. | // Init each account and put outgoing channels into a table for later reference. | ||||
for cc in config.accounts.iter() { | for cc in config.accounts.iter() { | ||||
match rt.block_on(client::create_and_auth_client(cc.1.clone())) { | |||||
match client::create_and_auth_client(cc.1.clone()).await { | |||||
Ok(c) => { | Ok(c) => { | ||||
let (send, recv) = mpsc::channel(2); // FIXME configurable | let (send, recv) = mpsc::channel(2); // FIXME configurable | ||||
clients.insert(cc.0.clone(), send); | clients.insert(cc.0.clone(), send); | ||||
} | } | ||||
// This is where the real stuff actually happens. | // This is where the real stuff actually happens. | ||||
match rt.block_on(spool::start_spoolers(config, clients)) { | |||||
match spool::start_spoolers(config, clients).await { | |||||
Ok(_) => {} | Ok(_) => {} | ||||
Err(e) => println!("fatal error: {:?}", e), | Err(e) => println!("fatal error: {:?}", e), | ||||
} | } | ||||
// just wait I guess? | // just wait I guess? | ||||
rt.block_on(futures::future::join_all(sender_futs.into_iter())); | |||||
futures::future::join_all(sender_futs.into_iter()).await; | |||||
} | } | ||||
fn make_runtime() -> runtime::Runtime { | fn make_runtime() -> runtime::Runtime { | ||||
runtime::Builder::new() | |||||
.max_threads(1) | |||||
runtime::Builder::new_current_thread() | |||||
.thread_name("mtxspooler-worker") | |||||
.enable_all() | .enable_all() | ||||
.basic_scheduler() | |||||
.build() | .build() | ||||
.expect("init runtime") | |||||
.expect("rt: init") | |||||
} | } |
use core::time; | |||||
use std::collections::*; | use std::collections::*; | ||||
use std::io; | |||||
use std::path::PathBuf; | use std::path::PathBuf; | ||||
use std::sync::Arc; | use std::sync::Arc; | ||||
use std::time; | |||||
use futures::compat::Stream01CompatExt; | use futures::compat::Stream01CompatExt; | ||||
use futures::prelude::*; | use futures::prelude::*; | ||||
use matrix_sdk::identifiers::RoomId; | use matrix_sdk::identifiers::RoomId; | ||||
use tokio::fs as tokiofs; | use tokio::fs as tokiofs; | ||||
use tokio::prelude::*; | |||||
use tokio::io::{AsyncRead, AsyncReadExt}; | |||||
use tokio::sync::mpsc; | use tokio::sync::mpsc; | ||||
use tokio_inotify; | use tokio_inotify; |