diff --git a/src/group_handler/mod.rs b/src/group_handler/mod.rs index ef09f2b..dd06e97 100644 --- a/src/group_handler/mod.rs +++ b/src/group_handler/mod.rs @@ -1,3 +1,4 @@ +use std::collections::VecDeque; use std::sync::Arc; use std::time::{Duration, Instant}; @@ -29,6 +30,20 @@ pub struct GroupHandle { pub client: FediClient, pub config: GroupConfig, pub cc: Arc, + pub internal: GroupInternal, +} + +#[derive(Debug)] +pub struct GroupInternal { + recently_seen_notif_statuses: VecDeque, +} + +impl Default for GroupInternal { + fn default() -> Self { + Self { + recently_seen_notif_statuses: VecDeque::new() + } + } } // TODO move other options to common_config! @@ -57,7 +72,6 @@ macro_rules! grp_info { }; } -#[allow(unused)] macro_rules! grp_trace { ($self:ident, $f:expr) => { ::log::trace!(concat!("(@{}) ", $f), $self.config.get_acct()); @@ -234,7 +248,13 @@ impl GroupHandle { async fn handle_notification(&mut self, n: Notification) -> Result<(), GroupError> { grp_debug!(self, "Handling notif #{}", n.id); + grp_trace!(self, "{:?}", n); + let ts = n.timestamp_millis(); + if ts < self.config.get_last_notif() { + grp_debug!(self, "Notif is too old, discard"); + return Ok(()); + } self.config.set_last_notif(ts); let group_acct = self.config.get_acct().to_string(); @@ -254,7 +274,16 @@ impl GroupHandle { match n.notification_type { NotificationType::Mention => { if let Some(status) = n.status { - self.handle_mention_status(status).await?; + if self.internal.recently_seen_notif_statuses.contains(&status.id) { + grp_debug!(self, "Already saw this notif, discard"); + } else { + self.internal.recently_seen_notif_statuses.push_front(status.id.clone()); + while self.internal.recently_seen_notif_statuses.len() > 64 { + let _ = self.internal.recently_seen_notif_statuses.pop_back(); + } + + self.handle_mention_status(status).await?; + } } } NotificationType::Follow => { @@ -273,6 +302,8 @@ impl GroupHandle { /// Handle a non-mention status for tags async fn handle_status(&mut self, s: Status) -> Result<(), GroupError> { grp_debug!(self, "Handling status #{}", s.id); + grp_trace!(self, "{:?}", s); + let ts = s.timestamp_millis(); self.config.set_last_status(ts); @@ -396,6 +427,7 @@ impl GroupHandle { } grp_debug!(self, "Inspecting notif {}", NotificationDisplay(&n)); + grp_trace!(self, "{:?}", n); notifs_to_handle.push(n); num += 1; if num > self.cc.max_catchup_notifs { @@ -449,6 +481,7 @@ impl GroupHandle { } grp_debug!(self, "Inspecting status {}", StatusDisplay(&s)); + grp_trace!(self, "{:?}", s); if newest_status.is_none() { newest_status = Some(ts); diff --git a/src/main.rs b/src/main.rs index 5c31dcc..fb0b457 100644 --- a/src/main.rs +++ b/src/main.rs @@ -83,6 +83,11 @@ async fn main() -> anyhow::Result<()> { .write_style(env_logger::WriteStyle::Always) .filter_module("rustls", LevelFilter::Warn) .filter_module("reqwest", LevelFilter::Warn) + .filter_module("tungstenite", LevelFilter::Warn) + .filter_module("tokio_tungstenite", LevelFilter::Warn) + .filter_module("tokio_util", LevelFilter::Warn) + .filter_module("want", LevelFilter::Warn) + .filter_module("mio", LevelFilter::Warn) .init(); let store = store::ConfigStore::load_from_fs(StoreOptions { diff --git a/src/store/mod.rs b/src/store/mod.rs index 4d05c1c..71c7ce6 100644 --- a/src/store/mod.rs +++ b/src/store/mod.rs @@ -5,7 +5,7 @@ use elefren::{scopes, FediClient, Registration, Scopes}; use futures::StreamExt; use crate::error::GroupError; -use crate::group_handler::GroupHandle; +use crate::group_handler::{GroupHandle, GroupInternal}; pub mod common_config; pub mod group_config; @@ -125,6 +125,7 @@ impl ConfigStore { client, config: data, cc: self.config.clone(), + internal: GroupInternal::default(), }) } @@ -169,6 +170,7 @@ impl ConfigStore { client, config, cc: self.config.clone(), + internal: GroupInternal::default(), }) } @@ -212,6 +214,7 @@ impl ConfigStore { client, config: gc, cc: self.config.clone(), + internal: GroupInternal::default(), }) } Err(e) => {