mirror of
https://gitlab.com/famedly/conduit.git
synced 2025-08-01 17:38:36 +00:00
draft: RoomEventFilter
This commit is contained in:
parent
11990e7524
commit
624d1fcc9a
6 changed files with 103 additions and 2 deletions
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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>(
|
||||
|
|
|
@ -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
48
src/utils/filter.rs
Normal 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")
|
||||
}),
|
||||
});
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
pub mod error;
|
||||
mod filter;
|
||||
|
||||
use argon2::{Config, Variant};
|
||||
use cmp::Ordering;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue