use nostr::Timestamp;
use std::collections::HashSet;
use std::sync::Arc;
use super::mute::MuteManager;
use super::prelude::*;
use nostr_sdk::prelude::*;
#[derive(Debug)]
pub struct NostraEventPolicy {
muted_pubkeys_cache: Cache<u64, Arc<HashSet<PublicKey>>>,
store: Arc<RdfEventsStore>,
}
impl NostraEventPolicy {
pub fn from_store(events_store: &Arc<RdfEventsStore>) -> Self {
Self {
muted_pubkeys_cache: Cache::new(4),
store: events_store.clone(),
}
}
pub fn get_cache_muted(
&self,
) -> Result<Arc<HashSet<PublicKey>>, RdfStoreError> {
let keys = Arc::new(self.store.all_muted_pubkeys()?);
self.muted_pubkeys_cache
.insert(Timestamp::now().as_u64(), keys.clone());
Ok(keys)
}
pub fn muted_set(&self) -> Result<Arc<HashSet<PublicKey>>, RdfStoreError> {
let ts_filter = Timestamp::now().as_u64() - 5;
match self
.muted_pubkeys_cache
.iter()
.filter(|(ts, _k)| *ts > ts_filter.into())
.next()
{
Some((_ts, keys)) => Ok(keys),
None => self.get_cache_muted(),
}
}
}
impl AdmitPolicy for NostraEventPolicy {
fn admit_connection<'a>(
&'a self,
_relay_url: &'a RelayUrl,
) -> BoxedFuture<'a, Result<AdmitStatus, PolicyError>> {
Box::pin(async move { Ok(AdmitStatus::success()) })
}
fn admit_event<'a>(
&'a self,
_relay_url: &'a RelayUrl,
_subscription_id: &'a SubscriptionId,
event: &'a Event,
) -> BoxedFuture<'a, Result<AdmitStatus, PolicyError>> {
Box::pin(async move {
let muted_pubkeys = self.muted_set().map_err(|_| {
PolicyError::Backend(Box::from("Cannot load muted pubkeys"))
})?;
if muted_pubkeys.contains(&event.pubkey) {
return Ok(AdmitStatus::rejected("Muted"));
}
Ok(AdmitStatus::success())
})
}
}