[fractal] Backend: Implement and use filter API



commit dcf51f2ef74d710a2ec4399650dca401c719cfd3
Author: Alejandro Domínguez <adomu net-c com>
Date:   Tue Jan 22 20:12:04 2019 +0100

    Backend: Implement and use filter API

 fractal-matrix-api/src/backend/room.rs |  7 ++-
 fractal-matrix-api/src/backend/sync.rs | 56 ++++++++++++++++-------
 fractal-matrix-api/src/model/filter.rs | 81 ++++++++++++++++++++++++++++++++++
 fractal-matrix-api/src/model/mod.rs    |  1 +
 fractal-matrix-api/src/types.rs        |  4 ++
 fractal-matrix-api/src/util.rs         |  9 +++-
 6 files changed, 138 insertions(+), 20 deletions(-)
---
diff --git a/fractal-matrix-api/src/backend/room.rs b/fractal-matrix-api/src/backend/room.rs
index 27b737cf..274b1289 100644
--- a/fractal-matrix-api/src/backend/room.rs
+++ b/fractal-matrix-api/src/backend/room.rs
@@ -24,6 +24,7 @@ use crate::backend::types::RoomType;
 
 use crate::types::Member;
 use crate::types::Message;
+use crate::types::RoomEventFilter;
 use crate::types::{Room, RoomMembership, RoomTag};
 
 use serde_json::Value as JsonValue;
@@ -129,7 +130,11 @@ pub fn get_room_messages(bk: &Backend, roomid: String, from: String) -> Result<(
         ("limit", format!("{}", globals::PAGE_LIMIT)),
         (
             "filter",
-            "{ \"types\": [\"m.room.message\", \"m.sticker\"] }".to_string(),
+            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(&format!("rooms/{}/messages", roomid), params)?;
diff --git a/fractal-matrix-api/src/backend/sync.rs b/fractal-matrix-api/src/backend/sync.rs
index 34a87a3a..02b46d9a 100644
--- a/fractal-matrix-api/src/backend/sync.rs
+++ b/fractal-matrix-api/src/backend/sync.rs
@@ -3,8 +3,12 @@ use crate::backend::types::Backend;
 use crate::error::Error;
 use crate::globals;
 use crate::types::Event;
+use crate::types::EventFilter;
+use crate::types::Filter;
 use crate::types::Message;
 use crate::types::Room;
+use crate::types::RoomEventFilter;
+use crate::types::RoomFilter;
 use crate::types::SyncResponse;
 use crate::types::UnreadNotificationsCount;
 use crate::util::json_q;
@@ -32,23 +36,41 @@ pub fn sync(bk: &Backend, new_since: Option<String>, initial: bool) -> Result<()
     let timeout = if !initial {
         time::Duration::from_secs(30)
     } else {
-        let filter = format!(r#"{{
-            "room": {{
-                "state": {{
-                    "types": ["m.room.*"],
-                    "not_types": ["m.room.member"]
-                }},
-                "timeline": {{
-                    "types": ["m.room.message", "m.sticker"],
-                    "limit": {}
-                }},
-                "ephemeral": {{ "types": [] }}
-            }},
-            "presence": {{ "types": [] }},
-            "event_format": "client",
-            "event_fields": ["type", "content", "sender", "origin_server_ts", "event_id", "unsigned"]
-        }}"#, globals::PAGE_LIMIT);
-        params.push(("filter", filter));
+        let filter = Filter {
+            room: Some(RoomFilter {
+                state: Some(RoomEventFilter {
+                    types: Some(vec!["m.room.*"]),
+                    not_types: vec!["m.room.member"],
+                    ..Default::default()
+                }),
+                timeline: Some(RoomEventFilter {
+                    types: Some(vec!["m.room.message", "m.sticker"]),
+                    limit: Some(globals::PAGE_LIMIT),
+                    ..Default::default()
+                }),
+                ephemeral: Some(RoomEventFilter {
+                    types: Some(vec![]),
+                    ..Default::default()
+                }),
+                ..Default::default()
+            }),
+            presence: Some(EventFilter {
+                types: Some(vec![]),
+                ..Default::default()
+            }),
+            event_fields: Some(vec![
+                "type",
+                "content",
+                "sender",
+                "origin_server_ts",
+                "event_id",
+                "unsigned",
+            ]),
+            ..Default::default()
+        };
+        let filter_str =
+            serde_json::to_string(&filter).expect("Failed to serialize sync request filter");
+        params.push(("filter", filter_str));
 
         Default::default()
     };
diff --git a/fractal-matrix-api/src/model/filter.rs b/fractal-matrix-api/src/model/filter.rs
new file mode 100644
index 00000000..2d852d67
--- /dev/null
+++ b/fractal-matrix-api/src/model/filter.rs
@@ -0,0 +1,81 @@
+use serde::Serialize;
+use std::ops::Not;
+
+#[derive(Clone, Debug, Default, Serialize)]
+pub struct Filter<'a> {
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub event_fields: Option<Vec<&'a str>>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub event_format: Option<EventFormat>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub presence: Option<EventFilter<'a>>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub account_data: Option<EventFilter<'a>>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub room: Option<RoomFilter<'a>>,
+}
+
+#[derive(Clone, Debug, Serialize)]
+#[serde(rename_all = "lowercase")]
+pub enum EventFormat {
+    Client,
+    Federation,
+}
+
+impl Default for EventFormat {
+    fn default() -> Self {
+        EventFormat::Client
+    }
+}
+
+#[derive(Clone, Debug, Default, Serialize)]
+pub struct EventFilter<'a> {
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub limit: Option<i32>,
+    #[serde(skip_serializing_if = "Vec::is_empty")]
+    pub not_senders: Vec<&'a str>,
+    #[serde(skip_serializing_if = "Vec::is_empty")]
+    pub not_types: Vec<&'a str>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub senders: Option<Vec<&'a str>>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub types: Option<Vec<&'a str>>,
+}
+
+#[derive(Clone, Debug, Default, Serialize)]
+pub struct RoomFilter<'a> {
+    #[serde(skip_serializing_if = "Vec::is_empty")]
+    pub not_rooms: Vec<&'a str>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub rooms: Option<Vec<&'a str>>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub ephemeral: Option<RoomEventFilter<'a>>,
+    #[serde(skip_serializing_if = "Not::not")]
+    pub include_leave: bool,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub state: Option<RoomEventFilter<'a>>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub timeline: Option<RoomEventFilter<'a>>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub account_data: Option<RoomEventFilter<'a>>,
+}
+
+#[derive(Clone, Debug, Default, Serialize)]
+pub struct RoomEventFilter<'a> {
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub limit: Option<i32>,
+    #[serde(skip_serializing_if = "Vec::is_empty")]
+    pub not_senders: Vec<&'a str>,
+    #[serde(skip_serializing_if = "Vec::is_empty")]
+    pub not_types: Vec<&'a str>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub senders: Option<Vec<&'a str>>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub types: Option<Vec<&'a str>>,
+    #[serde(skip_serializing_if = "Vec::is_empty")]
+    pub not_rooms: Vec<&'a str>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub rooms: Option<Vec<&'a str>>,
+    #[serde(skip_serializing_if = "Not::not")]
+    pub contains_url: bool,
+}
diff --git a/fractal-matrix-api/src/model/mod.rs b/fractal-matrix-api/src/model/mod.rs
index 956385fd..a1ce43b9 100644
--- a/fractal-matrix-api/src/model/mod.rs
+++ b/fractal-matrix-api/src/model/mod.rs
@@ -1,4 +1,5 @@
 pub mod event;
+pub mod filter;
 pub mod member;
 pub mod message;
 pub mod protocol;
diff --git a/fractal-matrix-api/src/types.rs b/fractal-matrix-api/src/types.rs
index d841d436..96aa9d1f 100644
--- a/fractal-matrix-api/src/types.rs
+++ b/fractal-matrix-api/src/types.rs
@@ -1,4 +1,8 @@
 pub use crate::model::event::Event;
+pub use crate::model::filter::EventFilter;
+pub use crate::model::filter::Filter;
+pub use crate::model::filter::RoomEventFilter;
+pub use crate::model::filter::RoomFilter;
 pub use crate::model::member::Member;
 pub use crate::model::member::MemberList;
 pub use crate::model::message::Message;
diff --git a/fractal-matrix-api/src/util.rs b/fractal-matrix-api/src/util.rs
index e91376d9..0afc30a2 100644
--- a/fractal-matrix-api/src/util.rs
+++ b/fractal-matrix-api/src/util.rs
@@ -21,6 +21,7 @@ use std::time::Duration as StdDuration;
 
 use crate::error::Error;
 use crate::types::Message;
+use crate::types::RoomEventFilter;
 
 use reqwest::header::CONTENT_TYPE;
 
@@ -187,8 +188,12 @@ pub fn get_room_media_list(
         ("access_token", String::from(tk)),
         (
             "filter",
-            "{\"filter_json\": { \"contains_url\": true, \"not_types\": [\"m.sticker\"] } }"
-                .to_string(),
+            serde_json::to_string(&RoomEventFilter {
+                contains_url: true,
+                not_types: vec!["m.sticker"],
+                ..Default::default()
+            })
+            .expect("Failed to serialize room media list request filter"),
         ),
     ];
 


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