bhcli

"Strange's fork of n0tr1v's bhcli (onion)"
git clone https://git.dasho.dev/Strange/bhcli.git
Log | Files | Refs | README

commit c2082599d4c94928a4b5a44ca305edb703918073
parent 937fd90206883ea5e1e9a696e677962dfa549e35
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Fri,  7 Apr 2023 15:43:06 -0700

test

Diffstat:
Msrc/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,