Matrix errors, retry
This commit is contained in:
parent
4a6c3db704
commit
b52dff12fe
5 changed files with 182 additions and 137 deletions
141
src/notify.rs
141
src/notify.rs
|
|
@ -1,64 +1,129 @@
|
|||
use crate::config::Config;
|
||||
|
||||
use crossbeam_channel::Receiver;
|
||||
use log::error;
|
||||
use matrix_sdk::ruma;
|
||||
use std::sync::Arc;
|
||||
use std::{
|
||||
sync::Arc,
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
|
||||
enum OptionSince<T> {
|
||||
Some(T),
|
||||
NoneSince(SystemTime),
|
||||
}
|
||||
|
||||
impl<T> OptionSince<T> {
|
||||
fn from_result<E, F: FnOnce(E)>(result: Result<T, E>, f: F) -> Self {
|
||||
match result {
|
||||
Ok(val) => Self::Some(val),
|
||||
Err(e) => {
|
||||
f(e);
|
||||
Self::NoneSince(SystemTime::now())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Option<T>> for OptionSince<T> {
|
||||
fn from(opt: Option<T>) -> Self {
|
||||
match opt {
|
||||
Some(val) => Self::Some(val),
|
||||
None => Self::NoneSince(SystemTime::now()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Notifier {
|
||||
matrix: Option<(matrix_sdk::Client, matrix_sdk::room::Joined)>,
|
||||
matrix: Option<OptionSince<(matrix_sdk::Client, matrix_sdk::room::Joined)>>,
|
||||
}
|
||||
|
||||
impl Notifier {
|
||||
async fn new(config: &Config) -> Self {
|
||||
Self {
|
||||
matrix: if config.matrix_notify {
|
||||
let user = ruma::UserId::parse(&config.matrix_user).unwrap();
|
||||
let client = matrix_sdk::Client::builder()
|
||||
.homeserver_url(&config.matrix_server)
|
||||
.user_agent("Webcomment")
|
||||
.build()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
client
|
||||
.login_username(&user, &config.matrix_password)
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
client
|
||||
.sync_once(matrix_sdk::config::SyncSettings::default())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let room_id = <&ruma::RoomId>::try_from(config.matrix_room.as_str()).unwrap();
|
||||
let room = client.get_room(room_id).unwrap();
|
||||
|
||||
if let matrix_sdk::room::Room::Joined(room) = room {
|
||||
Some((client, room))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
Some(OptionSince::from_result(init_matrix(config).await, |e| {
|
||||
error!("Cannot init Matrix: {:?}", e)
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async fn notify(&self) {
|
||||
if let Some((_client, room)) = &self.matrix {
|
||||
room.send(
|
||||
ruma::events::room::message::RoomMessageEventContent::text_plain("New comment."),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
async fn notify(&mut self, config: &Config) {
|
||||
match &self.matrix {
|
||||
None => {}
|
||||
Some(OptionSince::Some((_client, room))) => {
|
||||
room.send(
|
||||
ruma::events::room::message::RoomMessageEventContent::text_plain(
|
||||
"New comment.",
|
||||
),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
Some(OptionSince::NoneSince(earlier)) => {
|
||||
if SystemTime::now().duration_since(*earlier).unwrap()
|
||||
> Duration::from_secs(config.matrix_retry_timeout)
|
||||
{
|
||||
self.matrix = Some(OptionSince::from_result(init_matrix(config).await, |e| {
|
||||
error!("Cannot init Matrix: {:?}", e)
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run_notifier(config: Arc<Config>, recv: Receiver<()>) {
|
||||
let notifier = Notifier::new(&config).await;
|
||||
let mut notifier = Notifier::new(&config).await;
|
||||
for () in recv {
|
||||
notifier.notify().await;
|
||||
notifier.notify(&config).await;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum MatrixError {
|
||||
CannotConnect(matrix_sdk::ClientBuildError),
|
||||
CannotLogin(matrix_sdk::Error),
|
||||
CannotSync(matrix_sdk::Error),
|
||||
RoomNotJoined,
|
||||
UnknownRoom,
|
||||
}
|
||||
|
||||
async fn init_matrix(
|
||||
config: &Config,
|
||||
) -> Result<(matrix_sdk::Client, matrix_sdk::room::Joined), MatrixError> {
|
||||
let user = ruma::UserId::parse(&config.matrix_user)
|
||||
.expect("Matrix username should be in format `@user:homeserver`");
|
||||
let room_id = <&ruma::RoomId>::try_from(config.matrix_room.as_str())
|
||||
.expect("Matrix room should be in format `#roomname:homeserver` or `!roomid:homeserver`");
|
||||
|
||||
let client = matrix_sdk::Client::builder()
|
||||
.homeserver_url(&config.matrix_server)
|
||||
.user_agent("Webcomment")
|
||||
.handle_refresh_tokens()
|
||||
.build()
|
||||
.await
|
||||
.map_err(MatrixError::CannotConnect)?;
|
||||
|
||||
client
|
||||
.login_username(&user, &config.matrix_password)
|
||||
.send()
|
||||
.await
|
||||
.map_err(MatrixError::CannotLogin)?;
|
||||
client
|
||||
.sync_once(matrix_sdk::config::SyncSettings::default())
|
||||
.await
|
||||
.map_err(MatrixError::CannotSync)?;
|
||||
|
||||
let room = client.get_room(room_id).ok_or(MatrixError::UnknownRoom)?;
|
||||
|
||||
if let matrix_sdk::room::Room::Joined(room) = room {
|
||||
Ok((client, room))
|
||||
} else {
|
||||
Err(MatrixError::RoomNotJoined)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue