Browse Source

Converted over to using matrix-sdk instead of directly using the ruma APIs.

master
treyzania 2 years ago
parent
commit
18ecf1b93e
6 changed files with 2335 additions and 562 deletions
  1. 2235
    460
      Cargo.lock
  2. 4
    6
      Cargo.toml
  3. 71
    58
      src/client.rs
  4. 2
    2
      src/config.rs
  5. 16
    16
      src/main.rs
  6. 7
    20
      src/spool.rs

+ 2235
- 460
Cargo.lock
File diff suppressed because it is too large
View File


+ 4
- 6
Cargo.toml View File

@@ -5,18 +5,16 @@ authors = []
edition = "2018"

[dependencies]
clap = { git = "https://github.com/clap-rs/clap", features = ["derive"] }
argh = "*"
futures = { version = "0.3.4", features = ["compat"] }
hex = "*"
hyper = "0.13.2"
hyper-tls = "0.4.1"
inotify = "0.3.0"
rand = "0.7.3"
ruma-api = "0.13.0"
ruma-client = "0.3.0"
ruma-client-api = "0.6.0"
ruma-events = "0.15.0"
ruma-identifiers = "0.14.1"
matrix-sdk = { version = "0.3", features = ["markdown"] }
serde = { version = "1", features = ["derive"] }
sha2 = "0.9"
tokio = { version = "0.2.16", features = ["fs", "io-driver", "net", "rt-core", "sync"] }
tokio-inotify = "0.4.1"
toml = "0.5.6"

+ 71
- 58
src/client.rs View File

@@ -5,104 +5,117 @@ use std::sync::Arc;
use futures::compat::Stream01CompatExt;
use futures::prelude::*;

use hyper::client::connect::dns::GaiResolver;
use hyper::client::connect::HttpConnector;
use hyper_tls::HttpsConnector;

use inotify::ffi::*;

use tokio::fs as tokiofs;
use tokio::prelude::*;
use tokio::sync::mpsc;

use tokio_inotify;
use url::Url;
//use ruma_client::Client;
//use ruma_client_api::r0::message as rumamessage;
//use ruma_events::{self, room::message::*};

use ruma_client::Client;
use ruma_client_api::r0::message as rumamessage;
use ruma_events::{self, room::message::*};
use ruma_identifiers::RoomId;
use matrix_sdk::events::{
room::message::{MessageEventContent, TextMessageEventContent},
AnyMessageEventContent,
};
use matrix_sdk::identifiers::RoomId;
use matrix_sdk::uuid::Uuid;

use crate::config::*;

#[derive(Debug)]
pub enum Error {
BadUrl,
MtxClient(ruma_client::Error),
}

impl From<ruma_client::Error> for Error {
fn from(f: ruma_client::Error) -> Self {
Self::MtxClient(f)
}
UnknownRoom(RoomId),
Matrix(matrix_sdk::Error),
}

type MatrixClient = Client<HttpsConnector<HttpConnector<GaiResolver>>>;
type MessageRequest = rumamessage::create_message_event::Request;

pub struct Message {
dest_room: RoomId,
msg: String,
text: String,
delay_secs: u32,
}

pub type MatrixClient = matrix_sdk::Client;

impl Message {
pub fn new(dest_room: RoomId, msg: String) -> Self {
Self::new_delay(dest_room, msg, 0)
}

pub fn new_delay(dest_room: RoomId, msg: String, delay_secs: u32) -> Self {
pub fn new_delay(dest_room: RoomId, text: String, delay_secs: u32) -> Self {
Self {
dest_room,
msg,
text,
delay_secs,
}
}
}

pub async fn create_and_auth_client(acct: Account) -> Result<Arc<MatrixClient>, Error> {
let hs_url = Url::parse(&acct.homeserver).map_err(|_| Error::BadUrl)?;
let c = MatrixClient::https(hs_url, None);
let hs_url = url::Url::parse(&acct.homeserver).map_err(|_| Error::BadUrl)?;

let cc = matrix_sdk::ClientConfig::new()
.user_agent("mtxspooler")
.unwrap();
let c = matrix_sdk::Client::new_with_config(hs_url, cc).map_err(Error::Matrix)?;

// Now log in.
match acct.auth {
Auth::UsernamePass(un, pw) => c.log_in(un, pw, acct.device_id, acct.display).await?,
};
Auth::UsernamePass(un, pw) => {
let didref = acct.device_id.as_deref();
c.login(&un, &pw, didref, didref)
.map_err(Error::Matrix)
.await?;
}
}

Ok(Arc::new(c))
}

pub async fn submit_messages(cli: Arc<MatrixClient>, mut recv: mpsc::Receiver<Message>) {
let mut rng = rand::thread_rng();

while let Some(msg) = recv.recv().await {
let req = make_text_request(msg.dest_room.clone(), &msg.msg, &mut rng);
if let Err(e) = cli.request(req).await {
panic!("[client] error sending request: {:?}", e);
if let Err(e) = do_submit_msg(&msg, &cli).await {
panic!("[client] error handling message submission: {:?}", e);
}
}
}

fn make_text_request<R: rand::Rng>(room_id: RoomId, msg: &str, rng: &mut R) -> MessageRequest {
let inner = TextMessageEventContent {
body: String::from(msg),
format: None,
formatted_body: None,
relates_to: None,
};
let mec = MessageEventContent::Text(inner);
MessageRequest {
room_id: room_id,
event_type: ruma_events::EventType::RoomMessage,
txn_id: make_txn_id(rng),
data: mec,
}
}
async fn do_submit_msg(msg: &Message, cli: &Arc<MatrixClient>) -> Result<(), Error> {
let jroom = get_room_try_join(cli, &msg.dest_room).await?;

const TXN_ID_LEN: usize = 20;
let mec = MessageEventContent::text_plain(&msg.text);
let ec = AnyMessageEventContent::RoomMessage(mec);
jroom.send(ec, None).map_err(Error::Matrix).await?;

fn make_txn_id<R: rand::Rng>(rng: &mut R) -> String {
let mut buf = String::with_capacity(TXN_ID_LEN);
for _ in 0..TXN_ID_LEN {
buf.push((rng.gen_range(0, 26) + ('a' as u8)) as char);
Ok(())
}

pub async fn get_room_try_join(
cli: &Arc<MatrixClient>,
rid: &RoomId,
) -> Result<matrix_sdk::room::Joined, Error> {
use matrix_sdk::room::*;
match cli
.get_room(rid)
.ok_or_else(|| Error::UnknownRoom(rid.clone()))?
{
Room::Joined(j) => Ok(j),
Room::Invited(i) => {
i.accept_invitation().map_err(Error::Matrix).await?;
Ok(cli.get_joined_room(rid).expect("client: get invited room"))
}
Room::Left(l) => {
l.join().map_err(Error::Matrix).await?;
Ok(cli.get_joined_room(rid).expect("client: get room joined"))
}
}
buf
}

fn gen_device_id(un: &str, pw: &str) -> String {
use sha2::Digest;
let mut hasher = sha2::Sha256::new();
hasher.update(un.as_bytes());
hasher.update("\0");
hasher.update(pw.as_bytes());
hasher.update("\0_mtxspooler_salt");
let h: [u8; 32] = hasher.finalize().into();
hex::encode(h)
}

+ 2
- 2
src/config.rs View File

@@ -6,8 +6,6 @@ use std::path::PathBuf;

use futures::prelude::*;

use ruma_identifiers::{self, RoomId};

use tokio::fs as tokiofs;
use tokio::prelude::*;

@@ -15,6 +13,8 @@ use toml;

use serde::Deserialize;

use matrix_sdk::identifiers::RoomId;

// FIXME Some of these error types are only used in the main module.
#[derive(Debug)]
pub enum Error {

+ 16
- 16
src/main.rs View File

@@ -6,7 +6,7 @@
use std::collections::*;
use std::path::PathBuf;

use clap::Clap;
use argh::FromArgs;

use tokio::runtime;
use tokio::sync::mpsc;
@@ -17,33 +17,33 @@ mod spool;

use crate::config::*;

#[derive(Clap)]
#[clap(version = "0.1")]
#[derive(FromArgs, PartialEq, Debug)]
#[argh(description = "mtxspooler")]
struct Opts {
#[clap(
name = "config",
short = "c",
help = "Read this config file by itself, parsed before -C"
#[argh(
option,
short = 'c',
description = "read this config file by itself, parsed before -C"
)]
conf: Option<PathBuf>,

#[clap(
name = "configdir",
short = "C",
help = "Read all config files in this directory"
#[argh(
option,
short = 'C',
description = "read all config files in this directory"
)]
conf_dir: Option<PathBuf>,

#[clap(
name = "triggerpath",
short = "r",
help = "Delete this file to trigger a config reload [NYI]"
#[argh(
option,
short = 'r',
description = "delete this file to trigger a config reload [NYI]"
)]
reload_trigger: Option<PathBuf>,
}

fn main() {
let opts = Opts::parse();
let opts: Opts = argh::from_env();
if opts.reload_trigger.is_some() {
eprintln!("[init] warning: reload trigger file specified, but this option is not supported yet, ignoring...");
}

+ 7
- 20
src/spool.rs View File

@@ -6,38 +6,25 @@ use std::sync::Arc;
use futures::compat::Stream01CompatExt;
use futures::prelude::*;

use hyper::client::connect::dns::GaiResolver;
use hyper::client::connect::HttpConnector;
use hyper_tls::HttpsConnector;

use inotify::ffi::*;

use matrix_sdk::identifiers::RoomId;

use tokio::fs as tokiofs;
use tokio::prelude::*;
use tokio::sync::mpsc;

use tokio_inotify;

use url::Url;

use ruma_client::Client;
use ruma_client_api::r0::message as rumamessage;
use ruma_events::{self, room::message::*};
use ruma_identifiers::RoomId;

use crate::client;
use crate::client::{self, MatrixClient};
use crate::config::{self, *};

type MatrixClient = Client<HttpsConnector<HttpConnector<GaiResolver>>>;
type MessageRequest = rumamessage::create_message_event::Request;

#[derive(Debug)]
pub enum Error {
FileFormatMismatch,
BadUrl,
UnspecifiedClient(String),
Io(io::Error),
MtxClient(ruma_client::Error),
Matrix(matrix_sdk::Error),
}

impl From<io::Error> for Error {
@@ -46,9 +33,9 @@ impl From<io::Error> for Error {
}
}

impl From<ruma_client::Error> for Error {
fn from(f: ruma_client::Error) -> Self {
Self::MtxClient(f)
impl From<matrix_sdk::Error> for Error {
fn from(f: matrix_sdk::Error) -> Self {
Self::Matrix(f)
}
}


Loading…
Cancel
Save