[fractal] Manage push rules through matrix-sdk



commit c3f6d42994b55590b4247cd9e74a14633c440dc9
Author: Alejandro Domínguez <adomu net-c com>
Date:   Wed Sep 9 04:55:57 2020 +0200

    Manage push rules through matrix-sdk

 fractal-gtk/src/backend/mod.rs                     |  21 +++-
 fractal-gtk/src/backend/room.rs                    | 113 ++++++++++-----------
 fractal-gtk/src/widgets/room_settings.rs           |  22 ++--
 fractal-matrix-api/src/r0.rs                       |   1 -
 fractal-matrix-api/src/r0/pushrules.rs             |   3 -
 .../src/r0/pushrules/delete_room_rules.rs          |  23 -----
 .../src/r0/pushrules/get_room_rules.rs             |  23 -----
 .../src/r0/pushrules/set_room_rules.rs             |  29 ------
 8 files changed, 82 insertions(+), 153 deletions(-)
---
diff --git a/fractal-gtk/src/backend/mod.rs b/fractal-gtk/src/backend/mod.rs
index 01807ad9..b418502d 100644
--- a/fractal-gtk/src/backend/mod.rs
+++ b/fractal-gtk/src/backend/mod.rs
@@ -1,6 +1,10 @@
 use fractal_api::identifiers::{EventId, RoomId, ServerName};
 use fractal_api::url::Url;
-use fractal_api::{Client as MatrixClient, Error as MatrixError};
+use fractal_api::{
+    api::{error::ErrorKind as RumaErrorKind, Error as RumaClientError},
+    Client as MatrixClient, Error as MatrixError, FromHttpResponseError as RumaResponseError,
+    ServerError,
+};
 use lazy_static::lazy_static;
 use log::error;
 use regex::Regex;
@@ -165,6 +169,21 @@ pub trait HandleError: Debug {
     }
 }
 
+// Returns the encapsulated error in case it originated at the Matrix API level
+pub(self) fn get_ruma_client_error(matrix_error: &MatrixError) -> Option<&RumaClientError> {
+    match matrix_error {
+        MatrixError::RumaResponse(RumaResponseError::Http(ServerError::Known(error))) => {
+            Some(error)
+        }
+        _ => None,
+    }
+}
+
+// Returns the kind of error in case it originated at the Matrix API level
+pub(self) fn get_ruma_error_kind(matrix_error: &MatrixError) -> Option<&RumaErrorKind> {
+    get_ruma_client_error(matrix_error).map(|ruma_err| &ruma_err.kind)
+}
+
 /// This function removes the value of the `access_token` query from a URL used for accessing the Matrix API.
 /// The primary use case is the removing of sensitive information for logging.
 /// Specifically, the URL is expected to be contained within quotes and the token is replaced with 
`<redacted>`.
diff --git a/fractal-gtk/src/backend/room.rs b/fractal-gtk/src/backend/room.rs
index d148a676..4a86739e 100644
--- a/fractal-gtk/src/backend/room.rs
+++ b/fractal-gtk/src/backend/room.rs
@@ -4,7 +4,6 @@ use serde_json::json;
 use fractal_api::{
     api::{error::ErrorKind as RumaErrorKind, Error as RumaClientError},
     identifiers::{Error as IdError, EventId, RoomId, RoomIdOrAliasId, UserId},
-    reqwest::Error as ReqwestError,
     url::{ParseError as UrlError, Url},
     Client as MatrixClient, Error as MatrixError, FromHttpResponseError as RumaResponseError,
     ServerError,
@@ -19,7 +18,7 @@ use std::time::Duration;
 use crate::globals;
 
 use crate::actions::AppState;
-use crate::backend::{MediaError, HTTP_CLIENT};
+use crate::backend::MediaError;
 use crate::util::cache_dir_path;
 
 use crate::model::{
@@ -35,6 +34,10 @@ use fractal_api::api::r0::media::create_content::Request as CreateContentRequest
 use fractal_api::api::r0::media::create_content::Response as CreateContentResponse;
 use fractal_api::api::r0::membership::joined_members::Request as JoinedMembersRequest;
 use fractal_api::api::r0::message::get_message_events::Request as GetMessagesEventsRequest;
+use fractal_api::api::r0::push::delete_pushrule::Request as DeleteRoomRulesRequest;
+use fractal_api::api::r0::push::get_pushrule::Request as GetRoomRulesRequest;
+use fractal_api::api::r0::push::set_pushrule::Request as SetRoomRulesRequest;
+use fractal_api::api::r0::push::RuleKind;
 use fractal_api::api::r0::redact::redact_event::Request as RedactEventRequest;
 use fractal_api::api::r0::room::create_room::Request as CreateRoomRequest;
 use fractal_api::api::r0::room::create_room::RoomPreset;
@@ -60,20 +63,15 @@ use fractal_api::events::EventContent;
 use fractal_api::events::EventType;
 use fractal_api::events::InitialStateEvent;
 use fractal_api::events::InvalidInput as NameRoomEventInvalidInput;
-use fractal_api::r0::pushrules::delete_room_rules::request as delete_room_rules;
-use fractal_api::r0::pushrules::delete_room_rules::Parameters as DelRoomRulesParams;
-use fractal_api::r0::pushrules::get_room_rules::request as get_room_rules;
-use fractal_api::r0::pushrules::get_room_rules::Parameters as GetRoomRulesParams;
-use fractal_api::r0::pushrules::set_room_rules::request as set_room_rules;
-use fractal_api::r0::pushrules::set_room_rules::Parameters as SetRoomRulesParams;
-use fractal_api::r0::AccessToken;
+use fractal_api::push::Action;
+use fractal_api::push::Tweak;
 
 use serde_json::value::to_raw_value;
 use serde_json::Error as ParseJsonError;
-use serde_json::Value as JsonValue;
 
 use super::{
-    dw_media, get_prev_batch_from, remove_matrix_access_token_if_present, ContentType, HandleError,
+    dw_media, get_prev_batch_from, get_ruma_error_kind, remove_matrix_access_token_if_present,
+    ContentType, HandleError,
 };
 use crate::app::App;
 use crate::util::i18n::i18n;
@@ -926,10 +924,10 @@ pub enum RoomNotify {
 }
 
 #[derive(Debug)]
-pub struct PushRulesError(ReqwestError);
+pub struct PushRulesError(MatrixError);
 
-impl From<ReqwestError> for PushRulesError {
-    fn from(err: ReqwestError) -> Self {
+impl From<MatrixError> for PushRulesError {
+    fn from(err: MatrixError) -> Self {
         Self(err)
     }
 }
@@ -940,66 +938,61 @@ impl HandleError for PushRulesError {
     }
 }
 
-pub fn get_pushrules(
-    base: Url,
-    access_token: AccessToken,
-    room_id: RoomId,
+pub async fn get_pushrules(
+    session_client: MatrixClient,
+    room_id: &RoomId,
 ) -> Result<RoomNotify, PushRulesError> {
-    let params = GetRoomRulesParams { access_token };
-
-    let request = get_room_rules(base, &params, &room_id)?;
-
-    let mut value = RoomNotify::NotSet;
-
-    let response: Result<JsonValue, _> = HTTP_CLIENT.get_client().execute(request)?.json();
-
-    if let Ok(js) = response {
-        if let Some(array) = js["actions"].as_array() {
-            for v in array {
-                match v.as_str().unwrap_or_default() {
-                    "notify" => value = RoomNotify::All,
-                    "dont_notify" => value = RoomNotify::DontNotify,
-                    _ => {}
-                };
-            }
+    let request = GetRoomRulesRequest::new("global", RuleKind::Room, room_id.as_str());
+
+    let value = match session_client.send(request).await {
+        Ok(response) => {
+            response
+                .rule
+                .actions
+                .iter()
+                .fold(RoomNotify::NotSet, |notify_value, action| match action {
+                    Action::Notify => RoomNotify::All,
+                    Action::DontNotify => RoomNotify::DontNotify,
+                    _ => notify_value,
+                })
         }
-    }
+        // This has to be handled because the pushrule is not always sent previously
+        Err(ref err) if get_ruma_error_kind(err) == Some(&RumaErrorKind::NotFound) => {
+            RoomNotify::NotSet
+        }
+        Err(err) => return Err(err.into()),
+    };
 
     Ok(value)
 }
 
-pub fn set_pushrules(
-    base: Url,
-    access_token: AccessToken,
-    room_id: RoomId,
+pub async fn set_pushrules(
+    session_client: MatrixClient,
+    room_id: &RoomId,
     notify: RoomNotify,
 ) -> Result<(), PushRulesError> {
-    if let RoomNotify::NotSet = notify {
-        return delete_pushrules(base, access_token, room_id);
-    }
-
-    let params = SetRoomRulesParams { access_token };
-    let js = match notify {
-        RoomNotify::DontNotify => json!({"actions": ["dont_notify"]}),
-        RoomNotify::All => json!({
-            "actions": ["notify", {"set_tweak": "sound", "value": "default"}]
-        }),
-        _ => json!({}),
+    let actions = match notify {
+        RoomNotify::NotSet => return delete_pushrules(session_client, room_id).await,
+        RoomNotify::DontNotify => vec![Action::DontNotify],
+        RoomNotify::All => vec![
+            Action::Notify,
+            Action::SetTweak(Tweak::Sound(String::from("default"))),
+        ],
     };
 
-    let request = set_room_rules(base, &params, &room_id, &js)?;
+    let request = SetRoomRulesRequest::new("global", RuleKind::Room, room_id.as_str(), actions);
+
+    session_client.send(request).await?;
 
-    HTTP_CLIENT.get_client().execute(request)?;
     Ok(())
 }
 
-pub fn delete_pushrules(
-    base: Url,
-    access_token: AccessToken,
-    room_id: RoomId,
+pub async fn delete_pushrules(
+    session_client: MatrixClient,
+    room_id: &RoomId,
 ) -> Result<(), PushRulesError> {
-    let params = DelRoomRulesParams { access_token };
-    let request = delete_room_rules(base, &params, &room_id)?;
-    HTTP_CLIENT.get_client().execute(request)?;
+    let request = DeleteRoomRulesRequest::new("global", RuleKind::Room, room_id.as_str());
+    session_client.send(request).await?;
+
     Ok(())
 }
diff --git a/fractal-gtk/src/widgets/room_settings.rs b/fractal-gtk/src/widgets/room_settings.rs
index 73781bd9..1ceece38 100644
--- a/fractal-gtk/src/widgets/room_settings.rs
+++ b/fractal-gtk/src/widgets/room_settings.rs
@@ -5,7 +5,6 @@ use fractal_api::Client as MatrixClient;
 use glib::clone;
 use std::cell::RefCell;
 use std::rc::Rc;
-use std::thread;
 
 use crate::util::i18n::ni18n_f;
 use fractal_api::url::Url;
@@ -153,7 +152,7 @@ impl RoomSettings {
             let _ = button.emit("clicked", &[]);
         });
 
-        topic_btn.connect_clicked(clone!(@strong this => move |_| {
+        topic_btn.connect_clicked(clone!(@strong this, @strong session_client => move |_| {
             this.borrow_mut().update_room_topic(session_client.clone());
         }));
 
@@ -183,13 +182,12 @@ impl RoomSettings {
             clone!(@strong this => move |switch| {
                 let active = switch.get_active();
                 let notify = if active { room::RoomNotify::All } else { room::RoomNotify::DontNotify };
-                let server = this.borrow().server_url.clone();
-                let access_token = this.borrow().access_token.clone();
                 let room_id = this.borrow().room.id.clone();
                 switch.set_sensitive(false);
+                let session_client = session_client.clone();
 
-                thread::spawn(move || {
-                    if let Err(err) = room::set_pushrules(server, access_token, room_id, notify) {
+                RUNTIME.spawn(async move {
+                    if let Err(err) = room::set_pushrules(session_client, &room_id, notify).await {
                         err.handle_error();
                     }
                     let sensitive = true;
@@ -230,12 +228,12 @@ impl RoomSettings {
             ))
         };
 
-        self.room_settings_show_avatar(session_client, edit);
+        self.room_settings_show_avatar(session_client.clone(), edit);
         self.room_settings_show_room_name(name, edit);
         self.room_settings_show_room_topic(topic, is_room, edit);
         self.room_settings_show_room_type(description);
         self.room_settings_show_members(members);
-        self.room_settings_show_notifications();
+        self.room_settings_show_notifications(session_client);
 
         /* admin parts */
         self.room_settings_show_group_room(is_room || is_group);
@@ -672,7 +670,7 @@ impl RoomSettings {
         None
     }
 
-    fn room_settings_show_notifications(&mut self) {
+    fn room_settings_show_notifications(&mut self, session_client: MatrixClient) {
         let switch = self
             .builder
             .get_object::<gtk::Switch>("room_settings_notification_switch")
@@ -680,14 +678,12 @@ impl RoomSettings {
 
         switch.set_sensitive(false);
 
-        let server = self.server_url.clone();
-        let access_token = self.access_token.clone();
         let room_id = self.room.id.clone();
 
-        thread::spawn(move || {
+        RUNTIME.spawn(async move {
             let mut active = true;
             let mut sensitive = true;
-            match room::get_pushrules(server, access_token, room_id) {
+            match room::get_pushrules(session_client, &room_id).await {
                 Ok(room::RoomNotify::DontNotify) => {
                     active = false;
                 }
diff --git a/fractal-matrix-api/src/r0.rs b/fractal-matrix-api/src/r0.rs
index c0a5a4e8..81a8282d 100644
--- a/fractal-matrix-api/src/r0.rs
+++ b/fractal-matrix-api/src/r0.rs
@@ -3,7 +3,6 @@ pub mod contact;
 pub mod filter;
 pub mod media;
 pub mod profile;
-pub mod pushrules;
 pub mod server;
 pub mod sync;
 pub mod thirdparty;


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