Quellcode durchsuchen

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

master
treyzania vor 2 Jahren
Ursprung
Commit
18ecf1b93e
6 geänderte Dateien mit 2335 neuen und 562 gelöschten Zeilen
  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
Datei-Diff unterdrückt, da er zu groß ist
Datei anzeigen


+ 4
- 6
Cargo.toml Datei anzeigen

edition = "2018" edition = "2018"


[dependencies] [dependencies]
clap = { git = "https://github.com/clap-rs/clap", features = ["derive"] }
argh = "*"
futures = { version = "0.3.4", features = ["compat"] } futures = { version = "0.3.4", features = ["compat"] }
hex = "*"
hyper = "0.13.2" hyper = "0.13.2"
hyper-tls = "0.4.1" hyper-tls = "0.4.1"
inotify = "0.3.0" inotify = "0.3.0"
rand = "0.7.3" 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"] } serde = { version = "1", features = ["derive"] }
sha2 = "0.9"
tokio = { version = "0.2.16", features = ["fs", "io-driver", "net", "rt-core", "sync"] } tokio = { version = "0.2.16", features = ["fs", "io-driver", "net", "rt-core", "sync"] }
tokio-inotify = "0.4.1" tokio-inotify = "0.4.1"
toml = "0.5.6" toml = "0.5.6"

+ 71
- 58
src/client.rs Datei anzeigen

use futures::compat::Stream01CompatExt; use futures::compat::Stream01CompatExt;
use futures::prelude::*; 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::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::*; use crate::config::*;


#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
BadUrl, 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 { pub struct Message {
dest_room: RoomId, dest_room: RoomId,
msg: String,
text: String,
delay_secs: u32, delay_secs: u32,
} }


pub type MatrixClient = matrix_sdk::Client;

impl Message { impl Message {
pub fn new(dest_room: RoomId, msg: String) -> Self { pub fn new(dest_room: RoomId, msg: String) -> Self {
Self::new_delay(dest_room, msg, 0) 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 { Self {
dest_room, dest_room,
msg,
text,
delay_secs, delay_secs,
} }
} }
} }


pub async fn create_and_auth_client(acct: Account) -> Result<Arc<MatrixClient>, Error> { 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 { 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)) Ok(Arc::new(c))
} }


pub async fn submit_messages(cli: Arc<MatrixClient>, mut recv: mpsc::Receiver<Message>) { 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 { 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 Datei anzeigen



use futures::prelude::*; use futures::prelude::*;


use ruma_identifiers::{self, RoomId};

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




use serde::Deserialize; use serde::Deserialize;


use matrix_sdk::identifiers::RoomId;

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

+ 16
- 16
src/main.rs Datei anzeigen

use std::collections::*; use std::collections::*;
use std::path::PathBuf; use std::path::PathBuf;


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


use tokio::runtime; use tokio::runtime;
use tokio::sync::mpsc; use tokio::sync::mpsc;


use crate::config::*; use crate::config::*;


#[derive(Clap)]
#[clap(version = "0.1")]
#[derive(FromArgs, PartialEq, Debug)]
#[argh(description = "mtxspooler")]
struct Opts { 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>, 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>, 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>, reload_trigger: Option<PathBuf>,
} }


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

+ 7
- 20
src/spool.rs Datei anzeigen

use futures::compat::Stream01CompatExt; use futures::compat::Stream01CompatExt;
use futures::prelude::*; use futures::prelude::*;


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

use inotify::ffi::*; use inotify::ffi::*;


use matrix_sdk::identifiers::RoomId;

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


use tokio_inotify; 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, *}; use crate::config::{self, *};


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

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


impl From<io::Error> for Error { 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)
} }
} }



Laden…
Abbrechen
Speichern