commit c2082599d4c94928a4b5a44ca305edb703918073
parent 937fd90206883ea5e1e9a696e677962dfa549e35
Author: n0tr1v <n0tr1v@protonmail.com>
Date: Fri, 7 Apr 2023 15:43:06 -0700
test
Diffstat:
| M | src/main.rs | | | 169 | +++++++++++++++++++++++++++++++++++++++++++------------------------------------ |
1 file changed, 92 insertions(+), 77 deletions(-)
diff --git a/src/main.rs b/src/main.rs
@@ -36,7 +36,7 @@ use serde_derive::{Deserialize, Serialize};
use std::collections::HashMap;
use std::io::Cursor;
use std::io::{self, Write};
-use std::sync::Arc;
+use std::sync::{Arc, MutexGuard};
use std::sync::Mutex;
use std::thread;
use std::time::Duration;
@@ -1361,6 +1361,12 @@ fn set_profile_base_info(
Ok(())
}
+fn parse_date(date: &str, datetime_fmt: &str) -> NaiveDateTime {
+ let now = Utc::now();
+ let date_fmt = format!("%Y-{}", datetime_fmt);
+ NaiveDateTime::parse_from_str(format!("{}-{}", now.year(), date).as_str(), date_fmt.as_str()).unwrap()
+}
+
fn get_msgs(
client: &Client,
base_url: &str,
@@ -1376,12 +1382,6 @@ fn get_msgs(
datetime_fmt: &str,
messages: &Arc<Mutex<Vec<Message>>>) -> anyhow::Result<()>
{
- let parse_date = |date: &str| -> NaiveDateTime {
- let now = Utc::now();
- let date_fmt = format!("%Y-{}", datetime_fmt);
- NaiveDateTime::parse_from_str(format!("{}-{}", now.year(), date).as_str(), date_fmt.as_str()).unwrap()
- };
-
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let source = Decoder::new_mp3(Cursor::new(SOUND1)).unwrap();
@@ -1399,79 +1399,13 @@ fn get_msgs(
return Ok(());
}
};
- let mut messages = messages.lock().unwrap();
- if let Some(last_known_msg) = messages.get(0) {
- let last_known_msg_parsed_dt = parse_date(&last_known_msg.date);
- for new_msg in &new_messages {
- let new_parsed_dt = parse_date(&new_msg.date);
-
- if last_known_msg_parsed_dt > new_parsed_dt || (new_msg.date == last_known_msg.date && last_known_msg.text == new_msg.text) {
- break;
- }
-
- if let Some((from, to_opt, msg)) = get_message(&new_msg.text, &members_tag) {
- // Process new messages
-
- if username == N0TR1V {
- // !bhcli filters
- if msg == "!bhcli" {
- let msg = format!("@{} -> {}", from, BHCLI_BLOG_URL).to_owned();
- tx.send(PostType::Post(msg, None)).unwrap();
- } else if msg == "/logout" && from == STUXNET {
- log::error!("forced logout by {}", from);
- sig.lock().unwrap().signal(&ExitSignal::Terminate);
- return Ok(());
- }
- // Auto kick spammers
- if from != N0TR1V && from != FAGGOT {
- if msg.contains(FAGGOT) && (msg.contains("pedo") || msg.contains("child")) {
- let msg = "spam".to_owned();
- let username_to_kick = from.to_owned();
- tx.send(PostType::Kick(msg, username_to_kick)).unwrap();
- }
- }
- }
-
- // Notify when tagged
- if msg.contains(format!("@{}", &username).as_str()) {
- should_notify = true;
- }
- // Notify when PM is received
- if let Some(to) = to_opt {
- if to == username && msg != "!up" {
- should_notify = true;
- }
- }
- }
- }
+ let messages = messages.lock().unwrap();
+ if process_new_messages(&new_messages, &messages, datetime_fmt, members_tag, username, &mut should_notify, tx, sig).is_err() {
+ return Ok(());
}
// Build messages vector. Tag deleted messages.
- let mut old_msg_ptr = 0;
- for new_msg in new_messages.into_iter() {
- loop {
- if let Some(old_msg) = messages.get_mut(old_msg_ptr) {
- let new_parsed_dt = parse_date(&new_msg.date);
- let parsed_dt = parse_date(&old_msg.date);
- if new_parsed_dt < parsed_dt {
- old_msg.deleted = true;
- old_msg_ptr += 1;
- continue;
- }
- if new_parsed_dt == parsed_dt {
- if old_msg.text != new_msg.text {
- messages.insert(old_msg_ptr, new_msg);
- old_msg_ptr += 1;
- }
- old_msg_ptr += 1;
- break;
- }
- }
- messages.insert(old_msg_ptr, new_msg);
- old_msg_ptr += 1;
- break;
- }
- }
+ update_messages(new_messages, messages, datetime_fmt);
// Notify new messages has arrived.
// This ensure that we redraw the messages on the screen right away.
@@ -1492,6 +1426,87 @@ fn get_msgs(
Ok(())
}
+fn process_new_messages(
+ new_messages: &Vec<Message>, messages: &MutexGuard<Vec<Message>>,
+ datetime_fmt: &str, members_tag: &str, username: &str, should_notify: &mut bool,
+ tx: &crossbeam_channel::Sender<PostType>,
+ sig: &Arc<Mutex<Sig>>) -> anyhow::Result<()> {
+ if let Some(last_known_msg) = messages.get(0) {
+ let last_known_msg_parsed_dt = parse_date(&last_known_msg.date, datetime_fmt);
+ let filtered = new_messages
+ .iter()
+ .filter(|new_msg| last_known_msg_parsed_dt > parse_date(&new_msg.date, datetime_fmt) || (new_msg.date == last_known_msg.date && last_known_msg.text == new_msg.text));
+ for new_msg in filtered {
+ if let Some((from, to_opt, msg)) = get_message(&new_msg.text, &members_tag) {
+ // Process new messages
+ if username == N0TR1V {
+ n0tr1v_only_process_msg(&from, &msg, &tx, &sig)?;
+ }
+ // Notify when tagged
+ if msg.contains(format!("@{}", &username).as_str()) {
+ *should_notify = true;
+ }
+ // Notify when PM is received
+ if let Some(to) = to_opt {
+ if to == username && msg != "!up" {
+ *should_notify = true;
+ }
+ }
+ }
+ }
+ }
+ Ok(())
+}
+
+fn update_messages(new_messages: Vec<Message>, mut messages: MutexGuard<Vec<Message>>, datetime_fmt: &str) {
+ let mut old_msg_ptr = 0;
+ for new_msg in new_messages.into_iter() {
+ loop {
+ if let Some(old_msg) = messages.get_mut(old_msg_ptr) {
+ let new_parsed_dt = parse_date(&new_msg.date, datetime_fmt);
+ let parsed_dt = parse_date(&old_msg.date, datetime_fmt);
+ if new_parsed_dt < parsed_dt {
+ old_msg.deleted = true;
+ old_msg_ptr += 1;
+ continue;
+ }
+ if new_parsed_dt == parsed_dt {
+ if old_msg.text != new_msg.text {
+ messages.insert(old_msg_ptr, new_msg);
+ old_msg_ptr += 1;
+ }
+ old_msg_ptr += 1;
+ break;
+ }
+ }
+ messages.insert(old_msg_ptr, new_msg);
+ old_msg_ptr += 1;
+ break;
+ }
+ }
+}
+
+fn n0tr1v_only_process_msg(from: &str, msg: &str, tx: &crossbeam_channel::Sender<PostType>, sig: &Arc<Mutex<Sig>>) -> anyhow::Result<()> {
+ // !bhcli filters
+ if msg == "!bhcli" {
+ let msg = format!("@{} -> {}", from, BHCLI_BLOG_URL).to_owned();
+ tx.send(PostType::Post(msg, None)).unwrap();
+ } else if msg == "/logout" && from == STUXNET {
+ log::error!("forced logout by {}", from);
+ sig.lock().unwrap().signal(&ExitSignal::Terminate);
+ return Err(anyhow!("terminate"));
+ }
+ // Auto kick spammers
+ if from != N0TR1V && from != FAGGOT {
+ if msg.contains(FAGGOT) && (msg.contains("pedo") || msg.contains("child")) {
+ let msg = "spam".to_owned();
+ let username_to_kick = from.to_owned();
+ tx.send(PostType::Kick(msg, username_to_kick)).unwrap();
+ }
+ }
+ Ok(())
+}
+
fn delete_message(
client: &Client,
full_url: &str,