Files
matricks/src/lib.rs
Olivier 'reivilibre 4c8e4bf726 Initial commit
All tools successfully used for what I needed them for
2024-11-28 10:31:35 +00:00

152 lines
4.4 KiB
Rust

use std::path::Path;
use eyre::Context;
use matrix_sdk::{
config::SyncSettings,
matrix_auth::{MatrixAuth, MatrixSession, MatrixSessionTokens},
ruma::{
api::client::account::whoami, device_id, user_id, OwnedRoomAliasId, OwnedRoomId,
RoomAliasId, RoomId,
},
AuthSession, Client, SessionMeta,
};
use regex::{Regex, RegexBuilder};
use tracing::debug;
pub mod space_tree;
pub mod rooms_aliases;
pub mod rooms_make_read_only;
pub mod aliases_remove;
pub const USER_AGENT: &str = concat!("matricks/", env!("CARGO_PKG_VERSION"));
pub async fn get_client_from_env() -> eyre::Result<Client> {
let access_token = std::env::var("MATRICKS_TOKEN")
.context("you should supply an access token as env var MATRICKS_TOKEN")?;
let homeserver_uri = std::env::var("MATRICKS_HOMESERVER")
.context("you should supply a homeserver URI as MATRICKS_HOMESERVER env var")?;
let client = Client::builder()
.homeserver_url(&homeserver_uri)
.user_agent(USER_AGENT)
.build()
.await
.context("could not build client")?;
client
.restore_session(MatrixSession {
meta: SessionMeta {
user_id: user_id!("@nobody:example.org").to_owned(),
device_id: device_id!("???unknown???").to_owned(),
},
tokens: MatrixSessionTokens {
access_token: access_token.clone(),
refresh_token: None,
},
})
.await
.context("could not restore pre-session")?;
let whoami = client
.send(whoami::v3::Request::new(), None)
.await
.context("could not issue /whoami call")?;
debug!("logged in as {}/{:?}", whoami.user_id, whoami.device_id);
let client = Client::builder()
.homeserver_url(&homeserver_uri)
.user_agent(USER_AGENT)
.build()
.await
.context("could not build client")?;
client
.restore_session(MatrixSession {
meta: SessionMeta {
user_id: whoami.user_id,
device_id: whoami
.device_id
.unwrap_or_else(|| device_id!("???NoDeviceId???").to_owned()),
},
tokens: MatrixSessionTokens {
access_token: access_token.clone(),
refresh_token: None,
},
})
.await
.context("could not restore pre-session")?;
Ok(client)
}
async fn initial_sync(client: &Client) -> eyre::Result<()> {
// Sync once so we don't process old messages
for attempt in 0..3 {
match client
.sync_once(SyncSettings::default())
.await
.context("Failed initial sync")
{
Ok(_) => {
break;
}
Err(err) => {
if attempt == 2 {
return Err(err);
}
eprintln!("{err:?}");
}
}
}
Ok(())
}
/// Extracts the room IDs from a Room Batch File.
pub async fn parse_room_batch_file(path: &Path) -> eyre::Result<Vec<OwnedRoomId>> {
let room_id_finder_regex = RegexBuilder::new(r#"`(![^:\s]+:[a-z0-9-_.]+)`"#)
.build()
.expect("static regex");
let file_content = tokio::fs::read_to_string(&path)
.await
.with_context(|| format!("could not read file: {path:?}"))?;
let mut out = Vec::new();
for line in file_content.lines() {
for found_room_id in room_id_finder_regex.captures_iter(line) {
if let Ok(room_id) = <&RoomId>::try_from(found_room_id.get(1).unwrap().as_str()) {
out.push(room_id.to_owned());
}
}
}
Ok(out)
}
/// Extracts the room aliases from an Alias Batch File.
pub async fn parse_alias_batch_file(path: &Path) -> eyre::Result<Vec<OwnedRoomAliasId>> {
let room_id_finder_regex = RegexBuilder::new(r#"`(#[^:\s]+:[a-z0-9-_.]+)`"#)
.build()
.expect("static regex");
let file_content = tokio::fs::read_to_string(&path)
.await
.with_context(|| format!("could not read file: {path:?}"))?;
let mut out = Vec::new();
for line in file_content.lines() {
for found_room_alias in room_id_finder_regex.captures_iter(line) {
if let Ok(room_alias) =
<&RoomAliasId>::try_from(found_room_alias.get(1).unwrap().as_str())
{
out.push(room_alias.to_owned());
}
}
}
Ok(out)
}