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 }
|
sd-notify = { version = "0.4.1", optional = true }
|
||||||
|
|
||||||
|
url = "2.5.0"
|
||||||
|
|
||||||
[dependencies.rocksdb]
|
[dependencies.rocksdb]
|
||||||
features = ["lz4", "multi-threaded-cf", "zstd"]
|
features = ["lz4", "multi-threaded-cf", "zstd"]
|
||||||
optional = true
|
optional = true
|
||||||
|
|
|
@ -109,6 +109,38 @@ pub async fn get_context_route(
|
||||||
let events_before: Vec<_> = events_before
|
let events_before: Vec<_> = events_before
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_, pdu)| pdu.to_room_event())
|
.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();
|
.collect();
|
||||||
|
|
||||||
let events_after: Vec<_> = services()
|
let events_after: Vec<_> = services()
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use ruma::RoomId;
|
use ruma::RoomId;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use crate::{database::KeyValueDatabase, service, services, utils, Result};
|
use crate::{database::KeyValueDatabase, service, services, utils, Result};
|
||||||
|
|
||||||
impl service::rooms::search::Data for KeyValueDatabase {
|
impl service::rooms::search::Data for KeyValueDatabase {
|
||||||
fn index_pdu<'a>(&self, shortroomid: u64, pdu_id: &[u8], message_body: &str) -> Result<()> {
|
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())
|
.split_terminator(|c: char| !c.is_alphanumeric())
|
||||||
.filter(|s| !s.is_empty())
|
.filter(|s| !s.is_empty())
|
||||||
.filter(|word| word.len() <= 50)
|
.filter(|word| word.len() <= 50)
|
||||||
|
@ -17,7 +20,20 @@ impl service::rooms::search::Data for KeyValueDatabase {
|
||||||
(key, Vec::new())
|
(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>(
|
fn search_pdus<'a>(
|
||||||
|
|
|
@ -85,6 +85,7 @@ pub struct KeyValueDatabase {
|
||||||
pub(super) threadid_userids: Arc<dyn KvTree>, // ThreadId = RoomId + Count
|
pub(super) threadid_userids: Arc<dyn KvTree>, // ThreadId = RoomId + Count
|
||||||
|
|
||||||
pub(super) tokenids: Arc<dyn KvTree>, // TokenId = ShortRoomId + Token + PduIdCount
|
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.
|
/// Participating servers in a room.
|
||||||
pub(super) roomserverids: Arc<dyn KvTree>, // RoomServerId = RoomId + ServerName
|
pub(super) roomserverids: Arc<dyn KvTree>, // RoomServerId = RoomId + ServerName
|
||||||
|
@ -312,6 +313,7 @@ impl KeyValueDatabase {
|
||||||
threadid_userids: builder.open_tree("threadid_userids")?,
|
threadid_userids: builder.open_tree("threadid_userids")?,
|
||||||
|
|
||||||
tokenids: builder.open_tree("tokenids")?,
|
tokenids: builder.open_tree("tokenids")?,
|
||||||
|
urltokenids: builder.open_tree("urltokenids")?,
|
||||||
|
|
||||||
roomserverids: builder.open_tree("roomserverids")?,
|
roomserverids: builder.open_tree("roomserverids")?,
|
||||||
serverroomids: builder.open_tree("serverroomids")?,
|
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;
|
pub mod error;
|
||||||
|
mod filter;
|
||||||
|
|
||||||
use argon2::{Config, Variant};
|
use argon2::{Config, Variant};
|
||||||
use cmp::Ordering;
|
use cmp::Ordering;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue