diff options
Diffstat (limited to 'src/stream/activity.rs')
-rw-r--r-- | src/stream/activity.rs | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/src/stream/activity.rs b/src/stream/activity.rs new file mode 100644 index 0000000..dd311d7 --- /dev/null +++ b/src/stream/activity.rs @@ -0,0 +1,186 @@ +/** + * Representation of a stream item, as received from the zot api streams. + * + * SPDX-FileCopyrightText: 2023 Eilertsens Kodeknekkeri + * SPDX-FileCopyrightText: 2023 Harald Eilertsen <haraldei@anduin.net> + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +use super::actor::Actor; +use super::datetime::DateTime; +use super::Tag; +use super::verb::Verb; + +use serde::Deserialize; +use url::Url; +use uuid::Uuid; + +#[derive(Debug, Deserialize, PartialEq)] +#[serde(rename_all="snake_case")] +pub enum StreamItemType { + Activity, +} + +#[derive(Debug, Deserialize, PartialEq)] +#[serde(rename_all="snake_case")] +pub enum StreamItemEncoding { + Zot, +} + +#[derive(Debug, Deserialize, PartialEq)] +#[serde(rename_all="snake_case")] +pub enum StreamItemFlag { + Direct, + Notshown, + Private, + ThreadParent, +} + +/** + * Represents an item as returned by the stream API's. + */ +#[derive(Debug, Deserialize, PartialEq)] +pub struct StreamItem { + #[serde(rename="type")] + pub item_type: StreamItemType, + pub encoding: StreamItemEncoding, + + pub uuid: Uuid, + pub message_id: Url, + pub message_top: Url, + pub message_parent: Url, + pub permalink: Url, + + /* + * Date and time fields for when the item was + * created, last edited or commented, as well as + * when/if it expires. + */ + pub created: DateTime, + pub edited: DateTime, + pub expires: DateTime, + pub commented: DateTime, + + pub verb: Verb, + + pub title: String, + pub summary: String, + pub body: String, + + pub owner: Actor, + pub author: Actor, + + pub signature: String, + pub flags: Option<Vec<StreamItemFlag>>, + pub tags: Option<Vec<Tag>>, +} + +impl StreamItem { + pub fn is_post(&self) -> bool { + self.verb == Verb::Post + } +} + +#[cfg(test)] +mod test { + + use super::*; + + #[test] + fn parse_stream_item_from_json() { + let json = r#" + { + "type": "activity", + "encoding": "zot", + "uuid": "2c102ec3-676b-4d84-b2b4-9141467a254f", + "message_id": "https://example.com/item/2c102ec3-676b-4d84-b2b4-9141467a254f", + "message_top": "https://example.com/item/2c102ec3-676b-4d84-b2b4-9141467a254f", + "message_parent": "https://example.com/item/2c102ec3-676b-4d84-b2b4-9141467a254f", + "created": "2023-12-12 17:00:42", + "edited": "2023-12-12 17:00:42", + "expires": "0000-00-00 00:00:00", + "commented": "2023-12-19 09:01:15", + "mimetype": "text/bbcode", + "title": "The item title", + "summary": "The summary of the post", + "body": "The body of the post", + "app": "", + "verb": "Create", + "object_type": "Note", + "target_type": "", + "permalink": "https://example.com/item/2c102ec3-676b-4d84-b2b4-9141467a254f", + "location": "", + "longlat": "", + "signature": "sha256.ADzsjr5uFUpcwVkUT9liHimr1n2TJmGpTtm0SGSody_6vTbfYhHK3OJJhGknImHYwMradSwVcA9dNAAXzhSoAY5hCmSbnThLun30HVIA3E0ZSDBbt1RyKNomqBCvCBmyyFKhxYoPk34UQisCH6gIQ3eZL-m5PxE9t2oMO_CnpPvLWESoezY3CAZaEIIRj3KKozwC8DxibQmsnCeA32C-2Ejzv8PdZCX1skbIdc5d8Jj_ykyUTqc2DZKMSl9osua3esEMwYZLbxlRQruDfgyjJExdvz57zpeqf1WKzqdIZ5kmguZxch6NLVMiRitooT-sIZOvo9JzgP1ogBQW34W-kG1hHzuGJQkDZKOAA1rLD8qrfwugbbg9wDpjtZY-WHv265KMMsFhctIIupNPVVkuSgs0jMKQmjJTeDE0IxBKx2dCsxiqMWlJll_LSu7b6BtTa7jcuhfMPaKqdMOCRRnGNwehj6qeOXPV7zEZsc4Mzym6N_jRTV556OmUwaCHouEFqTG1ARE5EquYTMk2wXIteC5lT2d0WpEGTnlL1WpqWLx9DCp76Z2JsxMBxjZicKvJSm1gX3ng2ENG2cvECww0IF_zPy2DmHcWOqm795-11uLBNt_60bpP9-sgjrNSj0q6MHgAsFGnpW42M4sFe-6gb-W-HjyHwY2B2yjErYC9KDo", + "route": "", + "owner": { + "name": "Benjamin Franklin", + "address": "ben@example.com", + "url": "https://example.com/channel/ben", + "network": "zot6", + "photo": { + "mimetype": "image/jpeg", + "src": "https://example.com/photo/profile/m/2" + }, + "id": "rUpgk2qbvnWLoKIXOlZlwlqI5vk8C4NgudFNjbcmnOBjFSXU34TObkZEClaPSfKnpFZpg87tANtko7WGs7QRvA", + "id_sig": "sha256.ZD8uwYmUEG_d02Y...", + "key": "-----BEGIN PUBLIC KEY-----\n....\n-----END PUBLIC KEY-----\n" + }, + "author": { + "name": "Benjamin Franklin", + "address": "ben@example.com", + "url": "https://example.com/channel/ben", + "network": "zot6", + "photo": { + "mimetype": "image/jpeg", + "src": "https://example.com/photo/profile/m/2" + }, + "id": "rUpgk2qbvnWLoKIXOlZlwlqI5vk8C4NgudFNjbcmnOBjFSXU34TObkZEClaPSfKnpFZpg87tANtko7WGs7QRvA", + "id_sig": "sha256.ZD8uwYmUEG_d02Y...", + "key": "-----BEGIN PUBLIC KEY-----\n....\n-----END PUBLIC KEY-----\n" + }, + "flags": [ + "thread_parent" + ], + "public_scope": "", + "comment_scope": "contacts", + "tags": [ + { + "tag": "a-tag", + "url": "https://example.com/search?tag=a-tag", + "type": "hashtag" + }, + { + "tag": "fediverse", + "url": "https://example.com/search?tag=fediverse", + "type": "hashtag" + }, + { + "tag": "hubzilla", + "url": "https://example.com/search?tag=hubzilla", + "type": "hashtag" + } + ] + }"#; + + let item: StreamItem = serde_json::from_str(&json).unwrap(); + + assert_eq!(StreamItemType::Activity, item.item_type); + assert_eq!(StreamItemEncoding::Zot, item.encoding); + assert_eq!("2c102ec3-676b-4d84-b2b4-9141467a254f", item.uuid.to_string()); + assert_eq!("https://example.com/item/2c102ec3-676b-4d84-b2b4-9141467a254f", item.message_id.to_string()); + assert_eq!("https://example.com/item/2c102ec3-676b-4d84-b2b4-9141467a254f", item.message_top.to_string()); + assert_eq!("https://example.com/item/2c102ec3-676b-4d84-b2b4-9141467a254f", item.message_parent.to_string()); + assert_eq!("https://example.com/item/2c102ec3-676b-4d84-b2b4-9141467a254f", item.permalink.to_string()); + assert_eq!(Verb::Create, item.verb); + assert_eq!("The item title", &item.title); + assert_eq!("The summary of the post", &item.summary); + assert_eq!("The body of the post", &item.body); + assert_eq!("2023-12-12 17:00:42", &item.created.to_string()); + assert_eq!("2023-12-12 17:00:42", &item.edited.to_string()); + assert_eq!("0000-00-00 00:00:00", &item.expires.to_string()); + assert_eq!("2023-12-19 09:01:15", &item.commented.to_string()); + assert_eq!(StreamItemFlag::ThreadParent, item.flags.as_ref().unwrap()[0]); + } +} |