conduit/src/client_server/search.rs

90 lines
2.7 KiB
Rust
Raw Normal View History

2020-08-18 10:15:27 +00:00
use super::State;
use crate::{ConduitResult, Database, Error, Ruma};
use ruma::api::client::{error::ErrorKind, r0::search::search_events};
#[cfg(feature = "conduit_bin")]
use rocket::post;
2020-09-08 15:32:03 +00:00
use search_events::{EventContextResult, ResultCategories, ResultRoomEvents, SearchResult};
2020-08-18 10:15:27 +00:00
use std::collections::BTreeMap;
#[cfg_attr(
feature = "conduit_bin",
post("/_matrix/client/r0/search", data = "<body>")
)]
pub async fn search_events_route(
2020-08-18 10:15:27 +00:00
db: State<'_, Database>,
2020-09-08 15:32:03 +00:00
body: Ruma<search_events::Request<'_>>,
2020-08-18 10:15:27 +00:00
) -> ConduitResult<search_events::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
2020-08-18 10:15:27 +00:00
let search_criteria = body.search_categories.room_events.as_ref().unwrap();
let filter = search_criteria.filter.as_ref().unwrap();
let room_id = filter.rooms.as_ref().unwrap().first().unwrap();
2020-08-18 10:15:27 +00:00
let limit = filter.limit.map_or(10, |l| u64::from(l) as usize);
if !db.rooms.is_joined(sender_user, &room_id)? {
2020-08-18 10:15:27 +00:00
return Err(Error::BadRequest(
ErrorKind::Forbidden,
"You don't have permission to view this room.",
));
}
let skip = match body.next_batch.as_ref().map(|s| s.parse()) {
Some(Ok(s)) => s,
Some(Err(_)) => {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Invalid next_batch token.",
))
}
None => 0, // Default to the start
};
let search = db
.rooms
.search_pdus(&room_id, &search_criteria.search_term)?;
let results = search
.0
.map(|result| {
Ok::<_, Error>(SearchResult {
2020-09-08 15:32:03 +00:00
context: EventContextResult {
end: None,
events_after: Vec::new(),
events_before: Vec::new(),
profile_info: BTreeMap::new(),
start: None,
},
2020-08-18 10:15:27 +00:00
rank: None,
result: db
2020-08-18 10:15:27 +00:00
.rooms
.get_pdu_from_id(&result)?
2020-09-08 15:32:03 +00:00
.map(|pdu| pdu.to_room_event()),
2020-08-18 10:15:27 +00:00
})
})
.filter_map(|r| r.ok())
.skip(skip)
.take(limit)
.collect::<Vec<_>>();
let next_batch = if results.len() < limit as usize {
None
} else {
Some((skip + limit).to_string())
};
Ok(search_events::Response::new(ResultCategories {
2020-09-08 15:32:03 +00:00
room_events: ResultRoomEvents {
2020-09-12 19:30:07 +00:00
count: None, // TODO? maybe not
groups: BTreeMap::new(), // TODO
next_batch,
results,
state: BTreeMap::new(), // TODO
highlights: search.1,
2020-09-08 15:32:03 +00:00
},
})
2020-08-18 10:15:27 +00:00
.into())
}