[fractal] API, room: use endpoints in get_room_detail, get_room_avatar, get_room_members and get_room_messages



commit fd93031351e63a083c6a0c18ce1c3a69256e341e
Author: Alejandro Domínguez <adomu net-c com>
Date:   Mon Mar 2 22:34:01 2020 +0100

    API, room: use endpoints in get_room_detail, get_room_avatar, get_room_members and get_room_messages

 fractal-matrix-api/src/backend/mod.rs              |  17 +-
 fractal-matrix-api/src/backend/room.rs             | 219 +++++++++------------
 fractal-matrix-api/src/r0.rs                       |   1 +
 fractal-matrix-api/src/r0/state.rs                 |   1 +
 .../src/r0/state/get_state_events_for_key.rs       |  29 +++
 5 files changed, 136 insertions(+), 131 deletions(-)
---
diff --git a/fractal-matrix-api/src/backend/mod.rs b/fractal-matrix-api/src/backend/mod.rs
index 0fc92df3..d83622cb 100644
--- a/fractal-matrix-api/src/backend/mod.rs
+++ b/fractal-matrix-api/src/backend/mod.rs
@@ -229,8 +229,11 @@ impl Backend {
                 });
             }
             Ok(BKCommand::GetRoomMessages(server, access_token, room_id, from)) => {
-                let r = room::get_room_messages(self, server, access_token, room_id, from);
-                bkerror2!(r, tx, BKResponse::RoomMessagesTo);
+                thread::spawn(move || {
+                    let query = room::get_room_messages(server, access_token, room_id, from);
+                    tx.send(BKResponse::RoomMessagesTo(query))
+                        .expect_log("Connection closed");
+                });
             }
             Ok(BKCommand::GetRoomMessagesFromMsg(server, access_token, room_id, from)) => {
                 room::get_room_messages_from_msg(self, server, access_token, room_id, from)
@@ -257,12 +260,14 @@ impl Backend {
                 });
             }
             Ok(BKCommand::SetRoom(server, access_token, room_id)) => {
-                let r = room::set_room(self, server, access_token, room_id);
-                bkerror!(r, tx, BKResponse::SetRoomError);
+                room::set_room(self, server, access_token, room_id)
             }
             Ok(BKCommand::GetRoomAvatar(server, access_token, room_id)) => {
-                let r = room::get_room_avatar(self, server, access_token, room_id);
-                bkerror2!(r, tx, BKResponse::RoomAvatar);
+                thread::spawn(move || {
+                    let query = room::get_room_avatar(server, access_token, room_id);
+                    tx.send(BKResponse::RoomAvatar(query))
+                        .expect_log("Connection closed");
+                });
             }
             Ok(BKCommand::JoinRoom(server, access_token, room_id)) => {
                 room::join_room(self, server, access_token, room_id)
diff --git a/fractal-matrix-api/src/backend/room.rs b/fractal-matrix-api/src/backend/room.rs
index 0c9004b0..b7de16f6 100644
--- a/fractal-matrix-api/src/backend/room.rs
+++ b/fractal-matrix-api/src/backend/room.rs
@@ -41,6 +41,12 @@ use crate::r0::membership::join_room_by_id_or_alias::request as join_room_req;
 use crate::r0::membership::join_room_by_id_or_alias::Parameters as JoinRoomParameters;
 use crate::r0::membership::leave_room::request as leave_room_req;
 use crate::r0::membership::leave_room::Parameters as LeaveRoomParameters;
+use crate::r0::message::get_message_events::request as get_messages_events;
+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::r0::state::get_state_events_for_key::request as get_state_events_for_key;
+use crate::r0::state::get_state_events_for_key::Parameters as GetStateEventsForKeyParameters;
 use crate::r0::sync::get_joined_members::request as get_joined_members;
 use crate::r0::sync::get_joined_members::Parameters as JoinedMembersParameters;
 use crate::r0::sync::get_joined_members::Response as JoinedMembersResponse;
@@ -63,102 +69,84 @@ use serde_json::Value as JsonValue;
 
 // FIXME: Remove this function, this is used only to request information we should already have
 // when opening a room
-pub fn set_room(
-    bk: &Backend,
-    base: Url,
-    access_token: AccessToken,
-    room_id: RoomId,
-) -> Result<(), Error> {
-    /* FIXME: remove clone and pass id by reference */
-    get_room_avatar(bk, base.clone(), access_token.clone(), room_id.clone())?;
-    get_room_detail(
-        bk,
-        base,
-        access_token,
-        room_id,
-        String::from("m.room.topic"),
-    )?;
-
-    Ok(())
+pub fn set_room(bk: &Backend, base: Url, access_token: AccessToken, room_id: RoomId) {
+    if let Some(itx) = bk.internal_tx.clone() {
+        itx.send(BKCommand::GetRoomAvatar(
+            base.clone(),
+            access_token.clone(),
+            room_id.clone(),
+        ))
+        .expect_log("Connection closed");
+
+        let tx = bk.tx.clone();
+
+        thread::spawn(move || {
+            let query = get_room_detail(base, access_token, room_id, "m.room.topic".into());
+            tx.send(BKResponse::RoomDetail(query))
+                .expect_log("Connection closed");
+        });
+    }
 }
 
-pub fn get_room_detail(
-    bk: &Backend,
+fn get_room_detail(
     base: Url,
     access_token: AccessToken,
     room_id: RoomId,
     keys: String,
-) -> Result<(), Error> {
-    let url = bk.url(
-        base,
-        &access_token,
-        &format!("rooms/{}/state/{}", room_id, keys),
-        vec![],
-    )?;
+) -> Result<(RoomId, String, String), Error> {
+    let params = GetStateEventsForKeyParameters { access_token };
 
-    let tx = bk.tx.clone();
-    get!(
-        url,
-        |r: JsonValue| {
-            let k = keys.split('.').last().unwrap();
+    get_state_events_for_key(base, &params, &room_id, &keys)
+        .map_err(Into::into)
+        .and_then(|request| {
+            let response = HTTP_CLIENT
+                .get_client()?
+                .execute(request)?
+                .json::<JsonValue>()?;
 
-            let value = r[&k].as_str().map(Into::into).unwrap_or_default();
-            tx.send(BKResponse::RoomDetail(Ok((room_id, keys, value))))
-                .expect_log("Connection closed");
-        },
-        |err| {
-            tx.send(BKResponse::RoomDetail(Err(err)))
-                .expect_log("Connection closed");
-        }
-    );
+            let k = keys.split('.').last().unwrap();
+            let value = response[&k].as_str().map(Into::into).unwrap_or_default();
 
-    Ok(())
+            Ok((room_id, keys, value))
+        })
 }
 
 pub fn get_room_avatar(
-    bk: &Backend,
-    baseu: Url,
+    base: Url,
     access_token: AccessToken,
     room_id: RoomId,
-) -> Result<(), Error> {
-    let url = bk.url(
-        baseu.clone(),
-        &access_token,
-        &format!("rooms/{}/state/m.room.avatar", room_id),
-        vec![],
-    )?;
-    let tx = bk.tx.clone();
-    get!(
-        url,
-        |r: JsonValue| {
-            let avatar = r["url"].as_str().and_then(|s| Url::parse(s).ok());
+) -> Result<(RoomId, Option<Url>), Error> {
+    let params = GetStateEventsForKeyParameters { access_token };
+
+    get_state_events_for_key(base.clone(), &params, &room_id, "m.room.avatar")
+        .map_err(Into::into)
+        .and_then(|request| {
+            let response = HTTP_CLIENT
+                .get_client()?
+                .execute(request)?
+                .json::<JsonValue>()?;
+
+            let avatar = response["url"].as_str().and_then(|s| Url::parse(s).ok());
             let dest = cache_dir_path(None, &room_id.to_string()).ok();
             if let Some(ref avatar) = avatar {
                 let _ = dw_media(
-                    &baseu,
+                    &base,
                     avatar.as_str(),
                     ContentType::default_thumbnail(),
                     dest.as_ref().map(String::as_str),
                 );
             }
-            tx.send(BKResponse::RoomAvatar(Ok((room_id, avatar))))
-                .expect_log("Connection closed");
-        },
-        |err: Error| match err {
+
+            Ok((room_id.clone(), avatar))
+        })
+        .or_else(|err| match err {
             Error::MatrixError(ref js)
                 if js["errcode"].as_str().unwrap_or_default() == "M_NOT_FOUND" =>
             {
-                tx.send(BKResponse::RoomAvatar(Ok((room_id, None))))
-                    .expect_log("Connection closed");
-            }
-            _ => {
-                tx.send(BKResponse::RoomAvatar(Err(err)))
-                    .expect_log("Connection closed");
+                Ok((room_id, None))
             }
-        }
-    );
-
-    Ok(())
+            error => Err(error),
+        })
 }
 
 pub fn get_room_members(
@@ -171,16 +159,14 @@ pub fn get_room_members(
     get_joined_members(base, &room_id, &params)
         .map_err(Into::into)
         .and_then(|request| {
-            HTTP_CLIENT
+            let response = HTTP_CLIENT
                 .get_client()?
                 .execute(request)?
-                .json::<JoinedMembersResponse>()
-                .map_err(Into::into)
-        })
-        .map(|response| {
+                .json::<JoinedMembersResponse>()?;
+
             let ms = response.joined.into_iter().map(Member::from).collect();
 
-            (room_id, ms)
+            Ok((room_id, ms))
         })
 }
 
@@ -188,52 +174,37 @@ pub fn get_room_members(
  * https://matrix.org/docs/spec/client_server/latest.html#get-matrix-client-r0-rooms-roomid-messages
  */
 pub fn get_room_messages(
-    bk: &Backend,
     base: Url,
     access_token: AccessToken,
     room_id: RoomId,
     from: String,
-) -> Result<(), Error> {
-    let params = vec![
-        ("from", from),
-        ("dir", String::from("b")),
-        ("limit", format!("{}", globals::PAGE_LIMIT)),
-        (
-            "filter",
-            serde_json::to_string(&RoomEventFilter {
-                types: Some(vec!["m.room.message", "m.sticker"]),
-                ..Default::default()
-            })
-            .expect("Failed to serialize room messages request filter"),
-        ),
-    ];
-    let url = bk.url(
-        base,
-        &access_token,
-        &format!("rooms/{}/messages", room_id),
-        params,
-    )?;
-    let tx = bk.tx.clone();
-    get!(
-        url,
-        |r: JsonValue| {
-            let array = r["chunk"].as_array();
-            let evs = array.unwrap().iter().rev();
-            let prev_batch = r["end"].as_str().map(String::from);
-            let query = Message::from_json_events_iter(&room_id, evs)
-                .map(|list| (list, room_id, prev_batch))
-                .map_err(Into::into);
-
-            tx.send(BKResponse::RoomMessagesTo(query))
-                .expect_log("Connection closed");
+) -> Result<(Vec<Message>, RoomId, Option<String>), Error> {
+    let params = GetMessagesEventsParams {
+        access_token,
+        from,
+        to: None,
+        dir: GetMessagesEventsDirection::Backward,
+        limit: globals::PAGE_LIMIT as u64,
+        filter: RoomEventFilter {
+            types: Some(vec!["m.room.message", "m.sticker"]),
+            ..Default::default()
         },
-        |err| {
-            tx.send(BKResponse::RoomMessagesTo(Err(err)))
-                .expect_log("Connection closed");
-        }
-    );
+    };
 
-    Ok(())
+    get_messages_events(base, &params, &room_id)
+        .map_err(Into::into)
+        .and_then(|request| {
+            let response = HTTP_CLIENT
+                .get_client()?
+                .execute(request)?
+                .json::<GetMessagesEventsResponse>()?;
+
+            let prev_batch = response.end;
+            let evs = response.chunk.iter().rev();
+            Message::from_json_events_iter(&room_id, evs)
+                .map(|list| (list, room_id, prev_batch))
+                .map_err(Into::into)
+        })
 }
 
 pub fn get_room_messages_from_msg(
@@ -276,10 +247,10 @@ fn parse_context(
 
     get!(
         url,
-        |r: JsonValue| {
+        |response: JsonValue| {
             let mut id: Option<String> = None;
 
-            let ms: Result<Vec<Message>, _> = r["events_before"]
+            let ms: Result<Vec<Message>, _> = response["events_before"]
                 .as_array()
                 .into_iter()
                 .flatten()
@@ -293,21 +264,19 @@ fn parse_context(
                 .map(|msg| Message::parse_room_message(&room_id, msg))
                 .collect();
 
-            match ms {
-                Ok(msgs) if msgs.is_empty() && id.is_some() => {
+            match (ms, id) {
+                (Ok(msgs), Some(ref id)) if msgs.is_empty() => {
                     // there's no messages so we'll try with a bigger context
-                    if let Err(err) =
-                        parse_context(tx.clone(), tk, baseu, room_id, &id.unwrap(), limit * 2)
-                    {
+                    if let Err(err) = parse_context(tx.clone(), tk, baseu, room_id, id, limit * 2) {
                         tx.send(BKResponse::RoomMessagesTo(Err(err)))
                             .expect_log("Connection closed");
                     }
                 }
-                Ok(msgs) => {
+                (Ok(msgs), _) => {
                     tx.send(BKResponse::RoomMessagesTo(Ok((msgs, room_id, None))))
                         .expect_log("Connection closed");
                 }
-                Err(err) => {
+                (Err(err), _) => {
                     tx.send(BKResponse::RoomMessagesTo(Err(err.into())))
                         .expect_log("Connection closed");
                 }
diff --git a/fractal-matrix-api/src/r0.rs b/fractal-matrix-api/src/r0.rs
index b4c7e058..5988b554 100644
--- a/fractal-matrix-api/src/r0.rs
+++ b/fractal-matrix-api/src/r0.rs
@@ -8,6 +8,7 @@ pub mod message;
 pub mod profile;
 pub mod search;
 pub mod server;
+pub mod state;
 pub mod sync;
 pub mod tag;
 pub mod thirdparty;
diff --git a/fractal-matrix-api/src/r0/state.rs b/fractal-matrix-api/src/r0/state.rs
new file mode 100644
index 00000000..f46cf908
--- /dev/null
+++ b/fractal-matrix-api/src/r0/state.rs
@@ -0,0 +1 @@
+pub mod get_state_events_for_key;
diff --git a/fractal-matrix-api/src/r0/state/get_state_events_for_key.rs 
b/fractal-matrix-api/src/r0/state/get_state_events_for_key.rs
new file mode 100644
index 00000000..37154d73
--- /dev/null
+++ b/fractal-matrix-api/src/r0/state/get_state_events_for_key.rs
@@ -0,0 +1,29 @@
+use crate::r0::AccessToken;
+use reqwest::blocking::Client;
+use reqwest::blocking::Request;
+use reqwest::Error;
+use ruma_identifiers::RoomId;
+use serde::Serialize;
+use url::Url;
+
+#[derive(Clone, Debug, Serialize)]
+pub struct Parameters {
+    pub access_token: AccessToken,
+}
+
+pub fn request(
+    base: Url,
+    params: &Parameters,
+    room_id: &RoomId,
+    // event_type: &EventType,  TODO: Use this parameter
+    state_keys: &str,
+) -> Result<Request, Error> {
+    let url = base
+        .join(&format!(
+            "/_matrix/client/r0/rooms/{}/state/{}/",
+            room_id, state_keys,
+        ))
+        .expect("Malformed URL in get_state_events_for_key");
+
+    Client::new().get(url).query(params).build()
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]