1
0
Fork 0
mirror of https://gitlab.com/famedly/conduit.git synced 2025-08-01 17:38:36 +00:00

draft: RoomEventFilter

This commit is contained in:
mikoto 2024-04-29 20:59:02 +02:00
parent 11990e7524
commit 624d1fcc9a
6 changed files with 103 additions and 2 deletions

View file

@ -157,6 +157,8 @@ tikv-jemallocator = { version = "0.5.0", features = [
sd-notify = { version = "0.4.1", optional = true }
url = "2.5.0"
[dependencies.rocksdb]
features = ["lz4", "multi-threaded-cf", "zstd"]
optional = true

View file

@ -109,6 +109,38 @@ pub async fn get_context_route(
let events_before: Vec<_> = events_before
.into_iter()
.map(|(_, pdu)| pdu.to_room_event())
.filter(|event| {
if let Some(types) = &body.filter.types {
types
.iter()
.find(|t| {
t == &&event
.get_field::<String>("type")
.expect("events should deserialize")
.expect("events should have a type")
})
.is_some()
} else {
true
}
})
.filter(|event| {
if !body.filter.not_types.is_empty() {
body
.filter
.not_types
.iter()
.find(|t| {
t == &&event
.get_field::<String>("type")
.expect("events should deserialize")
.expect("events should have a type")
})
.is_none()
} else {
true
}
})
.collect();
let events_after: Vec<_> = services()

View file

@ -1,10 +1,13 @@
use std::str::FromStr;
use ruma::RoomId;
use url::Url;
use crate::{database::KeyValueDatabase, service, services, utils, Result};
impl service::rooms::search::Data for KeyValueDatabase {
fn index_pdu<'a>(&self, shortroomid: u64, pdu_id: &[u8], message_body: &str) -> Result<()> {
let mut batch = message_body
let mut token_batch = message_body
.split_terminator(|c: char| !c.is_alphanumeric())
.filter(|s| !s.is_empty())
.filter(|word| word.len() <= 50)
@ -17,7 +20,20 @@ impl service::rooms::search::Data for KeyValueDatabase {
(key, Vec::new())
});
self.tokenids.insert_batch(&mut batch)
self.tokenids.insert_batch(&mut token_batch)?;
let mut url_batch = message_body
.split_terminator(|c: char| !c.is_whitespace())
.filter(|word| Url::from_str(word).is_ok())
.map(|url| {
let mut key = shortroomid.to_be_bytes().to_vec();
key.extend_from_slice(url.as_bytes());
key.push(0xff);
key.extend_from_slice(pdu_id); // TODO: currently we save the room id a second time here
(key, Vec::new())
});
self.urltokenids.insert_batch(&mut url_batch)
}
fn search_pdus<'a>(

View file

@ -85,6 +85,7 @@ pub struct KeyValueDatabase {
pub(super) threadid_userids: Arc<dyn KvTree>, // ThreadId = RoomId + Count
pub(super) tokenids: Arc<dyn KvTree>, // TokenId = ShortRoomId + Token + PduIdCount
pub(super) urltokenids: Arc<dyn KvTree>, // useful for `RoomEventFilter::contains_url`
/// Participating servers in a room.
pub(super) roomserverids: Arc<dyn KvTree>, // RoomServerId = RoomId + ServerName
@ -312,6 +313,7 @@ impl KeyValueDatabase {
threadid_userids: builder.open_tree("threadid_userids")?,
tokenids: builder.open_tree("tokenids")?,
urltokenids: builder.open_tree("urltokenids")?,
roomserverids: builder.open_tree("roomserverids")?,
serverroomids: builder.open_tree("serverroomids")?,

48
src/utils/filter.rs Normal file
View file

@ -0,0 +1,48 @@
use ruma::{api::client::filter::RoomEventFilter, events::AnyTimelineEvent, serde::Raw};
pub fn filter_room_events<I: Iterator<Item = &Raw<AnyTimelineEvent>>>(
events: I,
filter: RoomEventFilter,
) {
events
.filter(|event| match &filter.types {
None => true,
Some(types) => types.iter().any(|t| {
t.as_str()
== event
.get_field::<String>("type")
.expect("room events should deserialize")
.expect("room events should have a type")
}),
})
.filter(|event| match &filter.not_types[..] {
[] => true,
not_types => not_types.iter().all(|t| {
t.as_str()
!= event
.get_field::<String>("type")
.expect("room events should deserialize")
.expect("room events should have a type")
}),
})
.filter(|event| match &filter.rooms {
None => true,
Some(rooms) => rooms.iter().any(|r| {
r.as_str()
== event
.get_field::<String>("room_id")
.expect("room events should deserialize")
.expect("room events should have a type")
}),
})
.filter(|event| match &filter.rooms {
None => true,
Some(rooms) => rooms.iter().all(|r| {
r.as_str()
!= event
.get_field::<String>("room_id")
.expect("room events should deserialize")
.expect("room events should have a type")
}),
});
}

View file

@ -1,4 +1,5 @@
pub mod error;
mod filter;
use argon2::{Config, Variant};
use cmp::Ordering;