chiark / gitweb /
Teach Client about the Notification type in the API.
authorSimon Tatham <anakin@pobox.com>
Sun, 31 Dec 2023 09:37:27 +0000 (09:37 +0000)
committerSimon Tatham <anakin@pobox.com>
Sun, 31 Dec 2023 09:54:20 +0000 (09:54 +0000)
src/client.rs
src/types.rs

index f9c3c50229757819a053a7e05928869f9c18f8ad..b70341c392c5202bb642fce02ae5157911385452 100644 (file)
@@ -49,6 +49,7 @@ pub struct Client {
     client: reqwest::blocking::Client,
     accounts: HashMap<String, Account>,
     statuses: HashMap<String, Status>,
+    notifications: HashMap<String, Notification>,
     feeds: HashMap<FeedId, Feed>,
     permit_write: bool,
 }
@@ -153,6 +154,7 @@ impl Client {
             client: reqwest::blocking::Client::new(),
             accounts: HashMap::new(),
             statuses: HashMap::new(),
+            notifications: HashMap::new(),
             feeds: HashMap::new(),
             permit_write: false,
         })
@@ -204,6 +206,14 @@ impl Client {
         self.statuses.insert(st.id.to_string(), st.clone());
     }
 
+    pub fn cache_notification(&mut self, n: &Notification) {
+        self.cache_account(&n.account);
+        if let Some(st) = &n.status {
+            self.cache_status(&st);
+        }
+        self.notifications.insert(n.id.to_string(), n.clone());
+    }
+
     pub fn account_by_id(&mut self, id: &str) -> Result<Account, ClientError> {
         if let Some(st) = self.accounts.get(id) {
             return Ok(st.clone());
@@ -254,6 +264,46 @@ impl Client {
         Ok(st)
     }
 
+    pub fn notification_by_id(&mut self, id: &str) ->
+        Result<Notification, ClientError>
+    {
+        if let Some(not) = self.notifications.get(id) {
+            let mut not = not.clone();
+            if let Some(ac) = self.accounts.get(&not.account.id) {
+                // Update the account details with the latest version
+                // we had cached
+                not.account = ac.clone();
+            }
+            let status_id = match not.status {
+                Some(ref st) => Some(&st.id),
+                None => None,
+            };
+            if let Some(status_id) = status_id {
+                if let Some(st) = self.statuses.get(status_id) {
+                    not.status = Some(st.clone());
+                }
+            }
+            return Ok(not);
+        }
+
+        let (url, req) = self.api_request(Req::get(
+            &("notifications/".to_owned() + id)))?;
+        let body = req.send()?.text()?;
+        let not: Notification = match serde_json::from_str(&body) {
+            Ok(st) => Ok(st),
+            Err(e) => {
+                Err(ClientError::UrlError(url.clone(), e.to_string()))
+            },
+        }?;
+        if not.id != id {
+            return Err(ClientError::UrlError(
+                url.clone(), format!(
+                    "request returned wrong notification id {}", &not.id)));
+        }
+        self.cache_notification(&not);
+        Ok(not)
+    }
+
     // Ok(bool) tells you whether any new items were in fact retrieved
     pub fn fetch_feed(&mut self, id: &FeedId, ext: FeedExtend) ->
         Result<bool, ClientError>
index 12236b3954e0f5c98330a8cbf5e9e18c978e970a..8f0d43ad47e7f37b263001f053d0750ce5abe217 100644 (file)
@@ -46,7 +46,7 @@ pub struct Application {
     pub website: Option<String>,
 }
 
-#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
+#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)]
 pub enum Visibility {
     #[serde(rename = "public")] Public,
     #[serde(rename = "unlisted")] Unlisted,
@@ -54,7 +54,7 @@ pub enum Visibility {
     #[serde(rename = "direct")] Direct,
 }
 
-#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
+#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)]
 pub enum MediaType {
     #[serde(rename = "unknown")] Unknown,
     #[serde(rename = "image")] Image,
@@ -115,3 +115,27 @@ pub struct Status {
     pub pinned: Option<bool>,
     // pub filtered: Option<Vec<FilterResult>>,
 }
+
+#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)]
+pub enum NotificationType {
+    #[serde(rename = "mention")] Mention,
+    #[serde(rename = "status")] Status,
+    #[serde(rename = "reblog")] Reblog,
+    #[serde(rename = "follow")] Follow,
+    #[serde(rename = "follow_request")] FollowRequest,
+    #[serde(rename = "favourite")] Favourite,
+    #[serde(rename = "poll")] Poll,
+    #[serde(rename = "update")] Update,
+    #[serde(rename = "admin.sign_up")] AdminSignUp,
+    #[serde(rename = "admin.report")] AdminReport,
+}
+
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub struct Notification {
+    pub id: String,
+    #[serde(rename="type")] pub ntype: NotificationType,
+    pub created_at: DateTime<Utc>,
+    pub account: Account,
+    pub status: Option<Status>,
+    // pub report: Option<AdminReport>,
+}