[fractal] API: Add get_message_events endpoint
- From: Daniel Garcia Moreno <danigm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal] API: Add get_message_events endpoint
- Date: Thu, 2 Apr 2020 10:38:35 +0000 (UTC)
commit 378e04cc30645d478a90700c4309b6e3f22d8678
Author: Alejandro DomÃnguez <adomu net-c com>
Date: Mon Feb 10 05:49:57 2020 +0100
API: Add get_message_events endpoint
fractal-matrix-api/src/backend/media.rs | 102 ++++++++++-----------
fractal-matrix-api/src/r0.rs | 5 +
fractal-matrix-api/src/r0/filter.rs | 20 +++-
fractal-matrix-api/src/r0/message.rs | 1 +
.../src/r0/message/get_message_events.rs | 51 +++++++++++
fractal-matrix-api/src/r0/search/user.rs | 5 +-
6 files changed, 128 insertions(+), 56 deletions(-)
---
diff --git a/fractal-matrix-api/src/backend/media.rs b/fractal-matrix-api/src/backend/media.rs
index 835aa531..68ce863e 100644
--- a/fractal-matrix-api/src/backend/media.rs
+++ b/fractal-matrix-api/src/backend/media.rs
@@ -2,7 +2,6 @@ use crate::backend::types::Backend;
use crate::error::Error;
use crate::globals;
use ruma_identifiers::RoomId;
-use serde_json::json;
use std::str::Split;
use std::sync::mpsc::Sender;
use std::thread;
@@ -10,16 +9,19 @@ use url::Url;
use crate::r0::AccessToken;
use crate::util::cache_dir_path;
-use crate::util::client_url;
use crate::util::download_file;
use crate::util::dw_media;
use crate::util::get_prev_batch_from;
-use crate::util::json_q;
use crate::util::semaphore;
use crate::util::ContentType;
use crate::util::ResultExpectLog;
+use crate::util::HTTP_CLIENT;
use crate::r0::filter::RoomEventFilter;
+use crate::r0::message::get_message_events::request as get_messages_events_req;
+use crate::r0::message::get_message_events::Direction as GetMessagesEventsDirection;
+use crate::r0::message::get_message_events::Parameters as GetMessagesEventsParams;
+use crate::r0::message::get_message_events::Response as GetMessagesEventsResponse;
use crate::types::Message;
pub fn get_thumb_async(bk: &Backend, baseu: Url, media: String, tx: Sender<Result<String, Error>>) {
@@ -46,15 +48,25 @@ pub fn get_media_list_async(
tx: Sender<(Vec<Message>, String)>,
) {
semaphore(bk.limit_threads.clone(), move || {
- let media_list = get_room_media_list(
- &baseu,
- &access_token,
- &room_id,
- globals::PAGE_LIMIT,
- first_media_id,
- &prev_batch,
- )
- .unwrap_or_default();
+ let media_list = prev_batch
+ // FIXME: This should never be an empty token
+ .or_else(|| {
+ if let Some(ref id) = first_media_id {
+ get_prev_batch_from(&baseu, &access_token, &room_id, id).ok()
+ } else {
+ None
+ }
+ })
+ .and_then(|from| {
+ get_room_media_list(
+ baseu,
+ access_token,
+ &room_id,
+ globals::PAGE_LIMIT as u64,
+ from,
+ ).ok()
+ })
+ .unwrap_or_default();
tx.send(media_list).expect_log("Connection closed");
});
}
@@ -75,49 +87,37 @@ pub fn get_file_async(url: Url, tx: Sender<String>) -> Result<(), Error> {
}
fn get_room_media_list(
- baseu: &Url,
- tk: &AccessToken,
+ baseu: Url,
+ access_token: AccessToken,
room_id: &RoomId,
- limit: i32,
- first_media_id: Option<String>,
- prev_batch: &Option<String>,
+ limit: u64,
+ prev_batch: String,
) -> Result<(Vec<Message>, String), Error> {
- let mut params = vec![
- ("dir", String::from("b")),
- ("limit", format!("{}", limit)),
- ("access_token", tk.to_string()),
- (
- "filter",
- serde_json::to_string(&RoomEventFilter {
- contains_url: true,
- not_types: vec!["m.sticker"],
- ..Default::default()
- })
- .expect("Failed to serialize room media list request filter"),
- ),
- ];
-
- match prev_batch {
- Some(ref pb) => params.push(("from", pb.clone())),
- None => {
- if let Some(id) = first_media_id {
- params.push(("from", get_prev_batch_from(baseu, tk, room_id, &id)?))
- }
- }
+ let params = GetMessagesEventsParams {
+ access_token,
+ from: prev_batch,
+ to: None,
+ dir: GetMessagesEventsDirection::Backward,
+ limit,
+ filter: RoomEventFilter {
+ contains_url: true,
+ not_types: vec!["m.sticker"],
+ ..Default::default()
+ },
};
- let path = format!("rooms/{}/messages", room_id);
- let url = client_url(baseu, &path, ¶ms)?;
-
- let r = json_q("get", url, &json!(null))?;
- let array = r["chunk"].as_array();
- let prev_batch = r["end"].to_string().trim_matches('"').to_string();
- if array.is_none() || array.unwrap().is_empty() {
- return Ok((vec![], prev_batch));
- }
+ get_messages_events_req(baseu, ¶ms, room_id)
+ .map_err(Into::into)
+ .and_then(|request| {
+ let response = HTTP_CLIENT
+ .get_client()?
+ .execute(request)?
+ .json::<GetMessagesEventsResponse>()?;
- let evs = array.unwrap().iter().rev();
- let media_list = Message::from_json_events_iter(room_id, evs)?;
+ let prev_batch = response.end.unwrap_or_default();
+ let evs = response.chunk.iter().rev();
+ let media_list = Message::from_json_events_iter(room_id, evs)?;
- Ok((media_list, prev_batch))
+ Ok((media_list, prev_batch))
+ })
}
diff --git a/fractal-matrix-api/src/r0.rs b/fractal-matrix-api/src/r0.rs
index 9b7e03e8..b4c7e058 100644
--- a/fractal-matrix-api/src/r0.rs
+++ b/fractal-matrix-api/src/r0.rs
@@ -4,6 +4,7 @@ pub mod directory;
pub mod filter;
pub mod media;
pub mod membership;
+pub mod message;
pub mod profile;
pub mod search;
pub mod server;
@@ -94,3 +95,7 @@ impl From<String> for AccessToken {
Self(token)
}
}
+
+pub(crate) fn u64_is_10(number: &u64) -> bool {
+ number == &10
+}
diff --git a/fractal-matrix-api/src/r0/filter.rs b/fractal-matrix-api/src/r0/filter.rs
index f2364ff1..3571fb6a 100644
--- a/fractal-matrix-api/src/r0/filter.rs
+++ b/fractal-matrix-api/src/r0/filter.rs
@@ -88,7 +88,25 @@ pub struct RoomEventFilter<'a> {
pub contains_url: bool,
}
-pub fn serialize_filter_as_str<S>(filter: &Filter, ser: S) -> Result<S::Ok, S::Error>
+impl<'a> RoomEventFilter<'a> {
+ pub fn is_default(&self) -> bool {
+ *self == Default::default()
+ }
+}
+
+pub(crate) fn serialize_filter_as_str<S>(filter: &Filter, ser: S) -> Result<S::Ok, S::Error>
+where
+ S: Serializer,
+{
+ let filter_str = serde_json::to_string(filter).expect("Malformed filter");
+
+ ser.serialize_str(&filter_str)
+}
+
+pub(crate) fn serialize_room_event_filter_as_str<S>(
+ filter: &RoomEventFilter,
+ ser: S,
+) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
diff --git a/fractal-matrix-api/src/r0/message.rs b/fractal-matrix-api/src/r0/message.rs
new file mode 100644
index 00000000..7a4e2571
--- /dev/null
+++ b/fractal-matrix-api/src/r0/message.rs
@@ -0,0 +1 @@
+pub mod get_message_events;
diff --git a/fractal-matrix-api/src/r0/message/get_message_events.rs
b/fractal-matrix-api/src/r0/message/get_message_events.rs
new file mode 100644
index 00000000..7eb194da
--- /dev/null
+++ b/fractal-matrix-api/src/r0/message/get_message_events.rs
@@ -0,0 +1,51 @@
+use crate::r0::filter::serialize_room_event_filter_as_str;
+use crate::r0::filter::RoomEventFilter;
+use crate::r0::u64_is_10;
+use crate::r0::AccessToken;
+use reqwest::blocking::Client;
+use reqwest::blocking::Request;
+use reqwest::Error;
+use ruma_identifiers::RoomId;
+use serde::{Deserialize, Serialize};
+use serde_json::Value as JsonValue;
+use url::Url;
+
+#[derive(Clone, Debug, Serialize)]
+pub struct Parameters<'a> {
+ pub access_token: AccessToken,
+ pub from: String,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub to: Option<String>,
+ pub dir: Direction,
+ #[serde(skip_serializing_if = "u64_is_10")]
+ pub limit: u64,
+ #[serde(serialize_with = "serialize_room_event_filter_as_str")]
+ #[serde(skip_serializing_if = "RoomEventFilter::is_default")]
+ pub filter: RoomEventFilter<'a>,
+}
+
+#[derive(Clone, Debug, Serialize)]
+pub enum Direction {
+ #[serde(rename = "b")]
+ Backward,
+ #[serde(rename = "f")]
+ Forward,
+}
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct Response {
+ pub start: Option<String>,
+ pub end: Option<String>,
+ #[serde(default)]
+ pub chunk: Vec<JsonValue>,
+ #[serde(default)]
+ pub state: Vec<JsonValue>,
+}
+
+pub fn request(base: Url, params: &Parameters, room_id: &RoomId) -> Result<Request, Error> {
+ let url = base
+ .join(&format!("/_matrix/client/r0/rooms/{}/messages", room_id))
+ .expect("Malformed URL in user_directory");
+
+ Client::new().get(url).query(params).build()
+}
diff --git a/fractal-matrix-api/src/r0/search/user.rs b/fractal-matrix-api/src/r0/search/user.rs
index 08be068a..55e97afa 100644
--- a/fractal-matrix-api/src/r0/search/user.rs
+++ b/fractal-matrix-api/src/r0/search/user.rs
@@ -1,3 +1,4 @@
+use crate::r0::u64_is_10;
use crate::r0::AccessToken;
use crate::serde::option_url;
use reqwest::blocking::Client;
@@ -43,10 +44,6 @@ pub struct User {
pub avatar_url: Option<Url>,
}
-fn u64_is_10(number: &u64) -> bool {
- number == &10
-}
-
pub fn request(base: Url, params: &Parameters, body: &Body) -> Result<Request, Error> {
let url = base
.join("/_matrix/client/r0/user_directory/search")
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]