Matrix errors, retry

This commit is contained in:
Pascal Engélibert 2022-10-25 18:22:49 +02:00
parent 4a6c3db704
commit b52dff12fe
Signed by: tuxmain
GPG key ID: 3504BC6D362F7DCA
5 changed files with 182 additions and 137 deletions

155
Cargo.lock generated
View file

@ -62,7 +62,7 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
"getrandom 0.2.7",
"getrandom 0.2.8",
"once_cell",
"version_check",
]
@ -87,9 +87,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.65"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602"
checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
[[package]]
name = "anymap2"
@ -331,7 +331,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1"
dependencies = [
"futures-core",
"getrandom 0.2.7",
"getrandom 0.2.8",
"instant",
"pin-project-lite 0.2.9",
"rand 0.8.5",
@ -346,9 +346,9 @@ checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270"
[[package]]
name = "base64"
version = "0.13.0"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "base64ct"
@ -503,9 +503,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.0.17"
version = "4.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06badb543e734a2d6568e19a40af66ed5364360b9226184926f89d229b4b4267"
checksum = "335867764ed2de42325fafe6d18b8af74ba97ee0c590fa016f157535b42ab04b"
dependencies = [
"bitflags",
"clap_derive",
@ -515,9 +515,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.0.13"
version = "4.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c42f169caba89a7d512b5418b09864543eeb4d497416c917d7137863bd2076ad"
checksum = "16a1b0f6422af32d5da0c58e2703320f379216ee70198241c84173a8c5ac28f3"
dependencies = [
"heck",
"proc-macro-error",
@ -690,9 +690,9 @@ dependencies = [
[[package]]
name = "cxx"
version = "1.0.79"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f83d0ebf42c6eafb8d7c52f7e5f2d3003b89c7aa4fd2b79229209459a849af8"
checksum = "6b7d4e43b25d3c994662706a1d4fcfc32aaa6afd287502c111b237093bb23f3a"
dependencies = [
"cc",
"cxxbridge-flags",
@ -702,9 +702,9 @@ dependencies = [
[[package]]
name = "cxx-build"
version = "1.0.79"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07d050484b55975889284352b0ffc2ecbda25c0c55978017c132b29ba0818a86"
checksum = "84f8829ddc213e2c1368e51a2564c552b65a8cb6a28f31e576270ac81d5e5827"
dependencies = [
"cc",
"codespan-reporting",
@ -717,15 +717,15 @@ dependencies = [
[[package]]
name = "cxxbridge-flags"
version = "1.0.79"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d2199b00553eda8012dfec8d3b1c75fce747cf27c169a270b3b99e3448ab78"
checksum = "e72537424b474af1460806647c41d4b6d35d09ef7fe031c5c2fa5766047cc56a"
[[package]]
name = "cxxbridge-macro"
version = "1.0.79"
version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb67a6de1f602736dd7eaead0080cf3435df806c61b24b13328db128c58868f"
checksum = "309e4fb93eed90e1e14bea0da16b209f81813ba9fc7830c20ed151dd7bc0a4d7"
dependencies = [
"proc-macro2",
"quote",
@ -1092,9 +1092,9 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.7"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"libc",
@ -1149,9 +1149,9 @@ dependencies = [
[[package]]
name = "h2"
version = "0.3.14"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be"
checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
dependencies = [
"bytes",
"fnv",
@ -1470,9 +1470,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.135"
version = "0.2.136"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
checksum = "55edcf6c0bb319052dea84732cf99db461780fd5e8d3eb46ab6ff312ab31f197"
[[package]]
name = "link-cplusplus"
@ -1521,9 +1521,9 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
name = "matrix-sdk"
version = "0.6.0"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37a075b2690bc305ca02755a868cfa9f9779cfc2353f7184f3cf1a0a405ecdb2"
checksum = "cbeafb4809f33f377165f2fbcf10e0613053ad206762194c3050a727fd3abcb2"
dependencies = [
"anymap2",
"async-once-cell",
@ -1555,9 +1555,9 @@ dependencies = [
[[package]]
name = "matrix-sdk-base"
version = "0.6.0"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de51f1662779739e7a74677f37cdf744a2c82dfb7618e89d5e18967a4540181b"
checksum = "b944f6d1fc8779ba790dd0b942ceff45c626c1f5da847f01122d355ad06511bd"
dependencies = [
"async-stream",
"async-trait",
@ -1616,14 +1616,14 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
[[package]]
name = "mio"
version = "0.8.4"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
dependencies = [
"libc",
"log",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.36.1",
"windows-sys",
]
[[package]]
@ -1714,7 +1714,7 @@ dependencies = [
"libc",
"redox_syscall",
"smallvec",
"windows-sys 0.42.0",
"windows-sys",
]
[[package]]
@ -1866,9 +1866,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "polling"
version = "2.3.0"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899b00b9c8ab553c743b3e11e87c5c7d423b2a2de229ba95b24a756344748011"
checksum = "ab4609a838d88b73d8238967b60dd115cc08d38e2bbaf51ee1e4b695f89122e2"
dependencies = [
"autocfg",
"cfg-if",
@ -2019,7 +2019,7 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom 0.2.7",
"getrandom 0.2.8",
]
[[package]]
@ -2046,7 +2046,7 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [
"getrandom 0.2.7",
"getrandom 0.2.8",
"redox_syscall",
"thiserror",
]
@ -2319,18 +2319,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.145"
version = "1.0.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b"
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.145"
version = "1.0.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c"
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
dependencies = [
"proc-macro2",
"quote",
@ -2601,9 +2601,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.102"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
dependencies = [
"proc-macro2",
"quote",
@ -2821,15 +2821,25 @@ dependencies = [
]
[[package]]
name = "toml_edit"
version = "0.14.4"
name = "toml_datetime"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5376256e44f2443f8896ac012507c19a012df0fe8758b55246ae51a2279db51f"
checksum = "808b51e57d0ef8f71115d8f3a01e7d3750d01c79cac4b3eda910f4389fdf92fd"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1541ba70885967e662f69d31ab3aeca7b1aaecfcd58679590b893e9239c3646"
dependencies = [
"combine",
"indexmap",
"itertools",
"serde",
"toml_datetime",
]
[[package]]
@ -3027,7 +3037,7 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "feb41e78f93363bb2df8b0e86a2ca30eed7806ea16ea0c790d757cf93f79be83"
dependencies = [
"getrandom 0.2.7",
"getrandom 0.2.8",
]
[[package]]
@ -3271,19 +3281,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
dependencies = [
"windows_aarch64_msvc 0.36.1",
"windows_i686_gnu 0.36.1",
"windows_i686_msvc 0.36.1",
"windows_x86_64_gnu 0.36.1",
"windows_x86_64_msvc 0.36.1",
]
[[package]]
name = "windows-sys"
version = "0.42.0"
@ -3291,12 +3288,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc 0.42.0",
"windows_i686_gnu 0.42.0",
"windows_i686_msvc 0.42.0",
"windows_x86_64_gnu 0.42.0",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc 0.42.0",
"windows_x86_64_msvc",
]
[[package]]
@ -3305,48 +3302,24 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
[[package]]
name = "windows_aarch64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
[[package]]
name = "windows_i686_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]]
name = "windows_i686_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
[[package]]
name = "windows_i686_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
[[package]]
name = "windows_i686_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
[[package]]
name = "windows_x86_64_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.0"
@ -3359,12 +3332,6 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
[[package]]
name = "windows_x86_64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.0"

View file

@ -9,20 +9,20 @@ edition = "2021"
[dependencies]
argon2 = "0.4.1"
base64 = "0.13.0"
clap = { version = "4.0.17", default-features = false, features = ["derive", "std"] }
base64 = "0.13.1"
clap = { version = "4.0.18", default-features = false, features = ["derive", "std"] }
crossbeam-channel = "0.5.6"
directories = "4.0.1"
log = "0.4.17"
matrix-sdk = { version = "0.6.0", default-features = false, features = ["rustls-tls"] }
matrix-sdk = { version = "0.6.2", default-features = false, features = ["rustls-tls"] }
rand = "0.8.5"
rand_core = { version = "0.6.4", features = ["std"] }
rpassword = "7.1.0"
serde = { version = "1.0.145", features = ["derive", "rc"] }
serde = { version = "1.0.147", features = ["derive", "rc"] }
sha2 = "0.10.6"
sled = "0.34.7"
tera = { version = "1.17.1", features = ["builtins", "date-locale"] }
tide = { version = "0.16.0", default-features = false, features = ["h1-server", "cookies", "logger"] }
tokio = { version = "1.21.2", features = ["macros", "rt-multi-thread"] }
toml_edit = { version = "0.14.4", features = ["easy"] }
toml_edit = { version = "0.15.0", features = ["easy"] }
typed-sled = "0.2.0"

View file

@ -28,6 +28,12 @@ Each topic is accessible at `/t/<topic_name>`.
Admin login is accessible at `/admin`. Once authenticated, you can see the pending comments on the topic pages.
### Matrix
If enabled, a message can be sent to a Matrix room (private or public) on every new comment.
The account must have joined the room for Webcomment to be able to send messages to it.
## License
CopyLeft 2022 Pascal Engélibert [(why copyleft?)](//txmn.tk/blog/why-copyleft/)

View file

@ -45,6 +45,9 @@ pub struct Config {
pub matrix_notify: bool,
#[serde(default = "Config::default_matrix_password")]
pub matrix_password: String,
/// If connection fails, retry connecting after minimum this duration (seconds)
#[serde(default = "Config::default_matrix_retry_timeout")]
pub matrix_retry_timeout: u64,
#[serde(default = "Config::default_matrix_room")]
pub matrix_room: String,
#[serde(default = "Config::default_matrix_server")]
@ -108,6 +111,9 @@ impl Config {
fn default_matrix_password() -> String {
"".into()
}
fn default_matrix_retry_timeout() -> u64 {
3600
}
fn default_matrix_room() -> String {
"#maintenance:matrix.txmn.tk".into()
}
@ -144,6 +150,7 @@ impl Default for Config {
listen: Self::default_listen(),
matrix_notify: Self::default_matrix_notify(),
matrix_password: Self::default_matrix_password(),
matrix_retry_timeout: Self::default_matrix_retry_timeout(),
matrix_room: Self::default_matrix_room(),
matrix_server: Self::default_matrix_server(),
matrix_user: Self::default_matrix_user(),

View file

@ -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)
}
}