From acab11f75e527398df8d925ecfc738b027583659 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 31 Dec 2023 09:37:27 +0000 Subject: [PATCH] Teach Client about the Notification type in the API. --- src/client.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/types.rs | 28 ++++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/client.rs b/src/client.rs index f9c3c50..b70341c 100644 --- a/src/client.rs +++ b/src/client.rs @@ -49,6 +49,7 @@ pub struct Client { client: reqwest::blocking::Client, accounts: HashMap, statuses: HashMap, + notifications: HashMap, feeds: HashMap, 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 { 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 + { + if let Some(not) = self.notifications.get(id) { + let mut not = not.clone(); + if let Some(ac) = self.accounts.get(¬.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 {}", ¬.id))); + } + self.cache_notification(¬); + 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 diff --git a/src/types.rs b/src/types.rs index 12236b3..8f0d43a 100644 --- a/src/types.rs +++ b/src/types.rs @@ -46,7 +46,7 @@ pub struct Application { pub website: Option, } -#[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, // pub filtered: Option>, } + +#[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, + pub account: Account, + pub status: Option, + // pub report: Option, +} -- 2.30.2