Code cleanup/reformat, added comments, other stuff i forgor

This commit is contained in:
0xf8 2023-04-14 21:21:45 -04:00
parent ff2d897549
commit 14246c7b60
Signed by: 0xf8
GPG Key ID: 446580D758689584
7 changed files with 203 additions and 125 deletions

2
Cargo.lock generated
View File

@ -2067,7 +2067,7 @@ checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]] [[package]]
name = "scam-police" name = "scam-police"
version = "0.4.0" version = "0.5.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"dirs", "dirs",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "scam-police" name = "scam-police"
version = "0.4.0" version = "0.5.0"
edition = "2021" edition = "2021"
authors = [ "@0xf8:projectsegfau.lt", "@jjj333:pain.agency" ] authors = [ "@0xf8:projectsegfau.lt", "@jjj333:pain.agency" ]

View File

@ -7,15 +7,19 @@ pub struct Config {
impl Config { impl Config {
pub fn load() -> Config { pub fn load() -> Config {
let keywords_reader = std::fs::File::open("config/keywords.json").expect("Couldn't find keywords.json"); let keywords_reader =
let keywords: Value = serde_json::from_reader(keywords_reader).expect("Couldn't read keywords"); std::fs::File::open("config/keywords.json").expect("Couldn't find keywords.json");
let keywords: Value =
serde_json::from_reader(keywords_reader).expect("Couldn't read keywords");
let responses_reader = std::fs::File::open("config/responses.json").expect("Couldn't find responses.json"); let responses_reader =
let responses: Value = serde_json::from_reader(responses_reader).expect("Couldn't read responses"); std::fs::File::open("config/responses.json").expect("Couldn't find responses.json");
let responses: Value =
serde_json::from_reader(responses_reader).expect("Couldn't read responses");
Self { Self {
keywords, keywords,
responses responses,
} }
} }
} }

View File

@ -1,5 +1,11 @@
use crate::{CONFIG, keywords::{Keywords, KeywordCategory}}; use crate::{
use matrix_sdk::{room::Joined, ruma::events::room::message::{RoomMessageEventContent, OriginalRoomMessageEvent}}; keywords::{KeywordCategory, Keywords},
CONFIG,
};
use matrix_sdk::{
room::Joined,
ruma::events::room::message::{OriginalRoomMessageEvent, RoomMessageEventContent},
};
use serde_json::json; use serde_json::json;
#[derive(Debug)] #[derive(Debug)]
@ -14,20 +20,24 @@ impl JudgementResult {
match self { match self {
Self::Ok => "Ok", Self::Ok => "Ok",
Self::MaybeScam => "MaybeScam", Self::MaybeScam => "MaybeScam",
Self::LikelyScam => "LikelyScam" Self::LikelyScam => "LikelyScam",
} }
} }
} }
pub struct Judgement { pub struct Judgement {
pub text: String pub text: String,
} }
impl Judgement { impl Judgement {
pub fn judge(&self) -> anyhow::Result<JudgementResult> { pub fn judge(&self) -> anyhow::Result<JudgementResult> {
// Load keywords // Load keywords
let mut keywords = CONFIG.keywords.clone(); let mut keywords = CONFIG.keywords.clone();
let keywords = keywords.as_object_mut().unwrap().get_mut("keywords").unwrap(); let keywords = keywords
.as_object_mut()
.unwrap()
.get_mut("keywords")
.unwrap();
// Turn json into Keywords // Turn json into Keywords
let verbs = Keywords::create("verbs", &keywords["verbs"]); let verbs = Keywords::create("verbs", &keywords["verbs"]);
@ -48,15 +58,23 @@ impl Judgement {
} }
} }
if count_all == 0 { return Ok(JudgementResult::Ok) }; if count_all == 0 {
if count_all < total { return Ok(JudgementResult::MaybeScam) }; return Ok(JudgementResult::Ok);
};
if count_all < total {
return Ok(JudgementResult::MaybeScam);
};
Ok(JudgementResult::LikelyScam) Ok(JudgementResult::LikelyScam)
} }
pub async fn send_debug(&self, room: &Joined) -> anyhow::Result<()> { pub async fn send_debug(&self, room: &Joined) -> anyhow::Result<()> {
// Load keywords // Load keywords
let mut keywords = CONFIG.keywords.clone(); let mut keywords = CONFIG.keywords.clone();
let keywords = keywords.as_object_mut().unwrap().get_mut("keywords").unwrap(); let keywords = keywords
.as_object_mut()
.unwrap()
.get_mut("keywords")
.unwrap();
// Turn json into Keywords // Turn json into Keywords
let verbs = Keywords::create("verbs", &keywords["verbs"]); let verbs = Keywords::create("verbs", &keywords["verbs"]);
@ -78,8 +96,12 @@ impl Judgement {
} }
let mut result = JudgementResult::LikelyScam; let mut result = JudgementResult::LikelyScam;
if count_all == 0 { result = JudgementResult::Ok } if count_all == 0 {
if count_all < total { result = JudgementResult::MaybeScam } result = JudgementResult::Ok
}
if count_all < total {
result = JudgementResult::MaybeScam
}
// Send message // Send message
let msg = RoomMessageEventContent::text_html( let msg = RoomMessageEventContent::text_html(
@ -90,11 +112,16 @@ impl Judgement {
Ok(()) Ok(())
} }
pub async fn alert(room: &Joined, event: &OriginalRoomMessageEvent, result: JudgementResult, is_reply: bool) -> anyhow::Result<()> { pub async fn alert(
room: &Joined,
event: &OriginalRoomMessageEvent,
result: JudgementResult,
is_reply: bool,
) -> anyhow::Result<()> {
let mut responses = CONFIG.responses.clone(); let mut responses = CONFIG.responses.clone();
let responses = responses.as_object_mut().unwrap(); let responses = responses.as_object_mut().unwrap();
// Add stats to end of response // Determine which message to send
let section = if is_reply { let section = if is_reply {
responses["reply"].as_object().unwrap() responses["reply"].as_object().unwrap()
} else { } else {
@ -117,12 +144,18 @@ impl Judgement {
// Send reaction // Send reaction
if !is_reply { if !is_reply {
room.send_raw(json!({ room.send_raw(
json!({
"m.relates_to": { "m.relates_to": {
"rel_type": "m.annotation", "rel_type": "m.annotation",
"event_id": event.event_id.to_string(), "event_id": event.event_id.to_string(),
"key": "🚨🚨 SCAM 🚨🚨" "key": "🚨🚨 SCAM 🚨🚨"
}}), "m.reaction", None).await.expect("Couldn't send reaction"); }}),
"m.reaction",
None,
)
.await
.expect("Couldn't send reaction");
} }
Ok(()) Ok(())

View File

@ -19,7 +19,6 @@ impl std::fmt::Display for KeywordCategory {
} }
} }
impl KeywordCategory { impl KeywordCategory {
pub fn to_json_var(&self) -> &str { pub fn to_json_var(&self) -> &str {
use KeywordCategory::*; use KeywordCategory::*;
@ -38,7 +37,7 @@ impl KeywordCategory {
"verbs" => Ok(Verb), "verbs" => Ok(Verb),
"currencies" => Ok(Currency), "currencies" => Ok(Currency),
"socials" => Ok(Social), "socials" => Ok(Social),
_ => Err(()) _ => Err(()),
} }
} }
@ -54,10 +53,9 @@ impl KeywordCategory {
} }
} }
pub struct Keywords { pub struct Keywords {
pub category: KeywordCategory, pub category: KeywordCategory,
pub words: Vec<Value> pub words: Vec<Value>,
} }
impl Keywords { impl Keywords {
@ -69,7 +67,7 @@ impl Keywords {
Self { Self {
category, category,
words: v.to_vec() words: v.to_vec(),
} }
} }

View File

@ -1,22 +1,27 @@
use matrix_sdk::{ use matrix_sdk::{
room::Room, room::Room,
ruma::{events::room::message::{ ruma::{
MessageType, OriginalSyncRoomMessageEvent, Relation, RoomMessageEvent events::room::message::{
}, OwnedRoomId}, MessageType, OriginalSyncRoomMessageEvent, Relation, RoomMessageEvent,
},
OwnedRoomId,
},
Error, LoopCtrl, Error, LoopCtrl,
}; };
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
pub mod matrix;
pub mod config; pub mod config;
pub mod keywords;
pub mod judge; pub mod judge;
pub mod keywords;
pub mod matrix;
static CONFIG: Lazy<config::Config> = Lazy::new(|| config::Config::load()); static CONFIG: Lazy<config::Config> = Lazy::new(|| config::Config::load());
async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room) -> anyhow::Result<()> { async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room) -> anyhow::Result<()> {
if let Room::Joined(room) = room { if let Room::Joined(room) = room {
let orig_event = event.to_owned().into_full_event(OwnedRoomId::from(room.room_id())); let orig_event = event
.to_owned()
.into_full_event(OwnedRoomId::from(room.room_id()));
// Ignore non-text // Ignore non-text
let MessageType::Text(text_content) = event.to_owned().content.msgtype else { let MessageType::Text(text_content) = event.to_owned().content.msgtype else {
@ -24,14 +29,24 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room) -> any
}; };
// Too short to be a scam lol // Too short to be a scam lol
if text_content.body.chars().count() < 12 { return Ok(()) } if text_content.body.chars().count() < 12 {
return Ok(());
}
let text_content = text_content.body.to_lowercase(); let text_content = text_content.body.to_lowercase();
let debug = text_content.contains(";spdebug"); let debug = text_content.contains(";spdebug");
// Ignore own messages // Ignore own messages
if !debug && event.sender == room.client().user_id().expect("Couldn't get user_id").to_string() { return Ok(()) } if !debug
&& event.sender
== room
.client()
.user_id()
.expect("Couldn't get user_id")
.to_string()
{
return Ok(());
}
let judgement = judge::Judgement { text: text_content }; let judgement = judge::Judgement { text: text_content };
@ -48,13 +63,22 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room) -> any
} else { } else {
None None
} }
}, }
_ => None _ => None,
} { } {
let event = event.as_original().unwrap(); let event = event.as_original().unwrap();
let content = event.content.to_owned().body().to_lowercase(); let content = event.content.to_owned().body().to_lowercase();
if !debug && event.sender == room.client().user_id().expect("Couldn't get user_id").to_string() { return Ok(()) } if !debug
&& event.sender
== room
.client()
.user_id()
.expect("Couldn't get user_id")
.to_string()
{
return Ok(());
}
let reply_judgement = judge::Judgement { text: content }; let reply_judgement = judge::Judgement { text: content };
@ -67,7 +91,13 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room) -> any
judge::JudgementResult::Ok => (), judge::JudgementResult::Ok => (),
judge::JudgementResult::MaybeScam => (), judge::JudgementResult::MaybeScam => (),
judge::JudgementResult::LikelyScam => { judge::JudgementResult::LikelyScam => {
judge::Judgement::alert(&room, &orig_event, judge::JudgementResult::LikelyScam, true).await?; judge::Judgement::alert(
&room,
&orig_event,
judge::JudgementResult::LikelyScam,
true,
)
.await?;
return Ok(()); return Ok(());
} }
} }
@ -78,7 +108,13 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room) -> any
judge::JudgementResult::Ok => return Ok(()), judge::JudgementResult::Ok => return Ok(()),
judge::JudgementResult::MaybeScam => return Ok(()), judge::JudgementResult::MaybeScam => return Ok(()),
judge::JudgementResult::LikelyScam => { judge::JudgementResult::LikelyScam => {
judge::Judgement::alert(&room, &orig_event, judge::JudgementResult::LikelyScam, false).await?; judge::Judgement::alert(
&room,
&orig_event,
judge::JudgementResult::LikelyScam,
false,
)
.await?;
return Ok(()); return Ok(());
} }
} }
@ -99,9 +135,15 @@ async fn main() -> anyhow::Result<()> {
let (client, sync_token) = if session_file.exists() { let (client, sync_token) = if session_file.exists() {
matrix::restore_session(&session_file).await? matrix::restore_session(&session_file).await?
} else if args.len() > 1 { } else if args.len() > 1 {
(matrix::login(&data_dir, &session_file, args.get(1).unwrap().to_owned()).await?, None) (
matrix::login(&data_dir, &session_file, args.get(1).unwrap().to_owned()).await?,
None,
)
} else { } else {
anyhow::bail!("No previous session found, please run \"{} <MXID>\"", args.get(0).unwrap()); anyhow::bail!(
"No previous session found, please run \"{} <MXID>\"",
args.get(0).unwrap()
);
}; };
let (client, sync_settings) = match matrix::sync(client, sync_token).await { let (client, sync_settings) = match matrix::sync(client, sync_token).await {
@ -114,7 +156,8 @@ async fn main() -> anyhow::Result<()> {
client.add_event_handler(on_room_message); client.add_event_handler(on_room_message);
client.sync_with_result_callback(sync_settings, |sync_result| async move { client
.sync_with_result_callback(sync_settings, |sync_result| async move {
let response = sync_result?; let response = sync_result?;
matrix::persist_sync_token(response.next_batch) matrix::persist_sync_token(response.next_batch)
@ -122,7 +165,8 @@ async fn main() -> anyhow::Result<()> {
.map_err(|err| Error::UnknownError(err.into()))?; .map_err(|err| Error::UnknownError(err.into()))?;
Ok(LoopCtrl::Continue) Ok(LoopCtrl::Continue)
}).await?; })
.await?;
Ok(()) Ok(())
} }

View File

@ -1,12 +1,12 @@
use matrix_sdk::{ use matrix_sdk::{
config::SyncSettings, ruma::api::client::filter::FilterDefinition, Client, Session config::SyncSettings, ruma::api::client::filter::FilterDefinition, Client, Session,
}; };
use rand::{distributions::Alphanumeric, thread_rng, Rng}; use rand::{distributions::Alphanumeric, thread_rng, Rng};
use serde::{Deserialize, Serialize};
use serde_json::{Value, from_str};
use std::path::{Path, PathBuf};
use reqwest::Client as http; use reqwest::Client as http;
use rpassword::prompt_password; use rpassword::prompt_password;
use serde::{Deserialize, Serialize};
use serde_json::{from_str, Value};
use std::path::{Path, PathBuf};
use tokio::fs; use tokio::fs;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@ -24,7 +24,6 @@ pub struct FullSession {
sync_token: Option<String>, sync_token: Option<String>,
} }
// //
// Matrix Login & Init // Matrix Login & Init
// //
@ -98,7 +97,7 @@ pub async fn build_client(data_dir: &Path, hs: String) -> anyhow::Result<(Client
db_path, db_path,
passphrase, passphrase,
}, },
)) ));
} }
Err(error) => match &error { Err(error) => match &error {
matrix_sdk::ClientBuildError::AutoDiscovery(_) matrix_sdk::ClientBuildError::AutoDiscovery(_)
@ -141,7 +140,10 @@ pub async fn resolve_homeserver(homeserver: String) -> anyhow::Result<String> {
hs.pop(); hs.pop();
} }
let ident = http::new().get(format!("{hs}/.well-known/matrix/client")).send().await; let ident = http::new()
.get(format!("{hs}/.well-known/matrix/client"))
.send()
.await;
match ident { match ident {
Ok(r) => { Ok(r) => {
let body = r.text().await?; let body = r.text().await?;
@ -150,13 +152,10 @@ pub async fn resolve_homeserver(homeserver: String) -> anyhow::Result<String> {
let discovered = json["m.homeserver"]["base_url"].as_str().unwrap(); let discovered = json["m.homeserver"]["base_url"].as_str().unwrap();
Ok(discovered.to_string()) Ok(discovered.to_string())
}, }
Err(e) => { Err(e) => Err(e.into()),
Err(e.into())
} }
} }
}
// //
// Persistence // Persistence