From 30d80a0ba71141ded55db9f7d8c219adb9ab222d Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Tue, 18 Apr 2023 03:23:52 +0900 Subject: [PATCH 01/44] Refactor: Use builder in test --- misskey-api/src/endpoint/antennas/create.rs | 6 ++ misskey-api/src/endpoint/antennas/delete.rs | 22 ++---- misskey-api/src/endpoint/antennas/list.rs | 22 ++---- misskey-api/src/endpoint/antennas/notes.rs | 71 +++++-------------- misskey-api/src/endpoint/antennas/show.rs | 24 ++----- misskey-api/src/endpoint/antennas/update.rs | 26 +++---- misskey-api/src/endpoint/channels/follow.rs | 10 +-- misskey-api/src/endpoint/channels/followed.rs | 10 +-- misskey-api/src/endpoint/channels/owned.rs | 10 +-- misskey-api/src/endpoint/channels/show.rs | 10 +-- misskey-api/src/endpoint/channels/timeline.rs | 62 +++++++--------- misskey-api/src/endpoint/channels/unfollow.rs | 10 +-- misskey-api/src/endpoint/channels/update.rs | 30 ++++---- .../endpoint/drive/files/attached_notes.rs | 22 ++---- .../src/endpoint/following/requests/accept.rs | 36 ++-------- .../src/endpoint/following/requests/cancel.rs | 37 ++-------- .../src/endpoint/following/requests/list.rs | 36 ++-------- .../src/endpoint/following/requests/reject.rs | 37 ++-------- misskey-api/src/endpoint/i/notifications.rs | 10 +-- misskey-api/src/endpoint/notes/create.rs | 10 +-- misskey-api/src/endpoint/notes/polls/vote.rs | 23 ++---- misskey-api/src/endpoint/notes/search.rs | 10 +-- misskey-api/src/model/antenna.rs | 3 +- misskey-api/src/streaming/channel/channel.rs | 42 +++++------ misskey-api/src/streaming/channel/drive.rs | 12 ++-- misskey-api/src/streaming/note.rs | 23 ++---- 26 files changed, 194 insertions(+), 420 deletions(-) diff --git a/misskey-api/src/endpoint/antennas/create.rs b/misskey-api/src/endpoint/antennas/create.rs index b55655bc..b4e8f19e 100644 --- a/misskey-api/src/endpoint/antennas/create.rs +++ b/misskey-api/src/endpoint/antennas/create.rs @@ -17,6 +17,7 @@ pub struct Request { /// [ 1 .. 100 ] characters #[builder(setter(into))] pub name: String, + #[builder(default)] pub src: AntennaSource, #[builder(default, setter(strip_option))] pub user_list_id: Option>, @@ -30,10 +31,15 @@ pub struct Request { #[cfg_attr(docsrs, doc(cfg(feature = "12-19-0")))] #[builder(default, setter(into))] pub exclude_keywords: Query, + #[builder(default)] pub users: Vec, + #[builder(default)] pub case_sensitive: bool, + #[builder(default)] pub with_replies: bool, + #[builder(default)] pub with_file: bool, + #[builder(default)] pub notify: bool, } diff --git a/misskey-api/src/endpoint/antennas/delete.rs b/misskey-api/src/endpoint/antennas/delete.rs index 76c3c0a1..32f6384e 100644 --- a/misskey-api/src/endpoint/antennas/delete.rs +++ b/misskey-api/src/endpoint/antennas/delete.rs @@ -20,25 +20,13 @@ mod tests { #[tokio::test] async fn request() { - use crate::model::{antenna::AntennaSource, query::Query}; - let client = TestClient::new(); let antenna = client - .test(crate::endpoint::antennas::create::Request { - name: "test".to_string(), - src: AntennaSource::All, - user_list_id: None, - #[cfg(feature = "12-10-0")] - user_group_id: None, - keywords: Query::default(), - #[cfg(feature = "12-19-0")] - exclude_keywords: Query::default(), - users: Vec::new(), - case_sensitive: false, - with_replies: false, - with_file: false, - notify: false, - }) + .test( + crate::endpoint::antennas::create::Request::builder() + .name("test") + .build(), + ) .await; client diff --git a/misskey-api/src/endpoint/antennas/list.rs b/misskey-api/src/endpoint/antennas/list.rs index 0ada1f3e..a30a6616 100644 --- a/misskey-api/src/endpoint/antennas/list.rs +++ b/misskey-api/src/endpoint/antennas/list.rs @@ -18,25 +18,13 @@ mod tests { #[tokio::test] async fn request() { - use crate::model::{antenna::AntennaSource, query::Query}; - let client = TestClient::new(); client - .test(crate::endpoint::antennas::create::Request { - name: "test".to_string(), - src: AntennaSource::All, - user_list_id: None, - #[cfg(feature = "12-10-0")] - user_group_id: None, - keywords: Query::default(), - #[cfg(feature = "12-19-0")] - exclude_keywords: Query::default(), - users: Vec::new(), - case_sensitive: false, - with_replies: false, - with_file: false, - notify: false, - }) + .test( + crate::endpoint::antennas::create::Request::builder() + .name("test") + .build(), + ) .await; client.test(Request::default()).await; diff --git a/misskey-api/src/endpoint/antennas/notes.rs b/misskey-api/src/endpoint/antennas/notes.rs index 193e3234..f72f3773 100644 --- a/misskey-api/src/endpoint/antennas/notes.rs +++ b/misskey-api/src/endpoint/antennas/notes.rs @@ -34,26 +34,13 @@ mod tests { #[tokio::test] async fn request() { - use crate::model::{antenna::AntennaSource, query::Query}; - let client = TestClient::new(); let antenna = client - .user - .test(crate::endpoint::antennas::create::Request { - name: "test".to_string(), - src: AntennaSource::All, - user_list_id: None, - #[cfg(feature = "12-10-0")] - user_group_id: None, - keywords: Query::default(), - #[cfg(feature = "12-19-0")] - exclude_keywords: Query::default(), - users: Vec::new(), - case_sensitive: false, - with_replies: false, - with_file: false, - notify: false, - }) + .test( + crate::endpoint::antennas::create::Request::builder() + .name("test") + .build(), + ) .await; client @@ -69,26 +56,14 @@ mod tests { #[tokio::test] async fn request_with_limit() { - use crate::model::{antenna::AntennaSource, query::Query}; - let client = TestClient::new(); let antenna = client - .user - .test(crate::endpoint::antennas::create::Request { - name: "test".to_string(), - src: AntennaSource::All, - user_list_id: None, - #[cfg(feature = "12-10-0")] - user_group_id: None, - keywords: Query::from_vec(vec![vec!["hello".to_string(), "awesome".to_string()]]), - #[cfg(feature = "12-19-0")] - exclude_keywords: Query::default(), - users: Vec::new(), - case_sensitive: false, - with_replies: false, - with_file: false, - notify: false, - }) + .test( + crate::endpoint::antennas::create::Request::builder() + .name("test") + .keywords("hello awesome") + .build(), + ) .await; client @@ -104,26 +79,14 @@ mod tests { #[tokio::test] async fn request_paginate() { - use crate::model::{antenna::AntennaSource, query::Query}; - let client = TestClient::new(); let antenna = client - .user - .test(crate::endpoint::antennas::create::Request { - name: "test".to_string(), - src: AntennaSource::All, - user_list_id: None, - #[cfg(feature = "12-10-0")] - user_group_id: None, - keywords: Query::from_vec(vec![vec!["hello".to_string(), "awesome".to_string()]]), - #[cfg(feature = "12-19-0")] - exclude_keywords: Query::default(), - users: Vec::new(), - case_sensitive: false, - with_replies: false, - with_file: false, - notify: false, - }) + .test( + crate::endpoint::antennas::create::Request::builder() + .name("test") + .keywords("hello awesome") + .build(), + ) .await; let note = client .admin diff --git a/misskey-api/src/endpoint/antennas/show.rs b/misskey-api/src/endpoint/antennas/show.rs index 538b03e3..2827403d 100644 --- a/misskey-api/src/endpoint/antennas/show.rs +++ b/misskey-api/src/endpoint/antennas/show.rs @@ -20,26 +20,14 @@ mod tests { #[tokio::test] async fn request() { - use crate::model::{antenna::AntennaSource, query::Query}; - let client = TestClient::new(); let antenna = client - .user - .test(crate::endpoint::antennas::create::Request { - name: "test".to_string(), - src: AntennaSource::All, - user_list_id: None, - #[cfg(feature = "12-10-0")] - user_group_id: None, - keywords: Query::from_vec(vec![vec!["hello".to_string(), "awesome".to_string()]]), - #[cfg(feature = "12-19-0")] - exclude_keywords: Query(vec![vec!["oh".to_string()]]), - users: Vec::new(), - case_sensitive: false, - with_replies: false, - with_file: false, - notify: false, - }) + .test( + crate::endpoint::antennas::create::Request::builder() + .name("test") + .keywords("hello awesome") + .build(), + ) .await; client diff --git a/misskey-api/src/endpoint/antennas/update.rs b/misskey-api/src/endpoint/antennas/update.rs index 2d555f34..5b4d283a 100644 --- a/misskey-api/src/endpoint/antennas/update.rs +++ b/misskey-api/src/endpoint/antennas/update.rs @@ -55,21 +55,17 @@ mod tests { let client = TestClient::new(); let antenna = client .user - .test(crate::endpoint::antennas::create::Request { - name: "test".to_string(), - src: AntennaSource::All, - user_list_id: None, - #[cfg(feature = "12-10-0")] - user_group_id: None, - keywords: Query::from_vec(vec![vec!["hello".to_string(), "awesome".to_string()]]), - #[cfg(feature = "12-19-0")] - exclude_keywords: Query::default(), - users: Vec::new(), - case_sensitive: true, - with_replies: false, - with_file: true, - notify: false, - }) + .test( + crate::endpoint::antennas::create::Request::builder() + .name("test") + .keywords(Query::from_vec(vec![vec![ + "hello".to_string(), + "awesome".to_string(), + ]])) + .case_sensitive(true) + .with_file(true) + .build(), + ) .await; let list = client diff --git a/misskey-api/src/endpoint/channels/follow.rs b/misskey-api/src/endpoint/channels/follow.rs index e2e9c729..c78f516c 100644 --- a/misskey-api/src/endpoint/channels/follow.rs +++ b/misskey-api/src/endpoint/channels/follow.rs @@ -22,11 +22,11 @@ mod tests { async fn request() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test channel".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test channel") + .build(), + ) .await; client diff --git a/misskey-api/src/endpoint/channels/followed.rs b/misskey-api/src/endpoint/channels/followed.rs index ff77a899..638701bd 100644 --- a/misskey-api/src/endpoint/channels/followed.rs +++ b/misskey-api/src/endpoint/channels/followed.rs @@ -64,11 +64,11 @@ mod tests { async fn request_paginate() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test channel".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test channel") + .build(), + ) .await; client .test(crate::endpoint::channels::follow::Request { diff --git a/misskey-api/src/endpoint/channels/owned.rs b/misskey-api/src/endpoint/channels/owned.rs index d950caec..4de00ca5 100644 --- a/misskey-api/src/endpoint/channels/owned.rs +++ b/misskey-api/src/endpoint/channels/owned.rs @@ -64,11 +64,11 @@ mod tests { async fn request_paginate() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test channel".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test channel") + .build(), + ) .await; client diff --git a/misskey-api/src/endpoint/channels/show.rs b/misskey-api/src/endpoint/channels/show.rs index 027523e0..1bbc51c6 100644 --- a/misskey-api/src/endpoint/channels/show.rs +++ b/misskey-api/src/endpoint/channels/show.rs @@ -22,11 +22,11 @@ mod tests { async fn request() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test channel".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test channel") + .build(), + ) .await; client diff --git a/misskey-api/src/endpoint/channels/timeline.rs b/misskey-api/src/endpoint/channels/timeline.rs index a3881cac..aa2b4b38 100644 --- a/misskey-api/src/endpoint/channels/timeline.rs +++ b/misskey-api/src/endpoint/channels/timeline.rs @@ -49,11 +49,11 @@ mod tests { async fn request() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test") + .build(), + ) .await; client @@ -72,11 +72,11 @@ mod tests { async fn request_with_limit() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test") + .build(), + ) .await; client @@ -95,29 +95,19 @@ mod tests { async fn request_paginate() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test") + .build(), + ) .await; let note = client - .test(crate::endpoint::notes::create::Request { - visibility: None, - visible_user_ids: None, - text: Some("some text".to_string()), - cw: None, - via_mobile: None, - local_only: None, - no_extract_mentions: None, - no_extract_hashtags: None, - no_extract_emojis: None, - file_ids: None, - reply_id: None, - renote_id: None, - poll: None, - channel_id: Some(channel.id.clone()), - }) + .test( + crate::endpoint::notes::create::Request::builder() + .text("some text") + .channel_id(channel.id.clone()) + .build(), + ) .await .created_note; @@ -137,11 +127,11 @@ mod tests { async fn request_with_date() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test") + .build(), + ) .await; let now = chrono::Utc::now(); diff --git a/misskey-api/src/endpoint/channels/unfollow.rs b/misskey-api/src/endpoint/channels/unfollow.rs index b5f91e57..e82fd9d5 100644 --- a/misskey-api/src/endpoint/channels/unfollow.rs +++ b/misskey-api/src/endpoint/channels/unfollow.rs @@ -22,11 +22,11 @@ mod tests { async fn request() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test channel".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test channel") + .build(), + ) .await; client .test(crate::endpoint::channels::follow::Request { diff --git a/misskey-api/src/endpoint/channels/update.rs b/misskey-api/src/endpoint/channels/update.rs index 31439e89..dea2e20a 100644 --- a/misskey-api/src/endpoint/channels/update.rs +++ b/misskey-api/src/endpoint/channels/update.rs @@ -35,11 +35,11 @@ mod tests { async fn request_with_name() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test channel".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test channel") + .build(), + ) .await; client.test(Request { @@ -55,11 +55,11 @@ mod tests { async fn request_with_description() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test channel".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test channel") + .build(), + ) .await; client @@ -84,11 +84,11 @@ mod tests { async fn request_with_banner() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test channel".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test channel") + .build(), + ) .await; let url = client.avatar_url().await; let file = client.upload_from_url(url).await; diff --git a/misskey-api/src/endpoint/drive/files/attached_notes.rs b/misskey-api/src/endpoint/drive/files/attached_notes.rs index 58c9aabc..77e7ec8d 100644 --- a/misskey-api/src/endpoint/drive/files/attached_notes.rs +++ b/misskey-api/src/endpoint/drive/files/attached_notes.rs @@ -23,23 +23,11 @@ mod tests { let client = TestClient::new(); let file = client.create_text_file("test.txt", "test").await; client - .test(crate::endpoint::notes::create::Request { - visibility: None, - visible_user_ids: None, - text: None, - cw: None, - via_mobile: None, - local_only: None, - no_extract_mentions: None, - no_extract_hashtags: None, - no_extract_emojis: None, - file_ids: Some(vec![file.id.clone()]), - reply_id: None, - renote_id: None, - poll: None, - #[cfg(feature = "12-47-0")] - channel_id: None, - }) + .test( + crate::endpoint::notes::create::Request::builder() + .file_ids(vec![file.id.clone()]) + .build(), + ) .await; client.test(Request { file_id: file.id }).await; diff --git a/misskey-api/src/endpoint/following/requests/accept.rs b/misskey-api/src/endpoint/following/requests/accept.rs index 85850844..f85840a9 100644 --- a/misskey-api/src/endpoint/following/requests/accept.rs +++ b/misskey-api/src/endpoint/following/requests/accept.rs @@ -24,37 +24,11 @@ mod tests { let (new_user, new_client) = client.admin.create_user().await; new_client - .test(crate::endpoint::i::update::Request { - name: None, - description: None, - lang: None, - location: None, - birthday: None, - avatar_id: None, - banner_id: None, - fields: None, - is_locked: Some(true), - #[cfg(feature = "12-63-0")] - is_explorable: None, - careful_bot: None, - auto_accept_followed: None, - is_bot: None, - is_cat: None, - #[cfg(not(feature = "12-55-0"))] - auto_watch: None, - inject_featured_note: None, - always_mark_nsfw: None, - pinned_page_id: None, - muted_words: None, - #[cfg(feature = "12-60-0")] - no_crawle: None, - #[cfg(feature = "12-69-0")] - receive_announcement_email: None, - #[cfg(feature = "12-48-0")] - muting_notification_types: None, - #[cfg(feature = "12-70-0")] - email_notification_types: None, - }) + .test( + crate::endpoint::i::update::Request::builder() + .is_locked(true) + .build(), + ) .await; client .user diff --git a/misskey-api/src/endpoint/following/requests/cancel.rs b/misskey-api/src/endpoint/following/requests/cancel.rs index f1f2348d..9eecca2e 100644 --- a/misskey-api/src/endpoint/following/requests/cancel.rs +++ b/misskey-api/src/endpoint/following/requests/cancel.rs @@ -24,37 +24,12 @@ mod tests { let (new_user, new_client) = client.admin.create_user().await; new_client - .test(crate::endpoint::i::update::Request { - name: None, - description: None, - lang: None, - location: None, - birthday: None, - avatar_id: None, - banner_id: None, - fields: None, - is_locked: Some(true), - #[cfg(feature = "12-63-0")] - is_explorable: None, - careful_bot: None, - auto_accept_followed: Some(false), - is_bot: None, - is_cat: None, - #[cfg(not(feature = "12-55-0"))] - auto_watch: None, - inject_featured_note: None, - always_mark_nsfw: None, - pinned_page_id: None, - muted_words: None, - #[cfg(feature = "12-60-0")] - no_crawle: None, - #[cfg(feature = "12-69-0")] - receive_announcement_email: None, - #[cfg(feature = "12-48-0")] - muting_notification_types: None, - #[cfg(feature = "12-70-0")] - email_notification_types: None, - }) + .test( + crate::endpoint::i::update::Request::builder() + .is_locked(true) + .auto_accept_followed(false) + .build(), + ) .await; client .user diff --git a/misskey-api/src/endpoint/following/requests/list.rs b/misskey-api/src/endpoint/following/requests/list.rs index 3a1e9221..bcc19886 100644 --- a/misskey-api/src/endpoint/following/requests/list.rs +++ b/misskey-api/src/endpoint/following/requests/list.rs @@ -22,37 +22,11 @@ mod tests { let (new_user, new_client) = client.admin.create_user().await; new_client - .test(crate::endpoint::i::update::Request { - name: None, - description: None, - lang: None, - location: None, - birthday: None, - avatar_id: None, - banner_id: None, - fields: None, - is_locked: Some(true), - #[cfg(feature = "12-63-0")] - is_explorable: None, - careful_bot: None, - auto_accept_followed: None, - is_bot: None, - is_cat: None, - #[cfg(not(feature = "12-55-0"))] - auto_watch: None, - inject_featured_note: None, - always_mark_nsfw: None, - pinned_page_id: None, - muted_words: None, - #[cfg(feature = "12-60-0")] - no_crawle: None, - #[cfg(feature = "12-69-0")] - receive_announcement_email: None, - #[cfg(feature = "12-48-0")] - muting_notification_types: None, - #[cfg(feature = "12-70-0")] - email_notification_types: None, - }) + .test( + crate::endpoint::i::update::Request::builder() + .is_locked(true) + .build(), + ) .await; client .user diff --git a/misskey-api/src/endpoint/following/requests/reject.rs b/misskey-api/src/endpoint/following/requests/reject.rs index 865255a8..d494d9ac 100644 --- a/misskey-api/src/endpoint/following/requests/reject.rs +++ b/misskey-api/src/endpoint/following/requests/reject.rs @@ -24,37 +24,12 @@ mod tests { let (new_user, new_client) = client.admin.create_user().await; new_client - .test(crate::endpoint::i::update::Request { - name: None, - description: None, - lang: None, - location: None, - birthday: None, - avatar_id: None, - banner_id: None, - fields: None, - is_locked: Some(true), - #[cfg(feature = "12-63-0")] - is_explorable: None, - careful_bot: None, - auto_accept_followed: Some(false), - is_bot: None, - is_cat: None, - #[cfg(not(feature = "12-55-0"))] - auto_watch: None, - inject_featured_note: None, - always_mark_nsfw: None, - pinned_page_id: None, - muted_words: None, - #[cfg(feature = "12-60-0")] - no_crawle: None, - #[cfg(feature = "12-69-0")] - receive_announcement_email: None, - #[cfg(feature = "12-48-0")] - muting_notification_types: None, - #[cfg(feature = "12-70-0")] - email_notification_types: None, - }) + .test( + crate::endpoint::i::update::Request::builder() + .is_locked(true) + .auto_accept_followed(false) + .build(), + ) .await; client .user diff --git a/misskey-api/src/endpoint/i/notifications.rs b/misskey-api/src/endpoint/i/notifications.rs index a5b7da30..5bf2aa32 100644 --- a/misskey-api/src/endpoint/i/notifications.rs +++ b/misskey-api/src/endpoint/i/notifications.rs @@ -97,11 +97,11 @@ mod tests { async fn request_paginate() { let client = TestClient::new(); client - .test(crate::endpoint::notifications::create::Request { - body: "hi".to_string(), - header: None, - icon: None, - }) + .test( + crate::endpoint::notifications::create::Request::builder() + .body("hi") + .build(), + ) .await; let mut notification = None; diff --git a/misskey-api/src/endpoint/notes/create.rs b/misskey-api/src/endpoint/notes/create.rs index af7ecc76..9cedf13f 100644 --- a/misskey-api/src/endpoint/notes/create.rs +++ b/misskey-api/src/endpoint/notes/create.rs @@ -428,11 +428,11 @@ mod tests { async fn request_with_channel_id() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test channel") + .build(), + ) .await; client diff --git a/misskey-api/src/endpoint/notes/polls/vote.rs b/misskey-api/src/endpoint/notes/polls/vote.rs index bad87799..6e42b497 100644 --- a/misskey-api/src/endpoint/notes/polls/vote.rs +++ b/misskey-api/src/endpoint/notes/polls/vote.rs @@ -30,23 +30,12 @@ mod tests { expired_after: None, }; let note = client - .test(crate::endpoint::notes::create::Request { - visibility: None, - visible_user_ids: None, - text: Some("poll".to_string()), - cw: None, - via_mobile: None, - local_only: None, - no_extract_mentions: None, - no_extract_hashtags: None, - no_extract_emojis: None, - file_ids: None, - reply_id: None, - renote_id: None, - poll: Some(poll), - #[cfg(feature = "12-47-0")] - channel_id: None, - }) + .test( + crate::endpoint::notes::create::Request::builder() + .text("poll") + .poll(poll) + .build(), + ) .await .created_note; diff --git a/misskey-api/src/endpoint/notes/search.rs b/misskey-api/src/endpoint/notes/search.rs index 8cb0b314..6a1479a2 100644 --- a/misskey-api/src/endpoint/notes/search.rs +++ b/misskey-api/src/endpoint/notes/search.rs @@ -83,11 +83,11 @@ mod tests { async fn request_with_channel_id() { let client = TestClient::new(); let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test channel".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test channel") + .build(), + ) .await; client diff --git a/misskey-api/src/model/antenna.rs b/misskey-api/src/model/antenna.rs index 8ebabf22..bdcb37bf 100644 --- a/misskey-api/src/model/antenna.rs +++ b/misskey-api/src/model/antenna.rs @@ -30,9 +30,10 @@ pub struct Antenna { impl_entity!(Antenna); -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)] +#[derive(Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone, Copy)] #[serde(rename_all = "camelCase")] pub enum AntennaSource { + #[default] All, Home, Users, diff --git a/misskey-api/src/streaming/channel/channel.rs b/misskey-api/src/streaming/channel/channel.rs index 89077fd1..9052825b 100644 --- a/misskey-api/src/streaming/channel/channel.rs +++ b/misskey-api/src/streaming/channel/channel.rs @@ -38,11 +38,11 @@ mod tests { async fn subscribe_unsubscribe() { let client = TestClient::new().await; let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test") + .build(), + ) .await; let mut stream = client @@ -58,11 +58,11 @@ mod tests { async fn stream() { let client = TestClient::new().await; let channel = client - .test(crate::endpoint::channels::create::Request { - name: "test".to_string(), - description: None, - banner_id: None, - }) + .test( + crate::endpoint::channels::create::Request::builder() + .name("test") + .build(), + ) .await; let mut stream = client @@ -73,22 +73,12 @@ mod tests { .unwrap(); future::join( - client.test(crate::endpoint::notes::create::Request { - visibility: None, - visible_user_ids: None, - text: Some("some text".to_string()), - cw: None, - via_mobile: None, - local_only: None, - no_extract_mentions: None, - no_extract_hashtags: None, - no_extract_emojis: None, - file_ids: None, - reply_id: None, - renote_id: None, - poll: None, - channel_id: Some(channel.id), - }), + client.test( + crate::endpoint::notes::create::Request::builder() + .text("some text") + .channel_id(channel.id) + .build(), + ), async { stream.next().await.unwrap().unwrap() }, ) .await; diff --git a/misskey-api/src/streaming/channel/drive.rs b/misskey-api/src/streaming/channel/drive.rs index 828feab7..2443c6c3 100644 --- a/misskey-api/src/streaming/channel/drive.rs +++ b/misskey-api/src/streaming/channel/drive.rs @@ -135,12 +135,12 @@ mod tests { let mut stream = client.channel(Request::default()).await.unwrap(); future::join( - client.test(crate::endpoint::drive::files::update::Request { - file_id: file.id, - folder_id: None, - is_sensitive: None, - name: Some("test".to_string()), - }), + client.test( + crate::endpoint::drive::files::update::Request::builder() + .file_id(file.id) + .name("test") + .build(), + ), async { loop { match stream.next().await.unwrap().unwrap() { diff --git a/misskey-api/src/streaming/note.rs b/misskey-api/src/streaming/note.rs index 04fc5dbf..d4e1a48c 100644 --- a/misskey-api/src/streaming/note.rs +++ b/misskey-api/src/streaming/note.rs @@ -143,23 +143,12 @@ mod tests { }; let note = client .user - .test(crate::endpoint::notes::create::Request { - visibility: None, - visible_user_ids: None, - text: Some("?".to_string()), - cw: None, - via_mobile: None, - local_only: None, - no_extract_mentions: None, - no_extract_hashtags: None, - no_extract_emojis: None, - file_ids: None, - reply_id: None, - renote_id: None, - poll: Some(poll), - #[cfg(feature = "12-47-0")] - channel_id: None, - }) + .test( + crate::endpoint::notes::create::Request::builder() + .text("?") + .poll(poll) + .build(), + ) .await .created_note; From f298bc0a2ad93df47a21baf07ef7cf5cc32e821b Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Tue, 18 Apr 2023 03:24:17 +0900 Subject: [PATCH 02/44] Add: Support v12.77.0 --- .github/workflows/ci.yml | 4 ++-- .github/workflows/flaky.yml | 2 ++ .github/workflows/unstable.yml | 4 ++-- misskey-api/CHANGELOG.md | 3 ++- misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/i/update.rs | 9 +++++++++ misskey-api/src/model/user.rs | 28 ++++++++++++++++++++++++++++ misskey-util/Cargo.toml | 1 + misskey-util/src/builder/me.rs | 5 +++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 3 ++- 11 files changed, 55 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2096913f..e2d5bf10 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.75.1' + MISSKEY_IMAGE: 'misskey/misskey:12.77.0' MISSKEY_ID: aid - - run: cargo test --features 12-75-0 + - run: cargo test --features 12-77-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index cc51a576..80055a59 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.77.0' + flags: --features 12-77-0 - image: 'misskey/misskey:12.75.0' flags: --features 12-75-0 - image: 'misskey/misskey:12.71.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 7c14bf85..b5bb22d1 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.75.1' + MISSKEY_IMAGE: 'misskey/misskey:12.77.0' MISSKEY_ID: aid - - run: cargo test --features 12-75-0 + - run: cargo test --features 12-77-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index ec9d11c3..f37f13a6 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -21,12 +21,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.69.0 - Support for Misskey v12.70.0 - Support for Misskey v12.71.0 ~ v12.74.1 -- Support for Misskey v12.75.0 ~ v12.75.1 +- Support for Misskey v12.75.0 ~ v12.76.1 - `muted_notification_types` user setting which is available since v12.48.0 - Page related endpoints - endpoint `pages/*` - endpoint `i/pages` - endpoint `i/page_likes` +- Support for Misskey v12.77.0 ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 8d5a0343..02b921b8 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-77-0 = ["12-75-0"] 12-75-0 = ["12-71-0"] 12-71-0 = ["12-70-0"] 12-70-0 = ["12-69-0"] diff --git a/misskey-api/src/endpoint/i/update.rs b/misskey-api/src/endpoint/i/update.rs index 83127a1f..bb878603 100644 --- a/misskey-api/src/endpoint/i/update.rs +++ b/misskey-api/src/endpoint/i/update.rs @@ -52,6 +52,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub is_explorable: Option, + #[cfg(feature = "12-77-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-77-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub hide_online_status: Option, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub careful_bot: Option, @@ -149,6 +154,8 @@ mod tests { is_locked: Some(true), #[cfg(feature = "12-63-0")] is_explorable: Some(false), + #[cfg(feature = "12-77-0")] + hide_online_status: Some(true), careful_bot: Some(true), auto_accept_followed: Some(true), is_bot: Some(true), @@ -201,6 +208,8 @@ mod tests { is_locked: None, #[cfg(feature = "12-63-0")] is_explorable: None, + #[cfg(feature = "12-77-0")] + hide_online_status: None, careful_bot: None, auto_accept_followed: None, is_bot: None, diff --git a/misskey-api/src/model/user.rs b/misskey-api/src/model/user.rs index 6875f613..72038550 100644 --- a/misskey-api/src/model/user.rs +++ b/misskey-api/src/model/user.rs @@ -91,6 +91,26 @@ impl std::str::FromStr for UserEmailNotificationType { } } +#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, Copy, Hash)] +#[serde(rename_all = "camelCase")] +pub enum OnlineStatus { + Unknown, + Online, + Active, + Offline, +} + +impl Display for OnlineStatus { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + OnlineStatus::Unknown => f.write_str("unknown"), + OnlineStatus::Online => f.write_str("online"), + OnlineStatus::Active => f.write_str("active"), + OnlineStatus::Offline => f.write_str("offline"), + } + } +} + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct User { @@ -194,6 +214,14 @@ pub struct User { #[cfg_attr(docsrs, doc(cfg(feature = "12-70-0")))] #[serde(default)] pub email_notification_types: Option>, + #[cfg(feature = "12-77-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-77-0")))] + #[serde(default)] + pub online_status: Option, + #[cfg(feature = "12-77-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-77-0")))] + #[serde(default)] + pub hide_online_status: Option, } fn default_false() -> bool { diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 8e574eef..bd64892c 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-77-0 = ["misskey-api/12-77-0", "12-75-0"] 12-75-0 = ["misskey-api/12-75-0", "12-71-0"] 12-71-0 = ["misskey-api/12-71-0", "12-70-0"] 12-70-0 = ["misskey-api/12-70-0", "12-69-0"] diff --git a/misskey-util/src/builder/me.rs b/misskey-util/src/builder/me.rs index 291a7096..b076e214 100644 --- a/misskey-util/src/builder/me.rs +++ b/misskey-util/src/builder/me.rs @@ -152,6 +152,11 @@ impl MeUpdateBuilder { #[cfg_attr(docsrs, doc(cfg(feature = "12-63-0")))] pub explorable { is_explorable }; + /// Sets whether to hide online status from other users. + #[cfg(feature = "12-77-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-77-0")))] + pub hide_online_status; + /// Sets whether this user requires a follow request from bots. pub require_follow_request_for_bot { careful_bot }; diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index c7317510..82ef9794 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-77-0 = ["misskey-api/12-77-0", "misskey-util/12-77-0"] 12-75-0 = ["misskey-api/12-75-0", "misskey-util/12-75-0"] 12-71-0 = ["misskey-api/12-71-0", "misskey-util/12-71-0"] 12-70-0 = ["misskey-api/12-70-0", "misskey-util/12-70-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 2b92cd75..24130ccd 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,7 +102,8 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | -//! | `12-75-0` | v12.75.0 ~ v12.75.1 | v12.75.0 | +//! | `12-77-0` | v12.77.0 | v12.77.0 | +//! | `12-75-0` | v12.75.0 ~ v12.76.1 | v12.75.0 | //! | `12-71-0` | v12.71.0 ~ v12.74.1 | v12.71.0 | //! | `12-70-0` | v12.70.0 | v12.70.0 | //! | `12-69-0` | v12.69.0 | v12.69.0 | From 799d8d58fc5d20dff27f9c4c53f1dcd525251c23 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Sun, 9 Apr 2023 23:52:57 +0900 Subject: [PATCH 03/44] Add: Support v12.77.1 --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 2 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/notifications.rs | 4 ++ .../src/endpoint/notifications/read.rs | 49 +++++++++++++++++++ misskey-util/Cargo.toml | 1 + misskey-util/src/client.rs | 17 +++++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 11 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 misskey-api/src/endpoint/notifications/read.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e2d5bf10..ef4936bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.77.0' + MISSKEY_IMAGE: 'misskey/misskey:12.77.1' MISSKEY_ID: aid - - run: cargo test --features 12-77-0 + - run: cargo test --features 12-77-1 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 80055a59..ce346cf6 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.77.1' + flags: --features 12-77-1 - image: 'misskey/misskey:12.77.0' flags: --features 12-77-0 - image: 'misskey/misskey:12.75.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index b5bb22d1..43bb6f39 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.77.0' + MISSKEY_IMAGE: 'misskey/misskey:12.77.1' MISSKEY_ID: aid - - run: cargo test --features 12-77-0 + - run: cargo test --features 12-77-1 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index f37f13a6..8e65329d 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -28,6 +28,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint `i/pages` - endpoint `i/page_likes` - Support for Misskey v12.77.0 +- Support for Misskey v12.77.1 ~ v12.78.0 + - endpoint `notifications/read` ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 02b921b8..2bf18367 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-77-1 = ["12-77-0"] 12-77-0 = ["12-75-0"] 12-75-0 = ["12-71-0"] 12-71-0 = ["12-70-0"] diff --git a/misskey-api/src/endpoint/notifications.rs b/misskey-api/src/endpoint/notifications.rs index 86d65686..d2b78a39 100644 --- a/misskey-api/src/endpoint/notifications.rs +++ b/misskey-api/src/endpoint/notifications.rs @@ -3,3 +3,7 @@ pub mod create; pub mod mark_all_as_read; + +#[cfg(feature = "12-77-1")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-77-1")))] +pub mod read; diff --git a/misskey-api/src/endpoint/notifications/read.rs b/misskey-api/src/endpoint/notifications/read.rs new file mode 100644 index 00000000..188bd44c --- /dev/null +++ b/misskey-api/src/endpoint/notifications/read.rs @@ -0,0 +1,49 @@ +use crate::model::{id::Id, notification::Notification}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub notification_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "notifications/read"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client + .admin + .test( + crate::endpoint::notifications::create::Request::builder() + .body("hi") + .build(), + ) + .await; + + let mut notification = None; + while notification.is_none() { + notification = client + .admin + .test(crate::endpoint::i::notifications::Request::default()) + .await + .pop(); + } + + client + .admin + .test(Request { + notification_id: notification.unwrap().id, + }) + .await; + } +} diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index bd64892c..1965835a 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-77-1 = ["misskey-api/12-77-1", "12-77-0"] 12-77-0 = ["misskey-api/12-77-0", "12-75-0"] 12-75-0 = ["misskey-api/12-75-0", "12-71-0"] 12-71-0 = ["misskey-api/12-71-0", "12-70-0"] diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index b8530172..de64e1ad 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -3699,6 +3699,23 @@ pub trait ClientExt: Client + Sync { }) } + /// Marks the specified notification as read. + #[cfg(feature = "12-77-1")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-77-1")))] + fn mark_notification_as_read( + &self, + notification: impl EntityRef, + ) -> BoxFuture>> { + let notification_id = notification.entity_ref(); + Box::pin(async move { + self.request(endpoint::notifications::read::Request { notification_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + /// Creates a notification with the given text. #[cfg(feature = "12-27-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-27-0")))] diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 82ef9794..70ef7b15 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-77-1 = ["misskey-api/12-77-1", "misskey-util/12-77-1"] 12-77-0 = ["misskey-api/12-77-0", "misskey-util/12-77-0"] 12-75-0 = ["misskey-api/12-75-0", "misskey-util/12-75-0"] 12-71-0 = ["misskey-api/12-71-0", "misskey-util/12-71-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 24130ccd..0f0abf93 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-77-1` | v12.77.1 ~ v12.78.0 | v12.77.1 | //! | `12-77-0` | v12.77.0 | v12.77.0 | //! | `12-75-0` | v12.75.0 ~ v12.76.1 | v12.75.0 | //! | `12-71-0` | v12.71.0 ~ v12.74.1 | v12.71.0 | From 0c05d5decd5a1205d0d46ab354e85f7560652dc7 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Tue, 11 Apr 2023 06:21:52 +0900 Subject: [PATCH 04/44] Add: Add gallery related endpoints --- misskey-api/CHANGELOG.md | 4 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint.rs | 4 + misskey-api/src/endpoint/gallery.rs | 3 + misskey-api/src/endpoint/gallery/featured.rs | 24 +++++ misskey-api/src/endpoint/gallery/popular.rs | 24 +++++ misskey-api/src/endpoint/gallery/posts.rs | 81 +++++++++++++++++ .../src/endpoint/gallery/posts/create.rs | 65 +++++++++++++ .../src/endpoint/gallery/posts/like.rs | 39 ++++++++ .../src/endpoint/gallery/posts/show.rs | 38 ++++++++ .../src/endpoint/gallery/posts/unlike.rs | 44 +++++++++ misskey-api/src/endpoint/i.rs | 4 + misskey-api/src/endpoint/i/gallery.rs | 2 + misskey-api/src/endpoint/i/gallery/likes.rs | 91 +++++++++++++++++++ misskey-api/src/endpoint/i/gallery/posts.rs | 76 ++++++++++++++++ misskey-api/src/endpoint/users.rs | 4 + misskey-api/src/endpoint/users/gallery.rs | 1 + .../src/endpoint/users/gallery/posts.rs | 90 ++++++++++++++++++ misskey-api/src/model.rs | 1 + misskey-api/src/model/gallery.rs | 36 ++++++++ 20 files changed, 632 insertions(+) create mode 100644 misskey-api/src/endpoint/gallery.rs create mode 100644 misskey-api/src/endpoint/gallery/featured.rs create mode 100644 misskey-api/src/endpoint/gallery/popular.rs create mode 100644 misskey-api/src/endpoint/gallery/posts.rs create mode 100644 misskey-api/src/endpoint/gallery/posts/create.rs create mode 100644 misskey-api/src/endpoint/gallery/posts/like.rs create mode 100644 misskey-api/src/endpoint/gallery/posts/show.rs create mode 100644 misskey-api/src/endpoint/gallery/posts/unlike.rs create mode 100644 misskey-api/src/endpoint/i/gallery.rs create mode 100644 misskey-api/src/endpoint/i/gallery/likes.rs create mode 100644 misskey-api/src/endpoint/i/gallery/posts.rs create mode 100644 misskey-api/src/endpoint/users/gallery.rs create mode 100644 misskey-api/src/endpoint/users/gallery/posts.rs create mode 100644 misskey-api/src/model/gallery.rs diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 8e65329d..9615ec21 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -30,6 +30,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.77.0 - Support for Misskey v12.77.1 ~ v12.78.0 - endpoint `notifications/read` +- Support for Misskey v12.79.0 ~ v12.79.1 + - endpoint `gallery/*` + - endpoint `i/gallery/*` + - endpoint `users/gallery/posts` ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 2bf18367..573c9cf9 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-79-0 = ["12-77-1"] 12-77-1 = ["12-77-0"] 12-77-0 = ["12-75-0"] 12-75-0 = ["12-71-0"] diff --git a/misskey-api/src/endpoint.rs b/misskey-api/src/endpoint.rs index 0478a47d..8cdb928d 100644 --- a/misskey-api/src/endpoint.rs +++ b/misskey-api/src/endpoint.rs @@ -78,3 +78,7 @@ pub mod server_info; #[cfg(feature = "12-67-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-67-0")))] pub mod ping; + +#[cfg(feature = "12-79-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] +pub mod gallery; diff --git a/misskey-api/src/endpoint/gallery.rs b/misskey-api/src/endpoint/gallery.rs new file mode 100644 index 00000000..ca095dc0 --- /dev/null +++ b/misskey-api/src/endpoint/gallery.rs @@ -0,0 +1,3 @@ +pub mod featured; +pub mod popular; +pub mod posts; diff --git a/misskey-api/src/endpoint/gallery/featured.rs b/misskey-api/src/endpoint/gallery/featured.rs new file mode 100644 index 00000000..9677ffeb --- /dev/null +++ b/misskey-api/src/endpoint/gallery/featured.rs @@ -0,0 +1,24 @@ +use crate::model::gallery::GalleryPost; + +use serde::Serialize; + +#[derive(Serialize, Default, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request {} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "gallery/featured"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.test(Request::default()).await; + } +} diff --git a/misskey-api/src/endpoint/gallery/popular.rs b/misskey-api/src/endpoint/gallery/popular.rs new file mode 100644 index 00000000..e2466cb8 --- /dev/null +++ b/misskey-api/src/endpoint/gallery/popular.rs @@ -0,0 +1,24 @@ +use crate::model::gallery::GalleryPost; + +use serde::Serialize; + +#[derive(Serialize, Default, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request {} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "gallery/popular"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.test(Request::default()).await; + } +} diff --git a/misskey-api/src/endpoint/gallery/posts.rs b/misskey-api/src/endpoint/gallery/posts.rs new file mode 100644 index 00000000..84556bf1 --- /dev/null +++ b/misskey-api/src/endpoint/gallery/posts.rs @@ -0,0 +1,81 @@ +use crate::model::{gallery::GalleryPost, id::Id}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +pub mod create; +pub mod like; +pub mod show; +pub mod unlike; + +#[derive(Serialize, Default, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + /// 1 .. 100 + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub since_id: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub until_id: Option>, +} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "gallery/posts"; +} + +impl_pagination!(Request, GalleryPost); + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.user.test(Request::default()).await; + } + + #[tokio::test] + async fn request_with_limit() { + let client = TestClient::new(); + + client + .test(Request { + limit: Some(100), + since_id: None, + until_id: None, + }) + .await; + } + + #[tokio::test] + async fn request_paginate() { + let client = TestClient::new(); + let url = client.avatar_url().await; + let file = client.upload_from_url(url).await; + + let post = client + .test(crate::endpoint::gallery::posts::create::Request { + title: "gallery post".to_string(), + description: None, + file_ids: vec![file.id], + is_sensitive: None, + }) + .await; + + client + .test(Request { + limit: None, + since_id: Some(post.id.clone()), + until_id: Some(post.id.clone()), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/gallery/posts/create.rs b/misskey-api/src/endpoint/gallery/posts/create.rs new file mode 100644 index 00000000..5601770c --- /dev/null +++ b/misskey-api/src/endpoint/gallery/posts/create.rs @@ -0,0 +1,65 @@ +use crate::model::{drive::DriveFile, gallery::GalleryPost, id::Id}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + /// [ 1 .. ] characters + #[builder(default, setter(into))] + pub title: String, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option, into))] + pub description: Option, + /// [ 1 .. 32 ] ids + #[builder(default, setter(into))] + pub file_ids: Vec>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option, into))] + pub is_sensitive: Option, +} + +impl misskey_core::Request for Request { + type Response = GalleryPost; + const ENDPOINT: &'static str = "gallery/posts/create"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let url = client.avatar_url().await; + let file = client.upload_from_url(url).await; + + client + .test(Request { + title: "gallery post".to_string(), + description: None, + file_ids: vec![file.id], + is_sensitive: None, + }) + .await; + } + + #[tokio::test] + async fn request_with_options() { + let client = TestClient::new(); + let url = client.avatar_url().await; + let file = client.upload_from_url(url).await; + + client + .test(Request { + title: "gallery post".to_string(), + description: Some("description".to_string()), + file_ids: vec![file.id], + is_sensitive: Some(true), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/gallery/posts/like.rs b/misskey-api/src/endpoint/gallery/posts/like.rs new file mode 100644 index 00000000..fdc267c0 --- /dev/null +++ b/misskey-api/src/endpoint/gallery/posts/like.rs @@ -0,0 +1,39 @@ +use crate::model::{gallery::GalleryPost, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub post_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "gallery/posts/like"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let url = client.avatar_url().await; + let file = client.upload_from_url(url).await; + + let post = client + .user + .test(crate::endpoint::gallery::posts::create::Request { + title: "gallery post".to_string(), + description: None, + file_ids: vec![file.id], + is_sensitive: None, + }) + .await; + + client.admin.test(Request { post_id: post.id }).await; + } +} diff --git a/misskey-api/src/endpoint/gallery/posts/show.rs b/misskey-api/src/endpoint/gallery/posts/show.rs new file mode 100644 index 00000000..7efaac0e --- /dev/null +++ b/misskey-api/src/endpoint/gallery/posts/show.rs @@ -0,0 +1,38 @@ +use crate::model::{gallery::GalleryPost, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub post_id: Id, +} + +impl misskey_core::Request for Request { + type Response = GalleryPost; + const ENDPOINT: &'static str = "gallery/posts/show"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let url = client.avatar_url().await; + let file = client.upload_from_url(url).await; + + let post = client + .test(crate::endpoint::gallery::posts::create::Request { + title: "gallery post".to_string(), + description: None, + file_ids: vec![file.id], + is_sensitive: None, + }) + .await; + + client.test(Request { post_id: post.id }).await; + } +} diff --git a/misskey-api/src/endpoint/gallery/posts/unlike.rs b/misskey-api/src/endpoint/gallery/posts/unlike.rs new file mode 100644 index 00000000..b802d6fd --- /dev/null +++ b/misskey-api/src/endpoint/gallery/posts/unlike.rs @@ -0,0 +1,44 @@ +use crate::model::{gallery::GalleryPost, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub post_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "gallery/posts/unlike"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let url = client.avatar_url().await; + let file = client.upload_from_url(url).await; + + let post = client + .user + .test(crate::endpoint::gallery::posts::create::Request { + title: "gallery post".to_string(), + description: None, + file_ids: vec![file.id], + is_sensitive: None, + }) + .await; + + client + .admin + .test(crate::endpoint::gallery::posts::like::Request { post_id: post.id }) + .await; + + client.admin.test(Request { post_id: post.id }).await; + } +} diff --git a/misskey-api/src/endpoint/i.rs b/misskey-api/src/endpoint/i.rs index 25b97155..af8b1f68 100644 --- a/misskey-api/src/endpoint/i.rs +++ b/misskey-api/src/endpoint/i.rs @@ -18,6 +18,10 @@ pub mod user_group_invites; #[cfg_attr(docsrs, doc(cfg(feature = "12-67-0")))] pub mod registry; +#[cfg(feature = "12-79-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] +pub mod gallery; + #[derive(Serialize, Default, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct Request {} diff --git a/misskey-api/src/endpoint/i/gallery.rs b/misskey-api/src/endpoint/i/gallery.rs new file mode 100644 index 00000000..09884894 --- /dev/null +++ b/misskey-api/src/endpoint/i/gallery.rs @@ -0,0 +1,2 @@ +pub mod likes; +pub mod posts; diff --git a/misskey-api/src/endpoint/i/gallery/likes.rs b/misskey-api/src/endpoint/i/gallery/likes.rs new file mode 100644 index 00000000..bb90118c --- /dev/null +++ b/misskey-api/src/endpoint/i/gallery/likes.rs @@ -0,0 +1,91 @@ +use crate::model::{gallery::GalleryLike, id::Id}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Default, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + /// 1 .. 100 + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub since_id: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub until_id: Option>, +} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "i/gallery/likes"; +} + +impl_pagination!(Request, GalleryLike); + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.user.test(Request::default()).await; + } + + #[tokio::test] + async fn request_with_limit() { + let client = TestClient::new(); + + client + .test(Request { + limit: Some(100), + since_id: None, + until_id: None, + }) + .await; + } + + #[tokio::test] + async fn request_paginate() { + let client = TestClient::new(); + let url = client.avatar_url().await; + let file = client.upload_from_url(url).await; + + let post = client + .user + .test(crate::endpoint::gallery::posts::create::Request { + title: "gallery post".to_string(), + description: None, + file_ids: vec![file.id], + is_sensitive: None, + }) + .await; + client + .admin + .test(crate::endpoint::gallery::posts::like::Request { post_id: post.id }) + .await; + + let likes = client + .admin + .test(Request { + limit: None, + since_id: None, + until_id: None, + }) + .await; + + client + .admin + .test(Request { + limit: None, + since_id: Some(likes[0].id.clone()), + until_id: Some(likes[0].id.clone()), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/i/gallery/posts.rs b/misskey-api/src/endpoint/i/gallery/posts.rs new file mode 100644 index 00000000..13efa780 --- /dev/null +++ b/misskey-api/src/endpoint/i/gallery/posts.rs @@ -0,0 +1,76 @@ +use crate::model::{gallery::GalleryPost, id::Id}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Default, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + /// 1 .. 100 + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub since_id: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub until_id: Option>, +} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "i/gallery/posts"; +} + +impl_pagination!(Request, GalleryPost); + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.user.test(Request::default()).await; + } + + #[tokio::test] + async fn request_with_limit() { + let client = TestClient::new(); + + client + .test(Request { + limit: Some(100), + since_id: None, + until_id: None, + }) + .await; + } + + #[tokio::test] + async fn request_paginate() { + let client = TestClient::new(); + let url = client.avatar_url().await; + let file = client.upload_from_url(url).await; + + let post = client + .test(crate::endpoint::gallery::posts::create::Request { + title: "gallery post".to_string(), + description: None, + file_ids: vec![file.id], + is_sensitive: None, + }) + .await; + + client + .test(Request { + limit: None, + since_id: Some(post.id.clone()), + until_id: Some(post.id.clone()), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/users.rs b/misskey-api/src/endpoint/users.rs index 07f5f5fd..de5ae06a 100644 --- a/misskey-api/src/endpoint/users.rs +++ b/misskey-api/src/endpoint/users.rs @@ -32,6 +32,10 @@ pub mod clips; #[cfg_attr(docsrs, doc(cfg(feature = "12-61-0")))] pub mod pages; +#[cfg(feature = "12-79-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] +pub mod gallery; + #[derive(Serialize, PartialEq, Eq, Clone, Debug, Copy)] #[serde(rename_all = "camelCase")] pub enum UserState { diff --git a/misskey-api/src/endpoint/users/gallery.rs b/misskey-api/src/endpoint/users/gallery.rs new file mode 100644 index 00000000..83d81e78 --- /dev/null +++ b/misskey-api/src/endpoint/users/gallery.rs @@ -0,0 +1 @@ +pub mod posts; diff --git a/misskey-api/src/endpoint/users/gallery/posts.rs b/misskey-api/src/endpoint/users/gallery/posts.rs new file mode 100644 index 00000000..60f36e5d --- /dev/null +++ b/misskey-api/src/endpoint/users/gallery/posts.rs @@ -0,0 +1,90 @@ +use crate::model::{gallery::GalleryPost, id::Id, user::User}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + pub user_id: Id, + /// 1 .. 100 + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub since_id: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub until_id: Option>, +} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "users/gallery/posts"; +} + +impl_pagination!(Request, GalleryPost); + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let user = client.user.me().await; + client + .user + .test(Request { + user_id: user.id, + limit: None, + since_id: None, + until_id: None, + }) + .await; + } + + #[tokio::test] + async fn request_with_limit() { + let client = TestClient::new(); + let user = client.user.me().await; + + client + .test(Request { + user_id: user.id, + limit: Some(100), + since_id: None, + until_id: None, + }) + .await; + } + + #[tokio::test] + async fn request_paginate() { + let client = TestClient::new(); + let user = client.user.me().await; + let url = client.avatar_url().await; + let file = client.upload_from_url(url).await; + + let post = client + .test(crate::endpoint::gallery::posts::create::Request { + title: "gallery post".to_string(), + description: None, + file_ids: vec![file.id], + is_sensitive: None, + }) + .await; + + client + .test(Request { + user_id: user.id, + limit: None, + since_id: Some(post.id.clone()), + until_id: Some(post.id.clone()), + }) + .await; + } +} diff --git a/misskey-api/src/model.rs b/misskey-api/src/model.rs index 0feedac7..cc5fb7da 100644 --- a/misskey-api/src/model.rs +++ b/misskey-api/src/model.rs @@ -26,6 +26,7 @@ pub mod clip; pub mod drive; pub mod emoji; pub mod following; +pub mod gallery; pub mod id; pub mod log; pub mod messaging; diff --git a/misskey-api/src/model/gallery.rs b/misskey-api/src/model/gallery.rs new file mode 100644 index 00000000..14d218a5 --- /dev/null +++ b/misskey-api/src/model/gallery.rs @@ -0,0 +1,36 @@ +use crate::model::{drive::DriveFile, id::Id, user::User}; + +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct GalleryPost { + pub id: Id, + pub created_at: DateTime, + pub updated_at: DateTime, + pub user_id: Id, + pub user: User, + pub title: String, + #[serde(default)] + pub description: Option, + pub file_ids: Vec>, + pub files: Vec, + #[serde(default)] + pub tags: Option>, + pub is_sensitive: bool, + pub liked_count: u64, + #[serde(default)] + pub is_liked: Option, +} + +impl_entity!(GalleryPost); + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct GalleryLike { + pub id: Id, + pub post: GalleryPost, +} + +impl_entity!(GalleryLike); From bf3dc2e5aec6d38cf253ccaf0cb927076d51c82a Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Tue, 11 Apr 2023 18:50:10 +0900 Subject: [PATCH 05/44] Add: Support v12.79.0 --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-util/CHANGELOG.md | 1 + misskey-util/Cargo.toml | 1 + misskey-util/src/builder.rs | 7 ++ misskey-util/src/builder/gallery.rs | 76 +++++++++++++ misskey-util/src/client.rs | 159 ++++++++++++++++++++++++++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 10 files changed, 252 insertions(+), 4 deletions(-) create mode 100644 misskey-util/src/builder/gallery.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ef4936bf..7256cd86 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.77.1' + MISSKEY_IMAGE: 'misskey/misskey:12.79.0' MISSKEY_ID: aid - - run: cargo test --features 12-77-1 + - run: cargo test --features 12-79-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index ce346cf6..273c8191 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.79.0' + flags: --features 12-79-0 - image: 'misskey/misskey:12.77.1' flags: --features 12-77-1 - image: 'misskey/misskey:12.77.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 43bb6f39..c49bfe6d 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.77.1' + MISSKEY_IMAGE: 'misskey/misskey:12.79.0' MISSKEY_ID: aid - - run: cargo test --features 12-77-1 + - run: cargo test --features 12-79-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-util/CHANGELOG.md b/misskey-util/CHANGELOG.md index dec2b2a3..160a6b01 100644 --- a/misskey-util/CHANGELOG.md +++ b/misskey-util/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Registry APIs - Page APIs +- Gallery APIs ### Changed ### Deprecated diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 1965835a..0d14da3e 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-79-0 = ["misskey-api/12-79-0", "12-77-1"] 12-77-1 = ["misskey-api/12-77-1", "12-77-0"] 12-77-0 = ["misskey-api/12-77-0", "12-75-0"] 12-75-0 = ["misskey-api/12-75-0", "12-71-0"] diff --git a/misskey-util/src/builder.rs b/misskey-util/src/builder.rs index 2e74becc..88be5bfe 100644 --- a/misskey-util/src/builder.rs +++ b/misskey-util/src/builder.rs @@ -22,6 +22,9 @@ mod user; #[cfg(feature = "12-47-0")] mod channel; +#[cfg(feature = "12-79-0")] +mod gallery; + pub use admin::{ AnnouncementUpdateBuilder, EmojiUpdateBuilder, MetaUpdateBuilder, ServerLogListBuilder, }; @@ -44,3 +47,7 @@ pub use channel::{ChannelBuilder, ChannelUpdateBuilder}; #[cfg(feature = "12-27-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-27-0")))] pub use misc::NotificationBuilder; + +#[cfg(feature = "12-79-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] +pub use gallery::GalleryPostBuilder; diff --git a/misskey-util/src/builder/gallery.rs b/misskey-util/src/builder/gallery.rs new file mode 100644 index 00000000..c5558ea9 --- /dev/null +++ b/misskey-util/src/builder/gallery.rs @@ -0,0 +1,76 @@ +use crate::Error; + +use misskey_api::model::{drive::DriveFile, gallery::GalleryPost}; +use misskey_api::{endpoint, EntityRef}; +use misskey_core::Client; + +/// Builder for the [`build_gallery_post`][`crate::ClientExt::build_gallery_post`] method. +pub struct GalleryPostBuilder { + client: C, + request: endpoint::gallery::posts::create::Request, +} + +impl GalleryPostBuilder { + /// Creates a builder with the client. + pub fn new(client: C) -> Self { + let request = endpoint::gallery::posts::create::Request { + title: String::default(), + description: None, + file_ids: Vec::default(), + is_sensitive: None, + }; + GalleryPostBuilder { client, request } + } + + /// Gets the request object for reuse. + pub fn as_request(&self) -> &endpoint::gallery::posts::create::Request { + &self.request + } + + /// Sets the title of the post. + pub fn title(&mut self, title: impl Into) -> &mut Self { + self.request.title = title.into(); + self + } + + /// Sets the description of the post. + pub fn description(&mut self, description: impl Into) -> &mut Self { + self.request.description.replace(description.into()); + self + } + + /// Sets the files of the post. + pub fn files( + &mut self, + files: impl IntoIterator>, + ) -> &mut Self { + let ids = files.into_iter().map(|file| file.entity_ref()); + self.request.file_ids = ids.collect(); + self + } + + /// Adds a file to the post. + pub fn add_file(&mut self, file: impl EntityRef) -> &mut Self { + self.request.file_ids.push(file.entity_ref()); + self + } + + /// Sets whether the post contains NSFW content. + pub fn sensitive(&mut self, sensitive: bool) -> &mut Self { + self.request.is_sensitive = Some(sensitive); + self + } +} + +impl GalleryPostBuilder { + /// Creates the post. + pub async fn create(&self) -> Result> { + let post = self + .client + .request(&self.request) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(post) + } +} diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index de64e1ad..06f05de4 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -4,6 +4,8 @@ use std::path::Path; #[cfg(feature = "12-9-0")] use crate::builder::EmojiUpdateBuilder; +#[cfg(feature = "12-79-0")] +use crate::builder::GalleryPostBuilder; #[cfg(feature = "12-27-0")] use crate::builder::NotificationBuilder; use crate::builder::{ @@ -27,6 +29,8 @@ use futures::{future::BoxFuture, stream::TryStreamExt}; use mime::Mime; #[cfg(feature = "12-47-0")] use misskey_api::model::channel::Channel; +#[cfg(feature = "12-79-0")] +use misskey_api::model::gallery::GalleryPost; #[cfg(feature = "12-67-0")] use misskey_api::model::registry::{RegistryKey, RegistryScope, RegistryValue}; use misskey_api::model::{ @@ -3250,6 +3254,161 @@ pub trait ClientExt: Client + Sync { } // }}} + // {{{ Gallery + /// Creates a gallery post with the given title and files. + #[cfg(feature = "12-79-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] + fn create_gallery_post( + &self, + title: impl Into, + files: impl IntoIterator>, + ) -> BoxFuture>> { + let title = title.into(); + let files: Vec> = files.into_iter().map(|file| file.entity_ref()).collect(); + Box::pin(async move { + self.build_gallery_post() + .title(title) + .files(files) + .create() + .await + }) + } + + /// Returns a builder for creating a gallery post. + /// + /// The returned builder provides methods to customize details of the post, + /// and you can chain them to create a post incrementally. + /// Finally, calling [`create`][builder_create] method will actually create a post. + /// See [`GalleryPostBuilder`] for the provided methods. + /// + /// [builder_create]: GalleryPostBuilder::create + #[cfg(feature = "12-79-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] + fn build_gallery_post(&self) -> GalleryPostBuilder<&Self> { + GalleryPostBuilder::new(self) + } + + /// Gets the corresponding gallery post from the ID. + #[cfg(feature = "12-79-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] + fn get_gallery_post( + &self, + id: Id, + ) -> BoxFuture>> { + Box::pin(async move { + let post = self + .request(endpoint::gallery::posts::show::Request { post_id: id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(post) + }) + } + + /// Gives a like to the specified gallery post. + #[cfg(feature = "12-79-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] + fn like_gallery_post( + &self, + post: impl EntityRef, + ) -> BoxFuture>> { + let post_id = post.entity_ref(); + Box::pin(async move { + self.request(endpoint::gallery::posts::like::Request { post_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + + /// Removes a like from the specified gallery post. + #[cfg(feature = "12-79-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] + fn unlike_gallery_post( + &self, + post: impl EntityRef, + ) -> BoxFuture>> { + let post_id = post.entity_ref(); + Box::pin(async move { + self.request(endpoint::gallery::posts::unlike::Request { post_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + + /// Lists the gallery posts created by the user logged in with this client. + #[cfg(feature = "12-79-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] + fn gallery_posts(&self) -> PagerStream> { + let pager = BackwardPager::new(self, endpoint::i::gallery::posts::Request::default()); + PagerStream::new(Box::pin(pager)) + } + + /// Lists the gallery posts liked by the user logged in with this client. + #[cfg(feature = "12-79-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] + fn liked_gallery_posts(&self) -> PagerStream> { + let pager = BackwardPager::new(self, endpoint::i::gallery::likes::Request::default()) + .map_ok(|v| v.into_iter().map(|l| l.post).collect()); + PagerStream::new(Box::pin(pager)) + } + + /// Lists the gallery posts created by the specified user. + #[cfg(feature = "12-79-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] + fn user_gallery_posts( + &self, + user: impl EntityRef, + ) -> PagerStream> { + let pager = BackwardPager::new( + self, + endpoint::users::gallery::posts::Request::builder() + .user_id(user.entity_ref()) + .build(), + ); + PagerStream::new(Box::pin(pager)) + } + + /// Lists the gallery posts in the instance. + #[cfg(feature = "12-79-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] + fn all_gallery_posts(&self) -> PagerStream> { + let pager = BackwardPager::new(self, endpoint::gallery::posts::Request::default()); + PagerStream::new(Box::pin(pager)) + } + + /// Lists the featured gallery posts. + #[cfg(feature = "12-79-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] + fn featured_gallery_posts(&self) -> BoxFuture, Error>> { + Box::pin(async move { + let posts = self + .request(endpoint::gallery::featured::Request::default()) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(posts) + }) + } + + /// Lists the popular gallery posts. + #[cfg(feature = "12-79-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] + fn popular_gallery_posts(&self) -> BoxFuture, Error>> { + Box::pin(async move { + let posts = self + .request(endpoint::gallery::popular::Request::default()) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(posts) + }) + } + // }}} + // {{{ Admin /// Sets moderator privileges for the specified user. /// diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 70ef7b15..fe0f9676 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-79-0 = ["misskey-api/12-79-0", "misskey-util/12-79-0"] 12-77-1 = ["misskey-api/12-77-1", "misskey-util/12-77-1"] 12-77-0 = ["misskey-api/12-77-0", "misskey-util/12-77-0"] 12-75-0 = ["misskey-api/12-75-0", "misskey-util/12-75-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 0f0abf93..4467eabd 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-79-0` | v12.79.0 ~ v12.79.1 | v12.79.0 | //! | `12-77-1` | v12.77.1 ~ v12.78.0 | v12.77.1 | //! | `12-77-0` | v12.77.0 | v12.77.0 | //! | `12-75-0` | v12.75.0 ~ v12.76.1 | v12.75.0 | From ea5065d1aaba2570f981adaa0c8ab1b17e8ffde8 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Tue, 11 Apr 2023 19:44:22 +0900 Subject: [PATCH 06/44] Add: Support v12.79.2 --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 3 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/gallery/posts.rs | 8 ++ .../src/endpoint/gallery/posts/delete.rs | 38 ++++++++ .../src/endpoint/gallery/posts/update.rs | 86 +++++++++++++++++++ misskey-util/Cargo.toml | 1 + misskey-util/src/builder.rs | 4 + misskey-util/src/builder/gallery.rs | 84 ++++++++++++++++++ misskey-util/src/client.rs | 33 +++++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 14 files changed, 266 insertions(+), 4 deletions(-) create mode 100644 misskey-api/src/endpoint/gallery/posts/delete.rs create mode 100644 misskey-api/src/endpoint/gallery/posts/update.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7256cd86..96188ac5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.79.0' + MISSKEY_IMAGE: 'misskey/misskey:12.79.2' MISSKEY_ID: aid - - run: cargo test --features 12-79-0 + - run: cargo test --features 12-79-2 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 273c8191..2abbf5fc 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.79.2' + flags: --features 12-79-2 - image: 'misskey/misskey:12.79.0' flags: --features 12-79-0 - image: 'misskey/misskey:12.77.1' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index c49bfe6d..d8a32d63 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.79.0' + MISSKEY_IMAGE: 'misskey/misskey:12.79.2' MISSKEY_ID: aid - - run: cargo test --features 12-79-0 + - run: cargo test --features 12-79-2 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 9615ec21..053450f4 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -34,6 +34,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint `gallery/*` - endpoint `i/gallery/*` - endpoint `users/gallery/posts` +- Support for Misskey v12.79.2 ~ v12.79.3 + - endpoint `gallery/posts/delete` + - endpoint `gallery/posts/update` ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 573c9cf9..639d31e5 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-79-2 = ["12-79-0"] 12-79-0 = ["12-77-1"] 12-77-1 = ["12-77-0"] 12-77-0 = ["12-75-0"] diff --git a/misskey-api/src/endpoint/gallery/posts.rs b/misskey-api/src/endpoint/gallery/posts.rs index 84556bf1..0fbcfafd 100644 --- a/misskey-api/src/endpoint/gallery/posts.rs +++ b/misskey-api/src/endpoint/gallery/posts.rs @@ -8,6 +8,14 @@ pub mod like; pub mod show; pub mod unlike; +#[cfg(feature = "12-79-2")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-79-2")))] +pub mod delete; + +#[cfg(feature = "12-79-2")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-79-2")))] +pub mod update; + #[derive(Serialize, Default, Debug, Clone, TypedBuilder)] #[serde(rename_all = "camelCase")] #[builder(doc)] diff --git a/misskey-api/src/endpoint/gallery/posts/delete.rs b/misskey-api/src/endpoint/gallery/posts/delete.rs new file mode 100644 index 00000000..bf03ed11 --- /dev/null +++ b/misskey-api/src/endpoint/gallery/posts/delete.rs @@ -0,0 +1,38 @@ +use crate::model::{gallery::GalleryPost, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub post_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "gallery/posts/delete"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let url = client.avatar_url().await; + let file = client.upload_from_url(url).await; + + let post = client + .test(crate::endpoint::gallery::posts::create::Request { + title: "gallery post".to_string(), + description: None, + file_ids: vec![file.id], + is_sensitive: None, + }) + .await; + + client.test(Request { post_id: post.id }).await; + } +} diff --git a/misskey-api/src/endpoint/gallery/posts/update.rs b/misskey-api/src/endpoint/gallery/posts/update.rs new file mode 100644 index 00000000..51b74685 --- /dev/null +++ b/misskey-api/src/endpoint/gallery/posts/update.rs @@ -0,0 +1,86 @@ +use crate::model::{drive::DriveFile, gallery::GalleryPost, id::Id}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + pub post_id: Id, + /// [ 1 .. ] characters + #[builder(default, setter(into))] + pub title: String, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option, into))] + pub description: Option, + /// [ 1 .. 32 ] ids + #[builder(default, setter(into))] + pub file_ids: Vec>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option, into))] + pub is_sensitive: Option, +} + +impl misskey_core::Request for Request { + type Response = GalleryPost; + const ENDPOINT: &'static str = "gallery/posts/update"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let url = client.avatar_url().await; + let file = client.upload_from_url(url).await; + + let post = client + .test(crate::endpoint::gallery::posts::create::Request { + title: "gallery post".to_string(), + description: None, + file_ids: vec![file.id], + is_sensitive: None, + }) + .await; + + client + .test(Request { + post_id: post.id, + title: "updated".to_string(), + description: None, + file_ids: vec![file.id], + is_sensitive: None, + }) + .await; + } + + #[tokio::test] + async fn request_with_options() { + let client = TestClient::new(); + let url = client.avatar_url().await; + let file = client.upload_from_url(url).await; + + let post = client + .test(crate::endpoint::gallery::posts::create::Request { + title: "gallery post".to_string(), + description: None, + file_ids: vec![file.id], + is_sensitive: None, + }) + .await; + + client + .test(Request { + post_id: post.id, + title: "updated".to_string(), + description: Some("description".to_string()), + file_ids: vec![file.id], + is_sensitive: Some(true), + }) + .await; + } +} diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 0d14da3e..73e3e334 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-79-2 = ["misskey-api/12-79-2", "12-79-0"] 12-79-0 = ["misskey-api/12-79-0", "12-77-1"] 12-77-1 = ["misskey-api/12-77-1", "12-77-0"] 12-77-0 = ["misskey-api/12-77-0", "12-75-0"] diff --git a/misskey-util/src/builder.rs b/misskey-util/src/builder.rs index 88be5bfe..2ce061f6 100644 --- a/misskey-util/src/builder.rs +++ b/misskey-util/src/builder.rs @@ -51,3 +51,7 @@ pub use misc::NotificationBuilder; #[cfg(feature = "12-79-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] pub use gallery::GalleryPostBuilder; + +#[cfg(feature = "12-79-2")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-79-2")))] +pub use gallery::GalleryPostUpdateBuilder; diff --git a/misskey-util/src/builder/gallery.rs b/misskey-util/src/builder/gallery.rs index c5558ea9..b68e13a7 100644 --- a/misskey-util/src/builder/gallery.rs +++ b/misskey-util/src/builder/gallery.rs @@ -74,3 +74,87 @@ impl GalleryPostBuilder { Ok(post) } } + +#[cfg(feature = "12-79-2")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-79-2")))] +/// Builder for the [`update_gallery_post`][`crate::ClientExt::update_gallery_post`] method. +pub struct GalleryPostUpdateBuilder { + client: C, + request: endpoint::gallery::posts::update::Request, +} + +#[cfg(feature = "12-79-2")] +impl GalleryPostUpdateBuilder { + /// Creates a builder with the client and the post you are going to update. + pub fn new(client: C, post: GalleryPost) -> Self { + let GalleryPost { + id, + title, + description, + file_ids, + is_sensitive, + .. + } = post; + let request = endpoint::gallery::posts::update::Request { + post_id: id, + title, + description, + file_ids, + is_sensitive: Some(is_sensitive), + }; + GalleryPostUpdateBuilder { client, request } + } + + /// Gets the request object for reuse. + pub fn as_request(&self) -> &endpoint::gallery::posts::update::Request { + &self.request + } + + /// Sets the title of the post. + pub fn title(&mut self, title: impl Into) -> &mut Self { + self.request.title = title.into(); + self + } + + /// Sets the description of the post. + pub fn description(&mut self, description: impl Into) -> &mut Self { + self.request.description.replace(description.into()); + self + } + + /// Sets the files of the post. + pub fn files( + &mut self, + files: impl IntoIterator>, + ) -> &mut Self { + let ids = files.into_iter().map(|file| file.entity_ref()); + self.request.file_ids = ids.collect(); + self + } + + /// Adds a file to the post. + pub fn add_file(&mut self, file: impl EntityRef) -> &mut Self { + self.request.file_ids.push(file.entity_ref()); + self + } + + /// Sets whether the post contains NSFW content. + pub fn sensitive(&mut self, sensitive: bool) -> &mut Self { + self.request.is_sensitive.replace(sensitive); + self + } +} + +#[cfg(feature = "12-79-2")] +impl GalleryPostUpdateBuilder { + /// Updates the post. + pub async fn update(&self) -> Result> { + let post = self + .client + .request(&self.request) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(post) + } +} diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index 06f05de4..b0ab9837 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -6,6 +6,8 @@ use std::path::Path; use crate::builder::EmojiUpdateBuilder; #[cfg(feature = "12-79-0")] use crate::builder::GalleryPostBuilder; +#[cfg(feature = "12-79-2")] +use crate::builder::GalleryPostUpdateBuilder; #[cfg(feature = "12-27-0")] use crate::builder::NotificationBuilder; use crate::builder::{ @@ -3288,6 +3290,23 @@ pub trait ClientExt: Client + Sync { GalleryPostBuilder::new(self) } + /// Deletes the specified gallery post. + #[cfg(feature = "12-79-2")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-79-2")))] + fn delete_gallery_post( + &self, + post: impl EntityRef, + ) -> BoxFuture>> { + let post_id = post.entity_ref(); + Box::pin(async move { + self.request(endpoint::gallery::posts::delete::Request { post_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + /// Gets the corresponding gallery post from the ID. #[cfg(feature = "12-79-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] @@ -3305,6 +3324,20 @@ pub trait ClientExt: Client + Sync { }) } + /// Updates the gallery post. + /// + /// This method actually returns a builder, namely [`GalleryPostUpdateBuilder`]. + /// You can chain the method calls to it corresponding to the fields you want to update. + /// Finally, calling [`update`][builder_update] method will actually perform the update. + /// See [`GalleryPostUpdateBuilder`] for the fields that can be updated. + /// + /// [builder_update]: GalleryPostUpdateBuilder::update + #[cfg(feature = "12-79-2")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-79-2")))] + fn update_gallery_post(&self, post: GalleryPost) -> GalleryPostUpdateBuilder<&Self> { + GalleryPostUpdateBuilder::new(self, post) + } + /// Gives a like to the specified gallery post. #[cfg(feature = "12-79-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index fe0f9676..a6c903c0 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-79-2 = ["misskey-api/12-79-2", "misskey-util/12-79-2"] 12-79-0 = ["misskey-api/12-79-0", "misskey-util/12-79-0"] 12-77-1 = ["misskey-api/12-77-1", "misskey-util/12-77-1"] 12-77-0 = ["misskey-api/12-77-0", "misskey-util/12-77-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 4467eabd..afe7e624 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-79-2` | v12.79.2 ~ v12.79.3 | v12.79.2 | //! | `12-79-0` | v12.79.0 ~ v12.79.1 | v12.79.0 | //! | `12-77-1` | v12.77.1 ~ v12.78.0 | v12.77.1 | //! | `12-77-0` | v12.77.0 | v12.77.0 | From fca0ce5190fc4f5d8fc684a4259350946e080402 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 12 Apr 2023 01:07:51 +0900 Subject: [PATCH 07/44] Add: Partially support v12.80.0 endpoint `request-reset-password` and `reset-password` are not supported --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 2 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/admin.rs | 4 + misskey-api/src/endpoint/admin/ad.rs | 4 + misskey-api/src/endpoint/admin/ad/create.rs | 58 +++++ misskey-api/src/endpoint/admin/ad/delete.rs | 44 ++++ misskey-api/src/endpoint/admin/ad/list.rs | 80 +++++++ misskey-api/src/endpoint/admin/ad/update.rs | 79 +++++++ misskey-api/src/model.rs | 1 + misskey-api/src/model/ad.rs | 95 +++++++++ misskey-util/Cargo.toml | 1 + misskey-util/src/builder.rs | 4 + misskey-util/src/builder/admin.rs | 225 ++++++++++++++++++++ misskey-util/src/client.rs | 78 +++++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 19 files changed, 684 insertions(+), 4 deletions(-) create mode 100644 misskey-api/src/endpoint/admin/ad.rs create mode 100644 misskey-api/src/endpoint/admin/ad/create.rs create mode 100644 misskey-api/src/endpoint/admin/ad/delete.rs create mode 100644 misskey-api/src/endpoint/admin/ad/list.rs create mode 100644 misskey-api/src/endpoint/admin/ad/update.rs create mode 100644 misskey-api/src/model/ad.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96188ac5..482c795b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.79.2' + MISSKEY_IMAGE: 'misskey/misskey:12.80.0' MISSKEY_ID: aid - - run: cargo test --features 12-79-2 + - run: cargo test --features 12-80-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 2abbf5fc..3235808b 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.80.0' + flags: --features 12-80-0 - image: 'misskey/misskey:12.79.2' flags: --features 12-79-2 - image: 'misskey/misskey:12.79.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index d8a32d63..8f7c7a3a 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.79.2' + MISSKEY_IMAGE: 'misskey/misskey:12.80.0' MISSKEY_ID: aid - - run: cargo test --features 12-79-2 + - run: cargo test --features 12-80-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 053450f4..eed3c232 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -37,6 +37,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.79.2 ~ v12.79.3 - endpoint `gallery/posts/delete` - endpoint `gallery/posts/update` +- Partial support for Misskey v12.80.0 ~ v12.80.3 + - endpoint `admin/ad/*` ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 639d31e5..1029113c 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-80-0 = ["12-79-2"] 12-79-2 = ["12-79-0"] 12-79-0 = ["12-77-1"] 12-77-1 = ["12-77-0"] diff --git a/misskey-api/src/endpoint/admin.rs b/misskey-api/src/endpoint/admin.rs index 9cf376c5..94ecbd7c 100644 --- a/misskey-api/src/endpoint/admin.rs +++ b/misskey-api/src/endpoint/admin.rs @@ -31,3 +31,7 @@ pub mod remove_abuse_user_report; #[cfg(feature = "12-49-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-49-0")))] pub mod resolve_abuse_user_report; + +#[cfg(feature = "12-80-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] +pub mod ad; diff --git a/misskey-api/src/endpoint/admin/ad.rs b/misskey-api/src/endpoint/admin/ad.rs new file mode 100644 index 00000000..ffd48daf --- /dev/null +++ b/misskey-api/src/endpoint/admin/ad.rs @@ -0,0 +1,4 @@ +pub mod create; +pub mod delete; +pub mod list; +pub mod update; diff --git a/misskey-api/src/endpoint/admin/ad/create.rs b/misskey-api/src/endpoint/admin/ad/create.rs new file mode 100644 index 00000000..bb3ab63a --- /dev/null +++ b/misskey-api/src/endpoint/admin/ad/create.rs @@ -0,0 +1,58 @@ +use chrono::{serde::ts_milliseconds, DateTime, Utc}; +use serde::Serialize; +use typed_builder::TypedBuilder; + +use crate::model::ad::{Place, Priority}; + +#[derive(Serialize, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + /// [ 1 .. ] characters + #[builder(setter(into))] + pub url: String, + #[builder(default, setter(into))] + pub memo: String, + #[builder(default)] + pub place: Place, + #[builder(default)] + pub priority: Priority, + #[serde(with = "ts_milliseconds")] + #[builder(setter(into))] + pub expires_at: DateTime, + /// [ 1 .. ] characters + #[builder(setter(into))] + pub image_url: String, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/ad/create"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::{ + model::ad::{Place, Priority}, + test::{ClientExt, TestClient}, + }; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let url = client.avatar_url().await; + + client + .admin + .test(Request { + url: url.to_string(), + memo: "memo".to_string(), + place: Place::Square, + priority: Priority::Middle, + image_url: url.to_string(), + expires_at: chrono::Utc::now() + chrono::Duration::hours(1), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/admin/ad/delete.rs b/misskey-api/src/endpoint/admin/ad/delete.rs new file mode 100644 index 00000000..11fb315b --- /dev/null +++ b/misskey-api/src/endpoint/admin/ad/delete.rs @@ -0,0 +1,44 @@ +use crate::model::{ad::Ad, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/ad/delete"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let url = client.avatar_url().await; + + client + .admin + .test( + crate::endpoint::admin::ad::create::Request::builder() + .url(url.clone()) + .image_url(url.clone()) + .expires_at(chrono::Utc::now() + chrono::Duration::hours(1)) + .build(), + ) + .await; + + let ads = client + .admin + .test(crate::endpoint::admin::ad::list::Request::default()) + .await; + + client.admin.test(Request { id: ads[0].id }).await; + } +} diff --git a/misskey-api/src/endpoint/admin/ad/list.rs b/misskey-api/src/endpoint/admin/ad/list.rs new file mode 100644 index 00000000..0b3f79bc --- /dev/null +++ b/misskey-api/src/endpoint/admin/ad/list.rs @@ -0,0 +1,80 @@ +use crate::model::{ad::Ad, id::Id}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Default, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + /// 1 .. 100 + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub since_id: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub until_id: Option>, +} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "admin/ad/list"; +} + +impl_pagination!(Request, Ad); + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.admin.test(Request::default()).await; + } + + #[tokio::test] + async fn request_with_limit() { + let client = TestClient::new(); + + client + .admin + .test(Request { + limit: Some(100), + since_id: None, + until_id: None, + }) + .await; + } + + #[tokio::test] + async fn request_paginate() { + let client = TestClient::new(); + let url = client.avatar_url().await; + client + .admin + .test( + crate::endpoint::admin::ad::create::Request::builder() + .url(url.clone()) + .image_url(url.clone()) + .expires_at(chrono::Utc::now() + chrono::Duration::hours(1)) + .build(), + ) + .await; + + let ads = client.admin.test(Request::default()).await; + + client + .admin + .test(Request { + limit: None, + since_id: Some(ads[0].id.clone()), + until_id: Some(ads[0].id.clone()), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/admin/ad/update.rs b/misskey-api/src/endpoint/admin/ad/update.rs new file mode 100644 index 00000000..20f45206 --- /dev/null +++ b/misskey-api/src/endpoint/admin/ad/update.rs @@ -0,0 +1,79 @@ +use chrono::{serde::ts_milliseconds, DateTime, Utc}; +use serde::Serialize; +use typed_builder::TypedBuilder; + +use crate::model::{ + ad::{Ad, Place, Priority}, + id::Id, +}; + +#[derive(Serialize, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + pub id: Id, + #[builder(default, setter(into))] + pub memo: String, + /// [ 1 .. ] characters + #[builder(setter(into))] + pub url: String, + /// [ 1 .. ] characters + #[builder(setter(into))] + pub image_url: String, + #[builder(default)] + pub place: Place, + #[builder(default)] + pub priority: Priority, + #[serde(with = "ts_milliseconds")] + #[builder(setter(into))] + pub expires_at: DateTime, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/ad/update"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::{ + model::ad::{Place, Priority}, + test::{ClientExt, TestClient}, + }; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let url = client.avatar_url().await; + + client + .admin + .test( + crate::endpoint::admin::ad::create::Request::builder() + .url(url.clone()) + .image_url(url.clone()) + .expires_at(chrono::Utc::now() + chrono::Duration::hours(1)) + .build(), + ) + .await; + + let ads = client + .admin + .test(crate::endpoint::admin::ad::list::Request::default()) + .await; + + client + .admin + .test(Request { + id: ads[0].id, + url: url.to_string(), + memo: "memo".to_string(), + place: Place::Horizontal, + priority: Priority::High, + image_url: url.to_string(), + expires_at: chrono::Utc::now() + chrono::Duration::hours(2), + }) + .await; + } +} diff --git a/misskey-api/src/model.rs b/misskey-api/src/model.rs index cc5fb7da..90eca0fd 100644 --- a/misskey-api/src/model.rs +++ b/misskey-api/src/model.rs @@ -17,6 +17,7 @@ macro_rules! impl_entity { } pub mod abuse_user_report; +pub mod ad; pub mod announcement; pub mod antenna; pub mod blocking; diff --git a/misskey-api/src/model/ad.rs b/misskey-api/src/model/ad.rs new file mode 100644 index 00000000..0fdf9704 --- /dev/null +++ b/misskey-api/src/model/ad.rs @@ -0,0 +1,95 @@ +use std::fmt::{self, Display}; + +use crate::model::id::Id; + +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Ad { + pub id: Id, + pub created_at: DateTime, + pub expires_at: DateTime, + pub place: Place, + pub priority: Priority, + pub url: String, + pub image_url: String, + pub memo: String, +} + +impl_entity!(Ad); + +#[derive(Serialize, Deserialize, Default, PartialEq, Eq, Clone, Debug, Copy)] +#[serde(rename_all = "camelCase")] +pub enum Place { + #[default] + Square, + Horizontal, +} + +impl Display for Place { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Place::Square => f.write_str("square"), + Place::Horizontal => f.write_str("horizontal"), + } + } +} + +#[derive(Debug, Error, Clone)] +#[error("invalid place")] +pub struct ParsePlaceError { + _priv: (), +} + +impl std::str::FromStr for Place { + type Err = ParsePlaceError; + + fn from_str(s: &str) -> Result { + match s { + "square" | "Square" => Ok(Place::Square), + "horizontal" | "Horizontal" => Ok(Place::Horizontal), + _ => Err(ParsePlaceError { _priv: () }), + } + } +} + +#[derive(Serialize, Deserialize, Default, PartialEq, Eq, Clone, Debug, Copy)] +#[serde(rename_all = "camelCase")] +pub enum Priority { + High, + #[default] + Middle, + Low, +} + +impl Display for Priority { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Priority::High => f.write_str("high"), + Priority::Middle => f.write_str("middle"), + Priority::Low => f.write_str("low"), + } + } +} + +#[derive(Debug, Error, Clone)] +#[error("invalid priority")] +pub struct ParsePriorityError { + _priv: (), +} + +impl std::str::FromStr for Priority { + type Err = ParsePriorityError; + + fn from_str(s: &str) -> Result { + match s { + "high" | "High" => Ok(Priority::High), + "middle" | "Middle" => Ok(Priority::Middle), + "low" | "Low" => Ok(Priority::Low), + _ => Err(ParsePriorityError { _priv: () }), + } + } +} diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 73e3e334..cbafc7ef 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-80-0 = ["misskey-api/12-80-0", "12-79-2"] 12-79-2 = ["misskey-api/12-79-2", "12-79-0"] 12-79-0 = ["misskey-api/12-79-0", "12-77-1"] 12-77-1 = ["misskey-api/12-77-1", "12-77-0"] diff --git a/misskey-util/src/builder.rs b/misskey-util/src/builder.rs index 2ce061f6..4b19cf88 100644 --- a/misskey-util/src/builder.rs +++ b/misskey-util/src/builder.rs @@ -55,3 +55,7 @@ pub use gallery::GalleryPostBuilder; #[cfg(feature = "12-79-2")] #[cfg_attr(docsrs, doc(cfg(feature = "12-79-2")))] pub use gallery::GalleryPostUpdateBuilder; + +#[cfg(feature = "12-80-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] +pub use admin::{AdBuilder, AdUpdateBuilder}; diff --git a/misskey-util/src/builder/admin.rs b/misskey-util/src/builder/admin.rs index 41115bd1..3807a0df 100644 --- a/misskey-util/src/builder/admin.rs +++ b/misskey-util/src/builder/admin.rs @@ -1,5 +1,9 @@ use crate::Error; +#[cfg(feature = "12-80-0")] +use chrono::{DateTime, Utc}; +#[cfg(feature = "12-80-0")] +use misskey_api::model::ad::{Ad, Place, Priority}; #[cfg(feature = "12-62-0")] use misskey_api::model::clip::Clip; #[cfg(feature = "12-9-0")] @@ -554,3 +558,224 @@ impl EmojiUpdateBuilder { Ok(()) } } + +#[cfg(feature = "12-80-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] +/// Builder for the [`build_ad`][`crate::ClientExt::build_ad`] method. +pub struct AdBuilder { + client: C, + request: endpoint::admin::ad::create::Request, +} + +#[cfg(feature = "12-80-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] +impl AdBuilder { + /// Creates a builder with the client. + pub fn new(client: C) -> Self { + let request = endpoint::admin::ad::create::Request { + url: String::default(), + memo: String::default(), + place: Place::default(), + priority: Priority::default(), + expires_at: DateTime::default(), + image_url: String::default(), + }; + AdBuilder { client, request } + } + + /// Gets the request object for reuse. + pub fn as_request(&self) -> &endpoint::admin::ad::create::Request { + &self.request + } + + /// Sets the url of the ad. + pub fn url(&mut self, url: impl Into) -> &mut Self { + self.request.url = url.into(); + self + } + + /// Sets the memo of the ad. + pub fn memo(&mut self, memo: impl Into) -> &mut Self { + self.request.memo = memo.into(); + self + } + + /// Sets the place of the ad. + pub fn place(&mut self, place: Place) -> &mut Self { + self.request.place = place; + self + } + + /// Sets the place of the ad to square. + pub fn square(&mut self) -> &mut Self { + self.place(Place::Square) + } + + /// Sets the place of the ad to horizontal. + pub fn horizontal(&mut self) -> &mut Self { + self.place(Place::Horizontal) + } + + /// Sets the priority of the ad. + pub fn priority(&mut self, priority: Priority) -> &mut Self { + self.request.priority = priority; + self + } + + /// Sets the priority of the ad to high. + pub fn high_priority(&mut self) -> &mut Self { + self.priority(Priority::High) + } + + /// Sets the priority of the ad to middle. + pub fn middle_priority(&mut self) -> &mut Self { + self.priority(Priority::Middle) + } + + /// Sets the priority of the ad to low. + pub fn low_priority(&mut self) -> &mut Self { + self.priority(Priority::Low) + } + + /// Sets the expiration date of the ad. + pub fn expires_at(&mut self, expires_at: impl Into>) -> &mut Self { + self.request.expires_at = expires_at.into(); + self + } + + /// Sets the image url of the ad. + pub fn image_url(&mut self, image_url: impl Into) -> &mut Self { + self.request.image_url = image_url.into(); + self + } +} + +#[cfg(feature = "12-80-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] +impl AdBuilder { + /// Creates the ad. + pub async fn create(&self) -> Result<(), Error> { + self.client + .request(&self.request) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + } +} + +#[cfg(feature = "12-80-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] +/// Builder for the [`update_ad`][`crate::ClientExt::update_ad`] method. +pub struct AdUpdateBuilder { + client: C, + request: endpoint::admin::ad::update::Request, +} + +#[cfg(feature = "12-80-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] +impl AdUpdateBuilder { + /// Creates a builder with the client. + pub fn new(client: C, ad: Ad) -> Self { + let Ad { + id, + expires_at, + place, + priority, + url, + image_url, + memo, + .. + } = ad; + let request = endpoint::admin::ad::update::Request { + id, + url, + memo, + place, + priority, + expires_at, + image_url, + }; + AdUpdateBuilder { client, request } + } + + /// Gets the request object for reuse. + pub fn as_request(&self) -> &endpoint::admin::ad::update::Request { + &self.request + } + + /// Sets the url of the ad. + pub fn url(&mut self, url: impl Into) -> &mut Self { + self.request.url = url.into(); + self + } + + /// Sets the memo of the ad. + pub fn memo(&mut self, memo: impl Into) -> &mut Self { + self.request.memo = memo.into(); + self + } + + /// Sets the place of the ad. + pub fn place(&mut self, place: Place) -> &mut Self { + self.request.place = place; + self + } + + /// Sets the place of the ad to square. + pub fn square(&mut self) -> &mut Self { + self.place(Place::Square) + } + + /// Sets the place of the ad to horizontal. + pub fn horizontal(&mut self) -> &mut Self { + self.place(Place::Horizontal) + } + + /// Sets the priority of the ad. + pub fn priority(&mut self, priority: Priority) -> &mut Self { + self.request.priority = priority; + self + } + + /// Sets the priority of the ad to high. + pub fn high_priority(&mut self) -> &mut Self { + self.priority(Priority::High) + } + + /// Sets the priority of the ad to middle. + pub fn middle_priority(&mut self) -> &mut Self { + self.priority(Priority::Middle) + } + + /// Sets the priority of the ad to low. + pub fn low_priority(&mut self) -> &mut Self { + self.priority(Priority::Low) + } + + /// Sets the expiration date of the ad. + pub fn expires_at(&mut self, expires_at: impl Into>) -> &mut Self { + self.request.expires_at = expires_at.into(); + self + } + + /// Sets the image url of the ad. + pub fn image_url(&mut self, image_url: impl Into) -> &mut Self { + self.request.image_url = image_url.into(); + self + } +} + +#[cfg(feature = "12-80-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] +impl AdUpdateBuilder { + /// Updates the ad. + pub async fn update(&self) -> Result<(), Error> { + self.client + .request(&self.request) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + } +} diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index b0ab9837..aae4a555 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -10,6 +10,8 @@ use crate::builder::GalleryPostBuilder; use crate::builder::GalleryPostUpdateBuilder; #[cfg(feature = "12-27-0")] use crate::builder::NotificationBuilder; +#[cfg(feature = "12-80-0")] +use crate::builder::{AdBuilder, AdUpdateBuilder}; use crate::builder::{ AnnouncementUpdateBuilder, AntennaBuilder, AntennaUpdateBuilder, DriveFileBuilder, DriveFileListBuilder, DriveFileUpdateBuilder, DriveFileUrlBuilder, DriveFolderUpdateBuilder, @@ -29,6 +31,8 @@ use chrono::DateTime; use chrono::Utc; use futures::{future::BoxFuture, stream::TryStreamExt}; use mime::Mime; +#[cfg(feature = "12-80-0")] +use misskey_api::model::ad::Ad; #[cfg(feature = "12-47-0")] use misskey_api::model::channel::Channel; #[cfg(feature = "12-79-0")] @@ -3858,6 +3862,80 @@ pub trait ClientExt: Client + Sync { ); PagerStream::new(Box::pin(pager)) } + + /// Creates an ad from the given urls. + /// + /// This operation may require moderator privileges. + #[cfg(feature = "12-80-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] + fn create_ad( + &self, + url: impl Into, + image_url: impl Into, + ) -> BoxFuture>> { + let url = url.into(); + let image_url = image_url.into(); + Box::pin(async move { self.build_ad().url(url).image_url(image_url).create().await }) + } + + /// Returns a builder for creating an ad. + /// + /// This method actually returns a builder, namely [`AdBuilder`]. + /// You can chain the method calls to it corresponding to the fields you want to update. + /// Finally, calling [`create`][builder_create] method will actually perform the update. + /// See [`AdBuilder`] for the fields that can be updated. + /// + /// This operation may require moderator privileges. + /// + /// [builder_create]: AdBuilder::create + #[cfg(feature = "12-80-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] + fn build_ad(&self) -> AdBuilder<&Self> { + AdBuilder::new(self) + } + + /// Deletes the specified ad. + /// + /// This operation may require moderator privileges. + #[cfg(feature = "12-80-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] + fn delete_ad(&self, ad: impl EntityRef) -> BoxFuture>> { + let ad_id = ad.entity_ref(); + Box::pin(async move { + self.request(endpoint::admin::ad::delete::Request { id: ad_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + + /// Updates the specified ad. + /// + /// This method actually returns a builder, namely [`AdUpdateBuilder`]. + /// You can chain the method calls to it corresponding to the fields you want to update. + /// Finally, calling [`update`][builder_update] method will actually perform the update. + /// See [`AdUpdateBuilder`] for the fields that can be updated. + /// + /// This operation may require moderator privileges. + /// + /// [builder_update]: AdUpdateBuilder::update + #[cfg(feature = "12-80-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] + fn update_ad(&self, ad: Ad) -> AdUpdateBuilder<&Self> { + AdUpdateBuilder::new(self, ad) + } + + /// Lists the ads in the instance. + /// + /// This operation may require moderator privileges. + /// Use [`meta`][`ClientExt::meta`] method if you want to get a list of ads from normal users, + #[cfg(feature = "12-80-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] + fn ads(&self) -> PagerStream> { + let pager = BackwardPager::new(self, endpoint::admin::ad::list::Request::default()); + PagerStream::new(Box::pin(pager)) + } // }}} // {{{ Miscellaneous diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index a6c903c0..4b97d108 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-80-0 = ["misskey-api/12-80-0", "misskey-util/12-80-0"] 12-79-2 = ["misskey-api/12-79-2", "misskey-util/12-79-2"] 12-79-0 = ["misskey-api/12-79-0", "misskey-util/12-79-0"] 12-77-1 = ["misskey-api/12-77-1", "misskey-util/12-77-1"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index afe7e624..1befb02d 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-80-0` | v12.80.0 ~ v12.80.3 | v12.80.0 | //! | `12-79-2` | v12.79.2 ~ v12.79.3 | v12.79.2 | //! | `12-79-0` | v12.79.0 ~ v12.79.1 | v12.79.0 | //! | `12-77-1` | v12.77.1 ~ v12.78.0 | v12.77.1 | From 0e8bb73e8e330f566ecf69bfefa25742440e30a1 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 12 Apr 2023 02:22:38 +0900 Subject: [PATCH 08/44] Add: Support v12.81.0 --- .github/workflows/ci.yml | 4 +-- .github/workflows/flaky.yml | 2 ++ .github/workflows/unstable.yml | 4 +-- misskey-api/CHANGELOG.md | 2 ++ misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/admin.rs | 4 +++ misskey-api/src/endpoint/admin/ad/create.rs | 6 ++++ misskey-api/src/endpoint/admin/ad/update.rs | 6 ++++ .../src/endpoint/admin/get_index_stats.rs | 29 +++++++++++++++ misskey-api/src/model/ad.rs | 12 ++++++- misskey-api/src/model/meta.rs | 17 +++++++++ misskey-util/Cargo.toml | 1 + misskey-util/src/builder/admin.rs | 36 +++++++++++++++++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 15 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 misskey-api/src/endpoint/admin/get_index_stats.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 482c795b..96e402f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.80.0' + MISSKEY_IMAGE: 'misskey/misskey:12.81.0' MISSKEY_ID: aid - - run: cargo test --features 12-80-0 + - run: cargo test --features 12-81-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 3235808b..5edf8edc 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.81.0' + flags: --features 12-81-0 - image: 'misskey/misskey:12.80.0' flags: --features 12-80-0 - image: 'misskey/misskey:12.79.2' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 8f7c7a3a..3749556b 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.80.0' + MISSKEY_IMAGE: 'misskey/misskey:12.81.0' MISSKEY_ID: aid - - run: cargo test --features 12-80-0 + - run: cargo test --features 12-81-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index eed3c232..0cb6bf23 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -39,6 +39,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint `gallery/posts/update` - Partial support for Misskey v12.80.0 ~ v12.80.3 - endpoint `admin/ad/*` +- Support for Misskey v12.81.0 ~ 12.81.2 + - endpoint `admin/get-index-stats` ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 1029113c..3d97c076 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-81-0 = ["12-80-0"] 12-80-0 = ["12-79-2"] 12-79-2 = ["12-79-0"] 12-79-0 = ["12-77-1"] diff --git a/misskey-api/src/endpoint/admin.rs b/misskey-api/src/endpoint/admin.rs index 94ecbd7c..bf5fd769 100644 --- a/misskey-api/src/endpoint/admin.rs +++ b/misskey-api/src/endpoint/admin.rs @@ -35,3 +35,7 @@ pub mod resolve_abuse_user_report; #[cfg(feature = "12-80-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] pub mod ad; + +#[cfg(feature = "12-81-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] +pub mod get_index_stats; diff --git a/misskey-api/src/endpoint/admin/ad/create.rs b/misskey-api/src/endpoint/admin/ad/create.rs index bb3ab63a..3831dcda 100644 --- a/misskey-api/src/endpoint/admin/ad/create.rs +++ b/misskey-api/src/endpoint/admin/ad/create.rs @@ -17,6 +17,10 @@ pub struct Request { pub place: Place, #[builder(default)] pub priority: Priority, + #[cfg(feature = "12-81-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] + #[builder(default, setter(into))] + pub ratio: u64, #[serde(with = "ts_milliseconds")] #[builder(setter(into))] pub expires_at: DateTime, @@ -50,6 +54,8 @@ mod tests { memo: "memo".to_string(), place: Place::Square, priority: Priority::Middle, + #[cfg(feature = "12-81-0")] + ratio: 1, image_url: url.to_string(), expires_at: chrono::Utc::now() + chrono::Duration::hours(1), }) diff --git a/misskey-api/src/endpoint/admin/ad/update.rs b/misskey-api/src/endpoint/admin/ad/update.rs index 20f45206..667b2bdb 100644 --- a/misskey-api/src/endpoint/admin/ad/update.rs +++ b/misskey-api/src/endpoint/admin/ad/update.rs @@ -24,6 +24,10 @@ pub struct Request { pub place: Place, #[builder(default)] pub priority: Priority, + #[cfg(feature = "12-81-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] + #[builder(default, setter(into))] + pub ratio: u64, #[serde(with = "ts_milliseconds")] #[builder(setter(into))] pub expires_at: DateTime, @@ -71,6 +75,8 @@ mod tests { memo: "memo".to_string(), place: Place::Horizontal, priority: Priority::High, + #[cfg(feature = "12-81-0")] + ratio: 2, image_url: url.to_string(), expires_at: chrono::Utc::now() + chrono::Duration::hours(2), }) diff --git a/misskey-api/src/endpoint/admin/get_index_stats.rs b/misskey-api/src/endpoint/admin/get_index_stats.rs new file mode 100644 index 00000000..c638c6fb --- /dev/null +++ b/misskey-api/src/endpoint/admin/get_index_stats.rs @@ -0,0 +1,29 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Default, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request {} + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Stat { + pub tablename: String, + pub indexname: String, +} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "admin/get-index-stats"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.admin.test(Request::default()).await; + } +} diff --git a/misskey-api/src/model/ad.rs b/misskey-api/src/model/ad.rs index 0fdf9704..252315be 100644 --- a/misskey-api/src/model/ad.rs +++ b/misskey-api/src/model/ad.rs @@ -14,6 +14,9 @@ pub struct Ad { pub expires_at: DateTime, pub place: Place, pub priority: Priority, + #[cfg(feature = "12-81-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] + pub ratio: u64, pub url: String, pub image_url: String, pub memo: String, @@ -22,11 +25,14 @@ pub struct Ad { impl_entity!(Ad); #[derive(Serialize, Deserialize, Default, PartialEq, Eq, Clone, Debug, Copy)] -#[serde(rename_all = "camelCase")] +#[serde(rename_all = "kebab-case")] pub enum Place { #[default] Square, Horizontal, + #[cfg(feature = "12-81-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] + HorizontalBig, } impl Display for Place { @@ -34,6 +40,8 @@ impl Display for Place { match self { Place::Square => f.write_str("square"), Place::Horizontal => f.write_str("horizontal"), + #[cfg(feature = "12-81-0")] + Place::HorizontalBig => f.write_str("horizontal-big"), } } } @@ -51,6 +59,8 @@ impl std::str::FromStr for Place { match s { "square" | "Square" => Ok(Place::Square), "horizontal" | "Horizontal" => Ok(Place::Horizontal), + #[cfg(feature = "12-81-0")] + "horizontal-big" | "Horizontal-big" => Ok(Place::HorizontalBig), _ => Err(ParsePlaceError { _priv: () }), } } diff --git a/misskey-api/src/model/meta.rs b/misskey-api/src/model/meta.rs index 058a7eb3..45ba38ea 100644 --- a/misskey-api/src/model/meta.rs +++ b/misskey-api/src/model/meta.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "12-81-0")] +use crate::model::ad::{Ad, Place}; #[cfg(feature = "12-62-0")] use crate::model::clip::Clip; use crate::model::{emoji::Emoji, id::Id, user::User}; @@ -54,6 +56,9 @@ pub struct Meta { pub icon_url: Option, pub max_note_text_length: u64, pub emojis: Vec, + #[cfg(feature = "12-81-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] + pub ads: Vec, /// This field is [`bool`] (i.e. not [`Option`]) on non-feature="12-58-0". #[cfg(feature = "12-58-0")] pub require_setup: Option, @@ -88,6 +93,18 @@ pub struct Meta { pub pinned_clip_id: Option>, } +#[cfg(feature = "12-81-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] +#[derive(Deserialize, Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct MetaAd { + pub id: Id, + pub url: String, + pub place: Place, + pub ratio: u64, + pub image_url: String, +} + #[derive(Deserialize, Serialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct AdminMeta { diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index cbafc7ef..55ed832a 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-81-0 = ["misskey-api/12-81-0", "12-80-0"] 12-80-0 = ["misskey-api/12-80-0", "12-79-2"] 12-79-2 = ["misskey-api/12-79-2", "12-79-0"] 12-79-0 = ["misskey-api/12-79-0", "12-77-1"] diff --git a/misskey-util/src/builder/admin.rs b/misskey-util/src/builder/admin.rs index 3807a0df..9231121e 100644 --- a/misskey-util/src/builder/admin.rs +++ b/misskey-util/src/builder/admin.rs @@ -577,6 +577,8 @@ impl AdBuilder { memo: String::default(), place: Place::default(), priority: Priority::default(), + #[cfg(feature = "12-81-0")] + ratio: 1, expires_at: DateTime::default(), image_url: String::default(), }; @@ -616,6 +618,13 @@ impl AdBuilder { self.place(Place::Horizontal) } + #[cfg(feature = "12-81-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] + /// Sets the place of the ad to horizontal-big. + pub fn horizontal_big(&mut self) -> &mut Self { + self.place(Place::HorizontalBig) + } + /// Sets the priority of the ad. pub fn priority(&mut self, priority: Priority) -> &mut Self { self.request.priority = priority; @@ -637,6 +646,14 @@ impl AdBuilder { self.priority(Priority::Low) } + #[cfg(feature = "12-81-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] + /// Sets the ratio of the ad. + pub fn ratio(&mut self, ratio: u64) -> &mut Self { + self.request.ratio = ratio; + self + } + /// Sets the expiration date of the ad. pub fn expires_at(&mut self, expires_at: impl Into>) -> &mut Self { self.request.expires_at = expires_at.into(); @@ -682,6 +699,8 @@ impl AdUpdateBuilder { expires_at, place, priority, + #[cfg(feature = "12-81-0")] + ratio, url, image_url, memo, @@ -693,6 +712,8 @@ impl AdUpdateBuilder { memo, place, priority, + #[cfg(feature = "12-81-0")] + ratio, expires_at, image_url, }; @@ -732,6 +753,13 @@ impl AdUpdateBuilder { self.place(Place::Horizontal) } + #[cfg(feature = "12-81-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] + /// Sets the place of the ad to horizontal-big. + pub fn horizontal_big(&mut self) -> &mut Self { + self.place(Place::HorizontalBig) + } + /// Sets the priority of the ad. pub fn priority(&mut self, priority: Priority) -> &mut Self { self.request.priority = priority; @@ -753,6 +781,14 @@ impl AdUpdateBuilder { self.priority(Priority::Low) } + #[cfg(feature = "12-81-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] + /// Sets the ratio of the ad. + pub fn ratio(&mut self, ratio: u64) -> &mut Self { + self.request.ratio = ratio; + self + } + /// Sets the expiration date of the ad. pub fn expires_at(&mut self, expires_at: impl Into>) -> &mut Self { self.request.expires_at = expires_at.into(); diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 4b97d108..48ec2385 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-81-0 = ["misskey-api/12-81-0", "misskey-util/12-81-0"] 12-80-0 = ["misskey-api/12-80-0", "misskey-util/12-80-0"] 12-79-2 = ["misskey-api/12-79-2", "misskey-util/12-79-2"] 12-79-0 = ["misskey-api/12-79-0", "misskey-util/12-79-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 1befb02d..6ea0b77d 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-81-0` | v12.81.0 ~ v12.81.2 | v12.81.0 | //! | `12-80-0` | v12.80.0 ~ v12.80.3 | v12.80.0 | //! | `12-79-2` | v12.79.2 ~ v12.79.3 | v12.79.2 | //! | `12-79-0` | v12.79.0 ~ v12.79.1 | v12.79.0 | From 7bd077bc11c8ed109d95249d0ab0e3f92d66ebe1 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 12 Apr 2023 04:22:45 +0900 Subject: [PATCH 09/44] Add: Support v12.82.0 --- .github/workflows/ci.yml | 4 ++-- .github/workflows/flaky.yml | 2 ++ .github/workflows/unstable.yml | 4 ++-- misskey-api/CHANGELOG.md | 1 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/drive/files/update.rs | 11 +++++++++++ misskey-util/Cargo.toml | 1 + misskey-util/src/builder/drive.rs | 10 ++++++++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 10 files changed, 32 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96e402f1..269fa214 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.81.0' + MISSKEY_IMAGE: 'misskey/misskey:12.82.0' MISSKEY_ID: aid - - run: cargo test --features 12-81-0 + - run: cargo test --features 12-82-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 5edf8edc..83f65a0f 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.82.0' + flags: --features 12-82-0 - image: 'misskey/misskey:12.81.0' flags: --features 12-81-0 - image: 'misskey/misskey:12.80.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 3749556b..49b4e75e 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.81.0' + MISSKEY_IMAGE: 'misskey/misskey:12.82.0' MISSKEY_ID: aid - - run: cargo test --features 12-81-0 + - run: cargo test --features 12-82-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 0cb6bf23..042b88ff 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -41,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint `admin/ad/*` - Support for Misskey v12.81.0 ~ 12.81.2 - endpoint `admin/get-index-stats` +- Support for Misskey v12.82.0 ~ v12.87.0 ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 3d97c076..078b79ce 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-82-0 = ["12-81-0"] 12-81-0 = ["12-80-0"] 12-80-0 = ["12-79-2"] 12-79-2 = ["12-79-0"] diff --git a/misskey-api/src/endpoint/drive/files/update.rs b/misskey-api/src/endpoint/drive/files/update.rs index c636ce71..0bfe92f3 100644 --- a/misskey-api/src/endpoint/drive/files/update.rs +++ b/misskey-api/src/endpoint/drive/files/update.rs @@ -20,6 +20,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub is_sensitive: Option, + #[cfg(feature = "12-82-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-82-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub comment: Option, } impl misskey_core::Request for Request { @@ -42,6 +47,8 @@ mod tests { folder_id: None, name: None, is_sensitive: None, + #[cfg(feature = "12-82-0")] + comment: None, }) .await; } @@ -63,6 +70,8 @@ mod tests { folder_id: Some(Some(folder.id)), name: Some("test2.txt".to_string()), is_sensitive: Some(true), + #[cfg(feature = "12-82-0")] + comment: Some("comment".to_string()), }) .await; } @@ -77,6 +86,8 @@ mod tests { folder_id: Some(None), name: None, is_sensitive: None, + #[cfg(feature = "12-82-0")] + comment: None, }) .await; } diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 55ed832a..137a7616 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-82-0 = ["misskey-api/12-82-0", "12-81-0"] 12-81-0 = ["misskey-api/12-81-0", "12-80-0"] 12-80-0 = ["misskey-api/12-80-0", "12-79-2"] 12-79-2 = ["misskey-api/12-79-2", "12-79-0"] diff --git a/misskey-util/src/builder/drive.rs b/misskey-util/src/builder/drive.rs index ea98882d..7a68c6fb 100644 --- a/misskey-util/src/builder/drive.rs +++ b/misskey-util/src/builder/drive.rs @@ -270,6 +270,8 @@ impl DriveFileUpdateBuilder { folder_id: None, name: None, is_sensitive: None, + #[cfg(feature = "12-82-0")] + comment: None, }; DriveFileUpdateBuilder { client, request } } @@ -302,6 +304,14 @@ impl DriveFileUpdateBuilder { self.request.is_sensitive = Some(sensitive); self } + + #[cfg(feature = "12-82-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-82-0")))] + /// Sets the comment of the file. + pub fn comment(&mut self, comment: impl Into) -> &mut Self { + self.request.comment.replace(comment.into()); + self + } } impl DriveFileUpdateBuilder { diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 48ec2385..07838419 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-82-0 = ["misskey-api/12-82-0", "misskey-util/12-82-0"] 12-81-0 = ["misskey-api/12-81-0", "misskey-util/12-81-0"] 12-80-0 = ["misskey-api/12-80-0", "misskey-util/12-80-0"] 12-79-2 = ["misskey-api/12-79-2", "misskey-util/12-79-2"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 6ea0b77d..6303c83a 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-82-0` | v12.82.0 ~ v12.87.0 | v12.82.0 | //! | `12-81-0` | v12.81.0 ~ v12.81.2 | v12.81.0 | //! | `12-80-0` | v12.80.0 ~ v12.80.3 | v12.80.0 | //! | `12-79-2` | v12.79.2 ~ v12.79.3 | v12.79.2 | From e35ad27d350d60ca7b9321afec435db873a95f8d Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 12 Apr 2023 08:58:23 +0900 Subject: [PATCH 10/44] Add: Partially support v12.88.0 endpoint `notes/translate` and `reset-db` are not supported --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 5 +++ misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/admin/update_meta.rs | 7 ++++ misskey-api/src/endpoint/users.rs | 19 +++++++++- misskey-api/src/model/meta.rs | 2 + misskey-util/CHANGELOG.md | 4 ++ misskey-util/Cargo.toml | 1 + misskey-util/src/builder.rs | 10 ++++- misskey-util/src/builder/admin.rs | 7 ++++ misskey-util/src/client.rs | 37 +++++++++++++------ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 15 files changed, 87 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 269fa214..e9b22dca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.82.0' + MISSKEY_IMAGE: 'misskey/misskey:12.88.0' MISSKEY_ID: aid - - run: cargo test --features 12-82-0 + - run: cargo test --features 12-88-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 83f65a0f..c073abc0 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.88.0' + flags: --features 12-88-0 - image: 'misskey/misskey:12.82.0' flags: --features 12-82-0 - image: 'misskey/misskey:12.81.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 49b4e75e..f2af46ea 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.82.0' + MISSKEY_IMAGE: 'misskey/misskey:12.88.0' MISSKEY_ID: aid - - run: cargo test --features 12-82-0 + - run: cargo test --features 12-88-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 042b88ff..c111e742 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -42,6 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.81.0 ~ 12.81.2 - endpoint `admin/get-index-stats` - Support for Misskey v12.82.0 ~ v12.87.0 +- Partial support for Misskey v12.88.0 ### Changed ### Deprecated @@ -50,6 +51,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `ClientSettingUpdated` variant from `MainStreamEvent` - For Misskey v12.67.0 ~ v12.68.0 - Latest version flag from being enabled as default +- endpoint `users` + - For Misskey v12.88.0 ~ +- endpoint `users/recommendation` + - For Misskey v12.88.0 ~ ### Fixed diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 078b79ce..784c27ce 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-88-0 = ["12-82-0"] 12-82-0 = ["12-81-0"] 12-81-0 = ["12-80-0"] 12-80-0 = ["12-79-2"] diff --git a/misskey-api/src/endpoint/admin/update_meta.rs b/misskey-api/src/endpoint/admin/update_meta.rs index 1c25742d..4cfef718 100644 --- a/misskey-api/src/endpoint/admin/update_meta.rs +++ b/misskey-api/src/endpoint/admin/update_meta.rs @@ -113,6 +113,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub summaly_proxy: Option>, + #[cfg(feature = "12-88-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-88-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub deepl_auth_key: Option>, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub enable_twitter_integration: Option, @@ -303,6 +308,8 @@ mod tests { maintainer_email: Some(Some("me@coord-e.com".to_string())), langs: Some(vec!["ja_JP".to_string()]), summaly_proxy: Some(None), + #[cfg(feature = "12-88-0")] + deepl_auth_key: Some(None), enable_twitter_integration: Some(false), twitter_consumer_key: Some(None), twitter_consumer_secret: Some(None), diff --git a/misskey-api/src/endpoint/users.rs b/misskey-api/src/endpoint/users.rs index de5ae06a..8d3535b3 100644 --- a/misskey-api/src/endpoint/users.rs +++ b/misskey-api/src/endpoint/users.rs @@ -1,10 +1,14 @@ +#[cfg(not(feature = "12-88-0"))] use crate::model::{ sort::SortOrder, user::{User, UserOrigin, UserSortKey}, }; +#[cfg(not(feature = "12-88-0"))] use serde::Serialize; +#[cfg(not(feature = "12-88-0"))] use thiserror::Error; +#[cfg(not(feature = "12-88-0"))] use typed_builder::TypedBuilder; pub mod followers; @@ -13,7 +17,6 @@ pub mod get_frequently_replied_users; pub mod groups; pub mod lists; pub mod notes; -pub mod recommendation; pub mod relation; pub mod report_abuse; pub mod search; @@ -36,6 +39,12 @@ pub mod pages; #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] pub mod gallery; +// misskey-dev/misskey#7656 +#[cfg(not(feature = "12-88-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-88-0"))))] +pub mod recommendation; + +#[cfg(not(feature = "12-88-0"))] #[derive(Serialize, PartialEq, Eq, Clone, Debug, Copy)] #[serde(rename_all = "camelCase")] pub enum UserState { @@ -46,12 +55,14 @@ pub enum UserState { AdminOrModerator, } +#[cfg(not(feature = "12-88-0"))] #[derive(Debug, Error, Clone)] #[error("invalid user state")] pub struct ParseUserStateError { _priv: (), } +#[cfg(not(feature = "12-88-0"))] impl std::str::FromStr for UserState { type Err = ParseUserStateError; @@ -67,6 +78,9 @@ impl std::str::FromStr for UserState { } } +// misskey-dev/misskey#7656 +#[cfg(not(feature = "12-88-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-88-0"))))] #[derive(Serialize, Default, Debug, Clone, TypedBuilder)] #[serde(rename_all = "camelCase")] #[builder(doc)] @@ -89,13 +103,16 @@ pub struct Request { pub origin: Option, } +#[cfg(not(feature = "12-88-0"))] impl misskey_core::Request for Request { type Response = Vec; const ENDPOINT: &'static str = "users"; } +#[cfg(not(feature = "12-88-0"))] impl_offset_pagination!(Request, User); +#[cfg(not(feature = "12-88-0"))] #[cfg(test)] mod tests { use super::{Request, UserState}; diff --git a/misskey-api/src/model/meta.rs b/misskey-api/src/model/meta.rs index 45ba38ea..a86e7fc9 100644 --- a/misskey-api/src/model/meta.rs +++ b/misskey-api/src/model/meta.rs @@ -69,6 +69,8 @@ pub struct Meta { pub enable_github_integration: bool, pub enable_discord_integration: bool, pub enable_service_worker: bool, + #[cfg(feature = "12-88-0")] + pub translator_available: bool, /// This field is [`Option`][`Option`] on non-feature="12-58-0". #[cfg(feature = "12-58-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-48-0")))] diff --git a/misskey-util/CHANGELOG.md b/misskey-util/CHANGELOG.md index 160a6b01..9bf11deb 100644 --- a/misskey-util/CHANGELOG.md +++ b/misskey-util/CHANGELOG.md @@ -18,6 +18,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - Latest version flag from being enabled as default +- `ClientExt::users` + - For Misskey v12.88.0 ~ +- `ClientExt::recommended_users` + - For Misskey v12.88.0 ~ ### Fixed ### Security diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 137a7616..239fd26e 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-88-0 = ["misskey-api/12-88-0", "12-82-0"] 12-82-0 = ["misskey-api/12-82-0", "12-81-0"] 12-81-0 = ["misskey-api/12-81-0", "12-80-0"] 12-80-0 = ["misskey-api/12-80-0", "12-79-2"] diff --git a/misskey-util/src/builder.rs b/misskey-util/src/builder.rs index 4b19cf88..5457fb63 100644 --- a/misskey-util/src/builder.rs +++ b/misskey-util/src/builder.rs @@ -17,7 +17,6 @@ mod messaging; mod misc; mod note; mod page; -mod user; #[cfg(feature = "12-47-0")] mod channel; @@ -25,6 +24,9 @@ mod channel; #[cfg(feature = "12-79-0")] mod gallery; +#[cfg(not(feature = "12-88-0"))] +mod user; + pub use admin::{ AnnouncementUpdateBuilder, EmojiUpdateBuilder, MetaUpdateBuilder, ServerLogListBuilder, }; @@ -38,7 +40,6 @@ pub use me::{IntoUserFields, MeUpdateBuilder}; pub use messaging::MessagingMessageBuilder; pub use note::NoteBuilder; pub use page::{PageBuilder, PageUpdateBuilder}; -pub use user::UserListBuilder; #[cfg(feature = "12-47-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-47-0")))] @@ -59,3 +60,8 @@ pub use gallery::GalleryPostUpdateBuilder; #[cfg(feature = "12-80-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] pub use admin::{AdBuilder, AdUpdateBuilder}; + +// misskey-dev/misskey#7656 +#[cfg(not(feature = "12-88-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-88-0"))))] +pub use user::UserListBuilder; diff --git a/misskey-util/src/builder/admin.rs b/misskey-util/src/builder/admin.rs index 9231121e..ffab81be 100644 --- a/misskey-util/src/builder/admin.rs +++ b/misskey-util/src/builder/admin.rs @@ -271,6 +271,13 @@ impl MetaUpdateBuilder { pub summaly_proxy: Url { summaly_proxy }; } + update_builder_string_option_field! { + #[doc_name = "DeepL auth key"] + #[cfg(feature = "12-88-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-88-0")))] + pub deepl_auth_key; + } + update_builder_bool_field! { /// Sets whether or not to enable the Twitter integration. pub enable_twitter_integration; diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index aae4a555..9046d3f7 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -10,13 +10,15 @@ use crate::builder::GalleryPostBuilder; use crate::builder::GalleryPostUpdateBuilder; #[cfg(feature = "12-27-0")] use crate::builder::NotificationBuilder; +#[cfg(not(feature = "12-88-0"))] +use crate::builder::UserListBuilder; #[cfg(feature = "12-80-0")] use crate::builder::{AdBuilder, AdUpdateBuilder}; use crate::builder::{ AnnouncementUpdateBuilder, AntennaBuilder, AntennaUpdateBuilder, DriveFileBuilder, DriveFileListBuilder, DriveFileUpdateBuilder, DriveFileUrlBuilder, DriveFolderUpdateBuilder, MeUpdateBuilder, MessagingMessageBuilder, MetaUpdateBuilder, NoteBuilder, PageBuilder, - PageUpdateBuilder, ServerLogListBuilder, UserListBuilder, + PageUpdateBuilder, ServerLogListBuilder, }; #[cfg(feature = "12-47-0")] use crate::builder::{ChannelBuilder, ChannelUpdateBuilder}; @@ -86,7 +88,7 @@ macro_rules! impl_timeline_method { /// # #[tokio::main] /// # async fn main() -> anyhow::Result<()> { /// # let client = misskey_test::test_client().await?; - /// # let user = client.users().list().try_next().await?.unwrap(); + /// # let user = client.me().await?; /// # #[cfg(feature = "12-47-0")] /// # let channel = client.create_channel("test").await?; /// # let list = client.create_user_list("test").await?; @@ -112,7 +114,7 @@ macro_rules! impl_timeline_method { /// # #[tokio::main] /// # async fn main() -> anyhow::Result<()> { /// # let client = misskey_test::test_client().await?; - /// # let user = client.users().list().try_next().await?.unwrap(); + /// # let user = client.me().await?; /// # #[cfg(feature = "12-47-0")] /// # let channel = client.create_channel("test").await?; /// # let list = client.create_user_list("test").await?; @@ -184,7 +186,7 @@ macro_rules! impl_timeline_method { /// # #[tokio::main] /// # async fn main() -> anyhow::Result<()> { /// # let client = misskey_test::test_client().await?; - /// # let user = client.users().list().try_next().await?.unwrap(); + /// # let user = client.me().await?; /// # #[cfg(feature = "12-47-0")] /// # let channel = client.create_channel("test").await?; /// # let list = client.create_user_list("test").await?; @@ -649,7 +651,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - /// ``` + #[cfg_attr(not(feature = "12-88-0"), doc = "```")] + #[cfg_attr(feature = "12-88-0", doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -675,7 +678,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - /// ``` + #[cfg_attr(not(feature = "12-88-0"), doc = "```")] + #[cfg_attr(feature = "12-88-0", doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -701,7 +705,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - /// ``` + #[cfg_attr(not(feature = "12-88-0"), doc = "```")] + #[cfg_attr(feature = "12-88-0", doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -727,7 +732,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - /// ``` + #[cfg_attr(not(feature = "12-88-0"), doc = "```")] + #[cfg_attr(feature = "12-88-0", doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -753,7 +759,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - /// ``` + #[cfg_attr(not(feature = "12-88-0"), doc = "```")] + #[cfg_attr(feature = "12-88-0", doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -776,7 +783,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - /// ``` + #[cfg_attr(not(feature = "12-88-0"), doc = "```")] + #[cfg_attr(feature = "12-88-0", doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -807,7 +815,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - /// ``` + #[cfg_attr(not(feature = "12-88-0"), doc = "```")] + #[cfg_attr(feature = "12-88-0", doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -921,11 +930,17 @@ pub trait ClientExt: Client + Sync { /// # Ok(()) /// # } /// ``` + // misskey-dev/misskey#7656 + #[cfg(not(feature = "12-88-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-88-0"))))] fn users(&self) -> UserListBuilder<&Self> { UserListBuilder::new(self) } /// Lists the recommended users of the instance. + // misskey-dev/misskey#7656 + #[cfg(not(feature = "12-88-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-88-0"))))] fn recommended_users(&self) -> PagerStream> { let pager = OffsetPager::new(self, endpoint::users::recommendation::Request::default()); PagerStream::new(Box::pin(pager)) diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 07838419..fd4b2cd0 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-88-0 = ["misskey-api/12-88-0", "misskey-util/12-88-0"] 12-82-0 = ["misskey-api/12-82-0", "misskey-util/12-82-0"] 12-81-0 = ["misskey-api/12-81-0", "misskey-util/12-81-0"] 12-80-0 = ["misskey-api/12-80-0", "misskey-util/12-80-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 6303c83a..8706aaff 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-88-0` | v12.88.0 | v12.88.0 | //! | `12-82-0` | v12.82.0 ~ v12.87.0 | v12.82.0 | //! | `12-81-0` | v12.81.0 ~ v12.81.2 | v12.81.0 | //! | `12-80-0` | v12.80.0 ~ v12.80.3 | v12.80.0 | From a1652dfa0231e05a0419447da54e8912c1a70254 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 12 Apr 2023 09:53:19 +0900 Subject: [PATCH 11/44] Add: Support v12.89.0 --- .github/workflows/ci.yml | 4 +-- .github/workflows/flaky.yml | 2 ++ .github/workflows/unstable.yml | 4 +-- misskey-api/CHANGELOG.md | 3 ++- misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/admin/logs.rs | 3 +++ misskey-api/src/endpoint/users.rs | 24 +++++++++--------- misskey-util/CHANGELOG.md | 2 +- misskey-util/Cargo.toml | 1 + misskey-util/src/builder.rs | 6 ++--- misskey-util/src/client.rs | 34 +++++++++++++------------- misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 13 files changed, 48 insertions(+), 38 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e9b22dca..cb2051cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.88.0' + MISSKEY_IMAGE: 'misskey/misskey:12.89.0' MISSKEY_ID: aid - - run: cargo test --features 12-88-0 + - run: cargo test --features 12-89-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index c073abc0..22d02071 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.89.0' + flags: --features 12-89-0 - image: 'misskey/misskey:12.88.0' flags: --features 12-88-0 - image: 'misskey/misskey:12.82.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index f2af46ea..f2cb58bc 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.88.0' + MISSKEY_IMAGE: 'misskey/misskey:12.89.0' MISSKEY_ID: aid - - run: cargo test --features 12-88-0 + - run: cargo test --features 12-89-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index c111e742..f913fbca 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -43,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint `admin/get-index-stats` - Support for Misskey v12.82.0 ~ v12.87.0 - Partial support for Misskey v12.88.0 +- Support for Misskey v12.89.0 ### Changed ### Deprecated @@ -52,7 +53,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - For Misskey v12.67.0 ~ v12.68.0 - Latest version flag from being enabled as default - endpoint `users` - - For Misskey v12.88.0 ~ + - For Misskey v12.88.0 - endpoint `users/recommendation` - For Misskey v12.88.0 ~ diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 784c27ce..757197d0 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-89-0 = ["12-88-0"] 12-88-0 = ["12-82-0"] 12-82-0 = ["12-81-0"] 12-81-0 = ["12-80-0"] diff --git a/misskey-api/src/endpoint/admin/logs.rs b/misskey-api/src/endpoint/admin/logs.rs index eb16cd5f..6354f44b 100644 --- a/misskey-api/src/endpoint/admin/logs.rs +++ b/misskey-api/src/endpoint/admin/logs.rs @@ -60,7 +60,10 @@ mod tests { .test(Request { limit: None, level: Some(LogLevel::Debug), + #[cfg(not(feature = "12-89-0"))] domain: Some("chart remote -resolve-user".to_string()), + #[cfg(feature = "12-89-0")] + domain: Some("chart".to_string()), }) .await; } diff --git a/misskey-api/src/endpoint/users.rs b/misskey-api/src/endpoint/users.rs index 8d3535b3..51df0833 100644 --- a/misskey-api/src/endpoint/users.rs +++ b/misskey-api/src/endpoint/users.rs @@ -1,14 +1,14 @@ -#[cfg(not(feature = "12-88-0"))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] use crate::model::{ sort::SortOrder, user::{User, UserOrigin, UserSortKey}, }; -#[cfg(not(feature = "12-88-0"))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] use serde::Serialize; -#[cfg(not(feature = "12-88-0"))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] use thiserror::Error; -#[cfg(not(feature = "12-88-0"))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] use typed_builder::TypedBuilder; pub mod followers; @@ -44,7 +44,7 @@ pub mod gallery; #[cfg_attr(docsrs, doc(cfg(not(feature = "12-88-0"))))] pub mod recommendation; -#[cfg(not(feature = "12-88-0"))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] #[derive(Serialize, PartialEq, Eq, Clone, Debug, Copy)] #[serde(rename_all = "camelCase")] pub enum UserState { @@ -55,14 +55,14 @@ pub enum UserState { AdminOrModerator, } -#[cfg(not(feature = "12-88-0"))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] #[derive(Debug, Error, Clone)] #[error("invalid user state")] pub struct ParseUserStateError { _priv: (), } -#[cfg(not(feature = "12-88-0"))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] impl std::str::FromStr for UserState { type Err = ParseUserStateError; @@ -79,8 +79,8 @@ impl std::str::FromStr for UserState { } // misskey-dev/misskey#7656 -#[cfg(not(feature = "12-88-0"))] -#[cfg_attr(docsrs, doc(cfg(not(feature = "12-88-0"))))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] +#[cfg_attr(docsrs, doc(cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))))] #[derive(Serialize, Default, Debug, Clone, TypedBuilder)] #[serde(rename_all = "camelCase")] #[builder(doc)] @@ -103,16 +103,16 @@ pub struct Request { pub origin: Option, } -#[cfg(not(feature = "12-88-0"))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] impl misskey_core::Request for Request { type Response = Vec; const ENDPOINT: &'static str = "users"; } -#[cfg(not(feature = "12-88-0"))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] impl_offset_pagination!(Request, User); -#[cfg(not(feature = "12-88-0"))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] #[cfg(test)] mod tests { use super::{Request, UserState}; diff --git a/misskey-util/CHANGELOG.md b/misskey-util/CHANGELOG.md index 9bf11deb..4a667846 100644 --- a/misskey-util/CHANGELOG.md +++ b/misskey-util/CHANGELOG.md @@ -19,7 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Latest version flag from being enabled as default - `ClientExt::users` - - For Misskey v12.88.0 ~ + - For Misskey v12.88.0 - `ClientExt::recommended_users` - For Misskey v12.88.0 ~ diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 239fd26e..3610844e 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-89-0 = ["misskey-api/12-89-0", "12-88-0"] 12-88-0 = ["misskey-api/12-88-0", "12-82-0"] 12-82-0 = ["misskey-api/12-82-0", "12-81-0"] 12-81-0 = ["misskey-api/12-81-0", "12-80-0"] diff --git a/misskey-util/src/builder.rs b/misskey-util/src/builder.rs index 5457fb63..80f72a50 100644 --- a/misskey-util/src/builder.rs +++ b/misskey-util/src/builder.rs @@ -24,7 +24,7 @@ mod channel; #[cfg(feature = "12-79-0")] mod gallery; -#[cfg(not(feature = "12-88-0"))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] mod user; pub use admin::{ @@ -62,6 +62,6 @@ pub use gallery::GalleryPostUpdateBuilder; pub use admin::{AdBuilder, AdUpdateBuilder}; // misskey-dev/misskey#7656 -#[cfg(not(feature = "12-88-0"))] -#[cfg_attr(docsrs, doc(cfg(not(feature = "12-88-0"))))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] +#[cfg_attr(docsrs, doc(cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))))] pub use user::UserListBuilder; diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index 9046d3f7..c47a17b1 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -10,7 +10,7 @@ use crate::builder::GalleryPostBuilder; use crate::builder::GalleryPostUpdateBuilder; #[cfg(feature = "12-27-0")] use crate::builder::NotificationBuilder; -#[cfg(not(feature = "12-88-0"))] +#[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] use crate::builder::UserListBuilder; #[cfg(feature = "12-80-0")] use crate::builder::{AdBuilder, AdUpdateBuilder}; @@ -651,8 +651,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - #[cfg_attr(not(feature = "12-88-0"), doc = "```")] - #[cfg_attr(feature = "12-88-0", doc = "```ignore")] + #[cfg_attr(any(not(feature = "12-88-0"), feature = "12-89-0"), doc = "```")] + #[cfg_attr(all(feature = "12-88-0", not(feature = "12-89-0")), doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -678,8 +678,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - #[cfg_attr(not(feature = "12-88-0"), doc = "```")] - #[cfg_attr(feature = "12-88-0", doc = "```ignore")] + #[cfg_attr(any(not(feature = "12-88-0"), feature = "12-89-0"), doc = "```")] + #[cfg_attr(all(feature = "12-88-0", not(feature = "12-89-0")), doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -705,8 +705,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - #[cfg_attr(not(feature = "12-88-0"), doc = "```")] - #[cfg_attr(feature = "12-88-0", doc = "```ignore")] + #[cfg_attr(any(not(feature = "12-88-0"), feature = "12-89-0"), doc = "```")] + #[cfg_attr(all(feature = "12-88-0", not(feature = "12-89-0")), doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -732,8 +732,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - #[cfg_attr(not(feature = "12-88-0"), doc = "```")] - #[cfg_attr(feature = "12-88-0", doc = "```ignore")] + #[cfg_attr(any(not(feature = "12-88-0"), feature = "12-89-0"), doc = "```")] + #[cfg_attr(all(feature = "12-88-0", not(feature = "12-89-0")), doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -759,8 +759,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - #[cfg_attr(not(feature = "12-88-0"), doc = "```")] - #[cfg_attr(feature = "12-88-0", doc = "```ignore")] + #[cfg_attr(any(not(feature = "12-88-0"), feature = "12-89-0"), doc = "```")] + #[cfg_attr(all(feature = "12-88-0", not(feature = "12-89-0")), doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -783,8 +783,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - #[cfg_attr(not(feature = "12-88-0"), doc = "```")] - #[cfg_attr(feature = "12-88-0", doc = "```ignore")] + #[cfg_attr(any(not(feature = "12-88-0"), feature = "12-89-0"), doc = "```")] + #[cfg_attr(all(feature = "12-88-0", not(feature = "12-89-0")), doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -815,8 +815,8 @@ pub trait ClientExt: Client + Sync { /// /// [user_relation]: ClientExt::user_relation /// - #[cfg_attr(not(feature = "12-88-0"), doc = "```")] - #[cfg_attr(feature = "12-88-0", doc = "```ignore")] + #[cfg_attr(any(not(feature = "12-88-0"), feature = "12-89-0"), doc = "```")] + #[cfg_attr(all(feature = "12-88-0", not(feature = "12-89-0")), doc = "```ignore")] /// # use misskey_util::ClientExt; /// # use futures::stream::TryStreamExt; /// # #[tokio::main] @@ -931,8 +931,8 @@ pub trait ClientExt: Client + Sync { /// # } /// ``` // misskey-dev/misskey#7656 - #[cfg(not(feature = "12-88-0"))] - #[cfg_attr(docsrs, doc(cfg(not(feature = "12-88-0"))))] + #[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] + #[cfg_attr(docsrs, doc(cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))))] fn users(&self) -> UserListBuilder<&Self> { UserListBuilder::new(self) } diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index fd4b2cd0..108186a2 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-89-0 = ["misskey-api/12-89-0", "misskey-util/12-89-0"] 12-88-0 = ["misskey-api/12-88-0", "misskey-util/12-88-0"] 12-82-0 = ["misskey-api/12-82-0", "misskey-util/12-82-0"] 12-81-0 = ["misskey-api/12-81-0", "misskey-util/12-81-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 8706aaff..11640886 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-89-0` | v12.89.0 | v12.89.0 | //! | `12-88-0` | v12.88.0 | v12.88.0 | //! | `12-82-0` | v12.82.0 ~ v12.87.0 | v12.82.0 | //! | `12-81-0` | v12.81.0 ~ v12.81.2 | v12.81.0 | From 9b011c21759af8ac3eeb914eb9fc6d39f0f00fb9 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 12 Apr 2023 10:34:02 +0900 Subject: [PATCH 12/44] Add: Support v12.89.1 --- .github/workflows/ci.yml | 4 ++-- .github/workflows/flaky.yml | 2 ++ .github/workflows/unstable.yml | 4 ++-- misskey-api/CHANGELOG.md | 1 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/admin/update_meta.rs | 7 +++++++ misskey-api/src/model/meta.rs | 6 ++++++ misskey-util/Cargo.toml | 1 + misskey-util/src/builder/admin.rs | 5 +++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 11 files changed, 29 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb2051cc..66215880 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.89.0' + MISSKEY_IMAGE: 'misskey/misskey:12.89.1' MISSKEY_ID: aid - - run: cargo test --features 12-89-0 + - run: cargo test --features 12-89-1 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 22d02071..9cd59902 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.89.1' + flags: --features 12-89-1 - image: 'misskey/misskey:12.89.0' flags: --features 12-89-0 - image: 'misskey/misskey:12.88.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index f2cb58bc..f6dda953 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.89.0' + MISSKEY_IMAGE: 'misskey/misskey:12.89.1' MISSKEY_ID: aid - - run: cargo test --features 12-89-0 + - run: cargo test --features 12-89-1 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index f913fbca..7f086a72 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.82.0 ~ v12.87.0 - Partial support for Misskey v12.88.0 - Support for Misskey v12.89.0 +- Support for Misskey v12.89.1 ~ v12.90.1 ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 757197d0..61193af4 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-89-1 = ["12-89-0"] 12-89-0 = ["12-88-0"] 12-88-0 = ["12-82-0"] 12-82-0 = ["12-81-0"] diff --git a/misskey-api/src/endpoint/admin/update_meta.rs b/misskey-api/src/endpoint/admin/update_meta.rs index 4cfef718..6b0837fe 100644 --- a/misskey-api/src/endpoint/admin/update_meta.rs +++ b/misskey-api/src/endpoint/admin/update_meta.rs @@ -118,6 +118,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub deepl_auth_key: Option>, + #[cfg(feature = "12-89-1")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-89-1")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub deepl_is_pro: Option, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub enable_twitter_integration: Option, @@ -310,6 +315,8 @@ mod tests { summaly_proxy: Some(None), #[cfg(feature = "12-88-0")] deepl_auth_key: Some(None), + #[cfg(feature = "12-89-1")] + deepl_is_pro: Some(false), enable_twitter_integration: Some(false), twitter_consumer_key: Some(None), twitter_consumer_secret: Some(None), diff --git a/misskey-api/src/model/meta.rs b/misskey-api/src/model/meta.rs index a86e7fc9..54998a39 100644 --- a/misskey-api/src/model/meta.rs +++ b/misskey-api/src/model/meta.rs @@ -153,6 +153,12 @@ pub struct AdminMeta { #[cfg(feature = "12-69-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-69-0")))] pub object_storage_s3_force_path_style: bool, + #[cfg(feature = "12-89-1")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-89-1")))] + pub deepl_auth_key: Option, + #[cfg(feature = "12-89-1")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-89-1")))] + pub deepl_is_pro: bool, } #[derive(Deserialize, Serialize, Debug, Clone)] diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 3610844e..15e31c7a 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-89-1 = ["misskey-api/12-89-1", "12-89-0"] 12-89-0 = ["misskey-api/12-89-0", "12-88-0"] 12-88-0 = ["misskey-api/12-88-0", "12-82-0"] 12-82-0 = ["misskey-api/12-82-0", "12-81-0"] diff --git a/misskey-util/src/builder/admin.rs b/misskey-util/src/builder/admin.rs index ffab81be..37745e9f 100644 --- a/misskey-util/src/builder/admin.rs +++ b/misskey-util/src/builder/admin.rs @@ -279,6 +279,11 @@ impl MetaUpdateBuilder { } update_builder_bool_field! { + /// Sets whether or not DeepL is pro. + #[cfg(feature = "12-89-1")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-89-1")))] + pub deepl_is_pro; + /// Sets whether or not to enable the Twitter integration. pub enable_twitter_integration; } diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 108186a2..e1b4b529 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-89-1 = ["misskey-api/12-89-1", "misskey-util/12-89-1"] 12-89-0 = ["misskey-api/12-89-0", "misskey-util/12-89-0"] 12-88-0 = ["misskey-api/12-88-0", "misskey-util/12-88-0"] 12-82-0 = ["misskey-api/12-82-0", "misskey-util/12-82-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 11640886..b9cd6f8b 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-89-1` | v12.89.1 ~ v12.90.1 | v12.89.1 | //! | `12-89-0` | v12.89.0 | v12.89.0 | //! | `12-88-0` | v12.88.0 | v12.88.0 | //! | `12-82-0` | v12.82.0 ~ v12.87.0 | v12.82.0 | From 2bc74da1e8688a22e0a39399f0d889599d0a372c Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 12 Apr 2023 10:44:30 +0900 Subject: [PATCH 13/44] CI: Set allowedPrivateNetworks --- ci/testenv/web/default.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci/testenv/web/default.yml b/ci/testenv/web/default.yml index 7743030d..1bf4b16e 100644 --- a/ci/testenv/web/default.yml +++ b/ci/testenv/web/default.yml @@ -1,5 +1,8 @@ url: http://localhost:3000/ port: 3000 +allowedPrivateNetworks: [ + 127.0.0.1/32 +] db: host: db From 21a3c61eb5e83357ccafa50358ed2f33393ec773 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 12 Apr 2023 12:00:17 +0900 Subject: [PATCH 14/44] Add: Support v12.91.0 --- .github/workflows/ci.yml | 4 +-- .github/workflows/flaky.yml | 2 ++ .github/workflows/unstable.yml | 4 +-- misskey-api/CHANGELOG.md | 2 ++ misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/admin/accounts.rs | 4 +++ .../src/endpoint/admin/accounts/delete.rs | 28 +++++++++++++++++++ misskey-util/Cargo.toml | 1 + misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 10 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 misskey-api/src/endpoint/admin/accounts/delete.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 66215880..16990208 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.89.1' + MISSKEY_IMAGE: 'misskey/misskey:12.91.0' MISSKEY_ID: aid - - run: cargo test --features 12-89-1 + - run: cargo test --features 12-91-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 9cd59902..bd1732f3 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.91.0' + flags: --features 12-91-0 - image: 'misskey/misskey:12.89.1' flags: --features 12-89-1 - image: 'misskey/misskey:12.89.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index f6dda953..00dae3c3 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.89.1' + MISSKEY_IMAGE: 'misskey/misskey:12.91.0' MISSKEY_ID: aid - - run: cargo test --features 12-89-1 + - run: cargo test --features 12-91-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 7f086a72..27fecda1 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -45,6 +45,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Partial support for Misskey v12.88.0 - Support for Misskey v12.89.0 - Support for Misskey v12.89.1 ~ v12.90.1 +- Support for Misskey v12.91.0 + - endpoint `admin/accounts/delete` ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 61193af4..0d9f62e9 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-91-0 = ["12-89-1"] 12-89-1 = ["12-89-0"] 12-89-0 = ["12-88-0"] 12-88-0 = ["12-82-0"] diff --git a/misskey-api/src/endpoint/admin/accounts.rs b/misskey-api/src/endpoint/admin/accounts.rs index c5fb369c..c1211780 100644 --- a/misskey-api/src/endpoint/admin/accounts.rs +++ b/misskey-api/src/endpoint/admin/accounts.rs @@ -1 +1,5 @@ pub mod create; + +#[cfg(feature = "12-91-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-91-0")))] +pub mod delete; diff --git a/misskey-api/src/endpoint/admin/accounts/delete.rs b/misskey-api/src/endpoint/admin/accounts/delete.rs new file mode 100644 index 00000000..b60d239a --- /dev/null +++ b/misskey-api/src/endpoint/admin/accounts/delete.rs @@ -0,0 +1,28 @@ +use crate::model::{id::Id, user::User}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub user_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/accounts/delete"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let (user, _) = client.admin.create_user().await; + + client.admin.test(Request { user_id: user.id }).await; + } +} diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 15e31c7a..3179adbb 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-91-0 = ["misskey-api/12-91-0", "12-89-1"] 12-89-1 = ["misskey-api/12-89-1", "12-89-0"] 12-89-0 = ["misskey-api/12-89-0", "12-88-0"] 12-88-0 = ["misskey-api/12-88-0", "12-82-0"] diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index e1b4b529..5b43544a 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-91-0 = ["misskey-api/12-91-0", "misskey-util/12-91-0"] 12-89-1 = ["misskey-api/12-89-1", "misskey-util/12-89-1"] 12-89-0 = ["misskey-api/12-89-0", "misskey-util/12-89-0"] 12-88-0 = ["misskey-api/12-88-0", "misskey-util/12-88-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index b9cd6f8b..232a8b60 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-91-0` | v12.91.0 | v12.91.0 | //! | `12-89-1` | v12.89.1 ~ v12.90.1 | v12.89.1 | //! | `12-89-0` | v12.89.0 | v12.89.0 | //! | `12-88-0` | v12.88.0 | v12.88.0 | From 13163d230da9bd3af56be168497f46a95f00de8d Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 12 Apr 2023 13:02:41 +0900 Subject: [PATCH 15/44] Add: Support v12.92.0 --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 3 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint.rs | 4 ++ misskey-api/src/endpoint/admin/update_meta.rs | 7 +++ misskey-api/src/endpoint/email_address.rs | 1 + .../src/endpoint/email_address/available.rs | 34 ++++++++++++ misskey-api/src/endpoint/i/notifications.rs | 13 +++++ misskey-api/src/endpoint/users/groups.rs | 4 ++ .../src/endpoint/users/groups/leave.rs | 55 +++++++++++++++++++ misskey-api/src/model/meta.rs | 6 ++ misskey-util/Cargo.toml | 1 + misskey-util/src/builder/admin.rs | 5 ++ misskey-util/src/client.rs | 19 +++++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 18 files changed, 161 insertions(+), 4 deletions(-) create mode 100644 misskey-api/src/endpoint/email_address.rs create mode 100644 misskey-api/src/endpoint/email_address/available.rs create mode 100644 misskey-api/src/endpoint/users/groups/leave.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 16990208..daf81732 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.91.0' + MISSKEY_IMAGE: 'misskey/misskey:12.92.0' MISSKEY_ID: aid - - run: cargo test --features 12-91-0 + - run: cargo test --features 12-92-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index bd1732f3..4479b6ee 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.92.0' + flags: --features 12-92-0 - image: 'misskey/misskey:12.91.0' flags: --features 12-91-0 - image: 'misskey/misskey:12.89.1' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 00dae3c3..1d184dde 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.91.0' + MISSKEY_IMAGE: 'misskey/misskey:12.92.0' MISSKEY_ID: aid - - run: cargo test --features 12-91-0 + - run: cargo test --features 12-92-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 27fecda1..86aedb1b 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -47,6 +47,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.89.1 ~ v12.90.1 - Support for Misskey v12.91.0 - endpoint `admin/accounts/delete` +- Support for Misskey v12.92.0 + - endpoint `email-address/available` + - endpoint `users/groups/leave` ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 0d9f62e9..5149ef49 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-92-0 = ["12-91-0"] 12-91-0 = ["12-89-1"] 12-89-1 = ["12-89-0"] 12-89-0 = ["12-88-0"] diff --git a/misskey-api/src/endpoint.rs b/misskey-api/src/endpoint.rs index 8cdb928d..50610458 100644 --- a/misskey-api/src/endpoint.rs +++ b/misskey-api/src/endpoint.rs @@ -82,3 +82,7 @@ pub mod ping; #[cfg(feature = "12-79-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-79-0")))] pub mod gallery; + +#[cfg(feature = "12-92-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-92-0")))] +pub mod email_address; diff --git a/misskey-api/src/endpoint/admin/update_meta.rs b/misskey-api/src/endpoint/admin/update_meta.rs index 6b0837fe..21e5aaa4 100644 --- a/misskey-api/src/endpoint/admin/update_meta.rs +++ b/misskey-api/src/endpoint/admin/update_meta.rs @@ -74,6 +74,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub proxy_remote_files: Option, + #[cfg(feature = "12-92-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-92-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub email_required_for_signup: Option, #[cfg(feature = "12-37-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-37-0")))] #[serde(skip_serializing_if = "Option::is_none")] @@ -299,6 +304,8 @@ mod tests { remote_drive_capacity_mb: Some(1000), cache_remote_files: Some(true), proxy_remote_files: Some(true), + #[cfg(feature = "12-92-0")] + email_required_for_signup: Some(true), #[cfg(feature = "12-37-0")] enable_hcaptcha: Some(false), #[cfg(feature = "12-37-0")] diff --git a/misskey-api/src/endpoint/email_address.rs b/misskey-api/src/endpoint/email_address.rs new file mode 100644 index 00000000..d158f16f --- /dev/null +++ b/misskey-api/src/endpoint/email_address.rs @@ -0,0 +1 @@ +pub mod available; diff --git a/misskey-api/src/endpoint/email_address/available.rs b/misskey-api/src/endpoint/email_address/available.rs new file mode 100644 index 00000000..85a9899a --- /dev/null +++ b/misskey-api/src/endpoint/email_address/available.rs @@ -0,0 +1,34 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub email_address: String, +} + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Response { + pub available: bool, +} + +impl misskey_core::Request for Request { + type Response = Response; + const ENDPOINT: &'static str = "email-address/available"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client + .test(Request { + email_address: "test@example.com".to_string(), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/i/notifications.rs b/misskey-api/src/endpoint/i/notifications.rs index 5bf2aa32..e9c58623 100644 --- a/misskey-api/src/endpoint/i/notifications.rs +++ b/misskey-api/src/endpoint/i/notifications.rs @@ -25,6 +25,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub following: Option, + #[cfg(feature = "12-92-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-92-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub unread_only: Option, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub mark_as_read: Option, @@ -63,6 +68,8 @@ mod tests { since_id: None, until_id: None, following: None, + #[cfg(feature = "12-92-0")] + unread_only: None, mark_as_read: None, include_types: None, exclude_types: None, @@ -81,6 +88,8 @@ mod tests { since_id: None, until_id: None, following: Some(true), + #[cfg(feature = "12-92-0")] + unread_only: Some(true), mark_as_read: Some(false), include_types: Some( vec![NotificationType::Follow, NotificationType::Reply] @@ -112,6 +121,8 @@ mod tests { since_id: None, until_id: None, following: None, + #[cfg(feature = "12-92-0")] + unread_only: None, mark_as_read: None, include_types: None, exclude_types: None, @@ -127,6 +138,8 @@ mod tests { since_id: Some(notification_id.clone()), until_id: Some(notification_id.clone()), following: None, + #[cfg(feature = "12-92-0")] + unread_only: None, mark_as_read: None, include_types: None, exclude_types: None, diff --git a/misskey-api/src/endpoint/users/groups.rs b/misskey-api/src/endpoint/users/groups.rs index 3f7c6865..b59564f5 100644 --- a/misskey-api/src/endpoint/users/groups.rs +++ b/misskey-api/src/endpoint/users/groups.rs @@ -8,3 +8,7 @@ pub mod pull; pub mod show; pub mod transfer; pub mod update; + +#[cfg(feature = "12-92-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-92-0")))] +pub mod leave; diff --git a/misskey-api/src/endpoint/users/groups/leave.rs b/misskey-api/src/endpoint/users/groups/leave.rs new file mode 100644 index 00000000..7e2152f7 --- /dev/null +++ b/misskey-api/src/endpoint/users/groups/leave.rs @@ -0,0 +1,55 @@ +use crate::model::{id::Id, user_group::UserGroup}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub group_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "users/groups/leave"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let (new_user, new_user_client) = client.admin.create_user().await; + let group = client + .test(crate::endpoint::users::groups::create::Request { + name: "test".to_string(), + }) + .await; + client + .test(crate::endpoint::users::groups::invite::Request { + group_id: group.id.clone(), + user_id: new_user.id.clone(), + }) + .await; + let invitation = new_user_client + .test(crate::endpoint::i::user_group_invites::Request { + limit: None, + since_id: None, + until_id: None, + }) + .await + .pop() + .unwrap(); + new_user_client + .test( + crate::endpoint::users::groups::invitations::accept::Request { + invitation_id: invitation.id, + }, + ) + .await; + + new_user_client.test(Request { group_id: group.id }).await; + } +} diff --git a/misskey-api/src/model/meta.rs b/misskey-api/src/model/meta.rs index 54998a39..dac120b3 100644 --- a/misskey-api/src/model/meta.rs +++ b/misskey-api/src/model/meta.rs @@ -40,6 +40,9 @@ pub struct Meta { pub proxy_remote_files: Option, #[cfg(not(feature = "12-58-0"))] pub proxy_remote_files: bool, + #[cfg(feature = "12-92-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-92-0")))] + pub email_required_for_signup: bool, #[cfg(feature = "12-37-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-37-0")))] pub enable_hcaptcha: bool, @@ -167,6 +170,9 @@ pub struct FeaturesMeta { pub registration: bool, pub local_time_line: bool, pub global_time_line: bool, + #[cfg(feature = "12-92-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-92-0")))] + pub email_required_for_signup: bool, pub elasticsearch: bool, #[cfg(feature = "12-37-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-37-0")))] diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 3179adbb..4a4c3cec 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-92-0 = ["misskey-api/12-92-0", "12-91-0"] 12-91-0 = ["misskey-api/12-91-0", "12-89-1"] 12-89-1 = ["misskey-api/12-89-1", "12-89-0"] 12-89-0 = ["misskey-api/12-89-0", "12-88-0"] diff --git a/misskey-util/src/builder/admin.rs b/misskey-util/src/builder/admin.rs index 37745e9f..8eb476a5 100644 --- a/misskey-util/src/builder/admin.rs +++ b/misskey-util/src/builder/admin.rs @@ -223,6 +223,11 @@ impl MetaUpdateBuilder { } update_builder_bool_field! { + /// Sets whether or not the instance requires email for signup. + #[cfg(feature = "12-92-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-92-0")))] + pub email_required_for_signup; + /// Sets whether or not the instance enables hCaptcha. #[cfg(feature = "12-37-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-37-0")))] diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index c47a17b1..513762ac 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -1690,6 +1690,25 @@ pub trait ClientExt: Client + Sync { }) } + /// Leaves the specified user group. + /// + /// Note that the owner cannot leave the group. + #[cfg(feature = "12-92-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-92-0")))] + fn leave_group( + &self, + group: impl EntityRef, + ) -> BoxFuture>> { + let group_id = group.entity_ref(); + Box::pin(async move { + self.request(endpoint::users::groups::leave::Request { group_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + /// Transfers the specified user group. /// /// Note that you can only transfer the group to one of its members. diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 5b43544a..6a4ddd57 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-92-0 = ["misskey-api/12-92-0", "misskey-util/12-92-0"] 12-91-0 = ["misskey-api/12-91-0", "misskey-util/12-91-0"] 12-89-1 = ["misskey-api/12-89-1", "misskey-util/12-89-1"] 12-89-0 = ["misskey-api/12-89-0", "misskey-util/12-89-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 232a8b60..50e3d6f7 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-92-0` | v12.92.0 | v12.92.0 | //! | `12-91-0` | v12.91.0 | v12.91.0 | //! | `12-89-1` | v12.89.1 ~ v12.90.1 | v12.89.1 | //! | `12-89-0` | v12.89.0 | v12.89.0 | From fda6b4057384b39adfe3c44af77833b3a820acc2 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Thu, 13 Apr 2023 10:21:00 +0900 Subject: [PATCH 16/44] Add: Partially support v12.93.0 endpoint `i/import-blocking` and `i/import-muting` are not supported --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 4 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/admin.rs | 10 +- misskey-api/src/endpoint/i/update.rs | 9 + misskey-api/src/endpoint/users.rs | 4 + misskey-api/src/endpoint/users/reactions.rs | 129 +++++++++++ misskey-api/src/endpoint/users/search.rs | 56 +++++ .../users/search_by_username_and_host.rs | 8 + misskey-api/src/model/note_reaction.rs | 6 + misskey-api/src/model/notification.rs | 37 ++- misskey-util/CHANGELOG.md | 3 + misskey-util/Cargo.toml | 1 + misskey-util/src/builder.rs | 8 +- misskey-util/src/builder/admin.rs | 12 +- misskey-util/src/builder/me.rs | 5 + misskey-util/src/client.rs | 214 +++++++++++++++++- misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 21 files changed, 495 insertions(+), 24 deletions(-) create mode 100644 misskey-api/src/endpoint/users/reactions.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index daf81732..7428721d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.92.0' + MISSKEY_IMAGE: 'misskey/misskey:12.93.0' MISSKEY_ID: aid - - run: cargo test --features 12-92-0 + - run: cargo test --features 12-93-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 4479b6ee..858f1c86 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.93.0' + flags: --features 12-93-0 - image: 'misskey/misskey:12.92.0' flags: --features 12-92-0 - image: 'misskey/misskey:12.91.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 1d184dde..a2bc2c33 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.92.0' + MISSKEY_IMAGE: 'misskey/misskey:12.93.0' MISSKEY_ID: aid - - run: cargo test --features 12-92-0 + - run: cargo test --features 12-93-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 86aedb1b..1ef66084 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -50,6 +50,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.92.0 - endpoint `email-address/available` - endpoint `users/groups/leave` +- Partial support for Misskey v12.93.0 ~ v12.94.1 + - endpoint `users/reactions` ### Changed ### Deprecated @@ -62,6 +64,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - For Misskey v12.88.0 - endpoint `users/recommendation` - For Misskey v12.88.0 ~ +- endpoint `admin/logs` and `admin/delete-logs` + - For Misskey v12.93.0 ~ ### Fixed diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 5149ef49..9923ac33 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-93-0 = ["12-92-0"] 12-92-0 = ["12-91-0"] 12-91-0 = ["12-89-1"] 12-89-1 = ["12-89-0"] diff --git a/misskey-api/src/endpoint/admin.rs b/misskey-api/src/endpoint/admin.rs index bf5fd769..9eca0c8d 100644 --- a/misskey-api/src/endpoint/admin.rs +++ b/misskey-api/src/endpoint/admin.rs @@ -1,11 +1,9 @@ pub mod abuse_user_reports; pub mod accounts; pub mod announcements; -pub mod delete_logs; pub mod emoji; pub mod get_table_stats; pub mod invite; -pub mod logs; pub mod moderators; pub mod reset_password; pub mod resync_chart; @@ -39,3 +37,11 @@ pub mod ad; #[cfg(feature = "12-81-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] pub mod get_index_stats; + +#[cfg(not(feature = "12-93-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-93-0"))))] +pub mod delete_logs; + +#[cfg(not(feature = "12-93-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-93-0"))))] +pub mod logs; diff --git a/misskey-api/src/endpoint/i/update.rs b/misskey-api/src/endpoint/i/update.rs index bb878603..b24cd025 100644 --- a/misskey-api/src/endpoint/i/update.rs +++ b/misskey-api/src/endpoint/i/update.rs @@ -57,6 +57,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub hide_online_status: Option, + #[cfg(feature = "12-93-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-93-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub public_reactions: Option, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub careful_bot: Option, @@ -156,6 +161,8 @@ mod tests { is_explorable: Some(false), #[cfg(feature = "12-77-0")] hide_online_status: Some(true), + #[cfg(feature = "12-93-0")] + public_reactions: Some(true), careful_bot: Some(true), auto_accept_followed: Some(true), is_bot: Some(true), @@ -210,6 +217,8 @@ mod tests { is_explorable: None, #[cfg(feature = "12-77-0")] hide_online_status: None, + #[cfg(feature = "12-93-0")] + public_reactions: None, careful_bot: None, auto_accept_followed: None, is_bot: None, diff --git a/misskey-api/src/endpoint/users.rs b/misskey-api/src/endpoint/users.rs index 51df0833..8aaccf3e 100644 --- a/misskey-api/src/endpoint/users.rs +++ b/misskey-api/src/endpoint/users.rs @@ -44,6 +44,10 @@ pub mod gallery; #[cfg_attr(docsrs, doc(cfg(not(feature = "12-88-0"))))] pub mod recommendation; +#[cfg(feature = "12-93-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-93-0")))] +pub mod reactions; + #[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] #[derive(Serialize, PartialEq, Eq, Clone, Debug, Copy)] #[serde(rename_all = "camelCase")] diff --git a/misskey-api/src/endpoint/users/reactions.rs b/misskey-api/src/endpoint/users/reactions.rs new file mode 100644 index 00000000..46bf942c --- /dev/null +++ b/misskey-api/src/endpoint/users/reactions.rs @@ -0,0 +1,129 @@ +use crate::model::{id::Id, note_reaction::NoteReaction, user::User}; + +use chrono::{serde::ts_milliseconds_option, DateTime, Utc}; +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + pub user_id: Id, + /// 1 .. 100 + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub since_id: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub until_id: Option>, + #[serde( + skip_serializing_if = "Option::is_none", + with = "ts_milliseconds_option" + )] + #[builder(default, setter(strip_option, into))] + pub since_date: Option>, + #[serde( + skip_serializing_if = "Option::is_none", + with = "ts_milliseconds_option" + )] + #[builder(default, setter(strip_option, into))] + pub until_date: Option>, +} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "users/reactions"; +} + +impl_pagination!(Request, NoteReaction); + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let user = client.me().await; + + client + .test(Request { + user_id: user.id, + limit: None, + since_id: None, + until_id: None, + since_date: None, + until_date: None, + }) + .await; + } + + #[tokio::test] + async fn request_with_limit() { + let client = TestClient::new(); + let user = client.me().await; + + client + .test(Request { + user_id: user.id, + limit: Some(100), + since_id: None, + until_id: None, + since_date: None, + until_date: None, + }) + .await; + } + + #[tokio::test] + async fn request_paginate() { + let client = TestClient::new(); + let user = client.user.me().await; + let note = client.admin.create_note(Some("hello"), None, None).await; + + client + .user + .test(crate::endpoint::notes::reactions::create::Request { + note_id: note.id, + reaction: "👍".into(), + }) + .await; + + let reactions = client + .test(Request::builder().user_id(user.id).build()) + .await; + + client + .test(Request { + user_id: user.id, + limit: None, + since_id: Some(reactions[0].id.clone()), + until_id: Some(reactions[0].id.clone()), + since_date: None, + until_date: None, + }) + .await; + } + + #[tokio::test] + async fn request_with_date() { + let client = TestClient::new(); + let user = client.me().await; + let now = chrono::Utc::now(); + + client + .test(Request { + user_id: user.id, + limit: None, + since_id: None, + until_id: None, + since_date: Some(now), + until_date: Some(now), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/users/search.rs b/misskey-api/src/endpoint/users/search.rs index 7ae91a79..05aed34c 100644 --- a/misskey-api/src/endpoint/users/search.rs +++ b/misskey-api/src/endpoint/users/search.rs @@ -1,4 +1,6 @@ use crate::model::user::User; +#[cfg(feature = "12-93-0")] +use crate::model::user::UserOrigin; use serde::Serialize; use typed_builder::TypedBuilder; @@ -9,9 +11,16 @@ use typed_builder::TypedBuilder; pub struct Request { #[builder(setter(into))] pub query: String, + #[cfg(not(feature = "12-93-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-93-0"))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub local_only: Option, + #[cfg(feature = "12-93-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-93-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub origin: Option, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub detail: Option, @@ -42,7 +51,10 @@ mod tests { client .test(Request { query: "test".to_string(), + #[cfg(not(feature = "12-93-0"))] local_only: None, + #[cfg(feature = "12-93-0")] + origin: None, detail: None, limit: None, offset: None, @@ -56,7 +68,10 @@ mod tests { client .test(Request { query: "admin".to_string(), + #[cfg(not(feature = "12-93-0"))] local_only: Some(true), + #[cfg(feature = "12-93-0")] + origin: None, detail: Some(false), limit: None, offset: None, @@ -64,13 +79,51 @@ mod tests { .await; } + #[cfg(feature = "12-93-0")] + #[tokio::test] + async fn request_with_origin() { + use crate::model::user::UserOrigin; + + let client = TestClient::new(); + client + .test(Request { + query: "test".to_string(), + origin: Some(UserOrigin::Local), + detail: None, + limit: None, + offset: None, + }) + .await; + client + .test(Request { + query: "test".to_string(), + origin: Some(UserOrigin::Remote), + detail: None, + limit: None, + offset: None, + }) + .await; + client + .test(Request { + query: "test".to_string(), + origin: Some(UserOrigin::Combined), + detail: None, + limit: None, + offset: None, + }) + .await; + } + #[tokio::test] async fn request_with_limit() { let client = TestClient::new(); client .test(Request { query: "test".to_string(), + #[cfg(not(feature = "12-93-0"))] local_only: None, + #[cfg(feature = "12-93-0")] + origin: None, detail: None, limit: Some(100), offset: None, @@ -84,7 +137,10 @@ mod tests { client .test(Request { query: "admin".to_string(), + #[cfg(not(feature = "12-93-0"))] local_only: None, + #[cfg(feature = "12-93-0")] + origin: None, detail: None, limit: None, offset: Some(5), diff --git a/misskey-api/src/endpoint/users/search_by_username_and_host.rs b/misskey-api/src/endpoint/users/search_by_username_and_host.rs index 9139b126..e7425b02 100644 --- a/misskey-api/src/endpoint/users/search_by_username_and_host.rs +++ b/misskey-api/src/endpoint/users/search_by_username_and_host.rs @@ -18,6 +18,8 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub limit: Option, + #[cfg(not(feature = "12-93-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-93-0"))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub offset: Option, @@ -28,6 +30,7 @@ impl misskey_core::Request for Request { const ENDPOINT: &'static str = "users/search-by-username-and-host"; } +#[cfg(not(feature = "12-93-0"))] impl_offset_pagination!(Request, User); #[cfg(test)] @@ -44,6 +47,7 @@ mod tests { host: None, detail: None, limit: None, + #[cfg(not(feature = "12-93-0"))] offset: None, }) .await; @@ -58,6 +62,7 @@ mod tests { host: Some("dummy".to_string()), // TODO: use proper host string detail: None, limit: None, + #[cfg(not(feature = "12-93-0"))] offset: None, }) .await; @@ -72,6 +77,7 @@ mod tests { host: None, detail: Some(false), limit: None, + #[cfg(not(feature = "12-93-0"))] offset: None, }) .await; @@ -86,11 +92,13 @@ mod tests { host: None, detail: None, limit: Some(100), + #[cfg(not(feature = "12-93-0"))] offset: None, }) .await; } + #[cfg(not(feature = "12-93-0"))] #[tokio::test] async fn request_with_offset() { let client = TestClient::new(); diff --git a/misskey-api/src/model/note_reaction.rs b/misskey-api/src/model/note_reaction.rs index ebcf3f99..e77ebfe7 100644 --- a/misskey-api/src/model/note_reaction.rs +++ b/misskey-api/src/model/note_reaction.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "12-93-0")] +use crate::model::note::Note; use crate::model::{id::Id, note::Reaction, user::User}; use chrono::{DateTime, Utc}; @@ -11,6 +13,10 @@ pub struct NoteReaction { pub user: User, #[serde(rename = "type")] pub type_: Reaction, + #[cfg(feature = "12-93-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-93-0")))] + #[serde(default)] + pub note: Option, } impl_entity!(NoteReaction); diff --git a/misskey-api/src/model/notification.rs b/misskey-api/src/model/notification.rs index e50db775..ca4dca0f 100644 --- a/misskey-api/src/model/notification.rs +++ b/misskey-api/src/model/notification.rs @@ -43,15 +43,34 @@ pub enum NotificationBody { Follow, FollowRequestAccepted, ReceiveFollowRequest, - Mention { note: Note }, - Reply { note: Note }, - Renote { note: Note }, - Quote { note: Note }, - Reaction { note: Note, reaction: Reaction }, - PollVote { note: Note, choice: u64 }, - GroupInvited { invitation: UserGroupInvitation }, - // TODO: Implement - App {}, + Mention { + note: Note, + }, + Reply { + note: Note, + }, + Renote { + note: Note, + }, + Quote { + note: Note, + }, + Reaction { + note: Note, + reaction: Reaction, + }, + PollVote { + note: Note, + choice: u64, + }, + GroupInvited { + invitation: UserGroupInvitation, + }, + App { + body: Option, + header: Option, + icon: Option, + }, } #[derive(Debug, Error, Clone)] diff --git a/misskey-util/CHANGELOG.md b/misskey-util/CHANGELOG.md index 4a667846..534a8d72 100644 --- a/misskey-util/CHANGELOG.md +++ b/misskey-util/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Registry APIs - Page APIs - Gallery APIs +- Reactions APIs ### Changed ### Deprecated @@ -22,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - For Misskey v12.88.0 - `ClientExt::recommended_users` - For Misskey v12.88.0 ~ +- `ClientExt::server_logs` + - For Misskey v12.93.0 ~ ### Fixed ### Security diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 4a4c3cec..fe4f4760 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-93-0 = ["misskey-api/12-93-0", "12-92-0"] 12-92-0 = ["misskey-api/12-92-0", "12-91-0"] 12-91-0 = ["misskey-api/12-91-0", "12-89-1"] 12-89-1 = ["misskey-api/12-89-1", "12-89-0"] diff --git a/misskey-util/src/builder.rs b/misskey-util/src/builder.rs index 80f72a50..87fdb60e 100644 --- a/misskey-util/src/builder.rs +++ b/misskey-util/src/builder.rs @@ -27,9 +27,7 @@ mod gallery; #[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] mod user; -pub use admin::{ - AnnouncementUpdateBuilder, EmojiUpdateBuilder, MetaUpdateBuilder, ServerLogListBuilder, -}; +pub use admin::{AnnouncementUpdateBuilder, EmojiUpdateBuilder, MetaUpdateBuilder}; pub use antenna::{AntennaBuilder, AntennaUpdateBuilder}; pub use clip::{ClipBuilder, ClipUpdateBuilder}; pub use drive::{ @@ -65,3 +63,7 @@ pub use admin::{AdBuilder, AdUpdateBuilder}; #[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] #[cfg_attr(docsrs, doc(cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))))] pub use user::UserListBuilder; + +#[cfg(not(feature = "12-93-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-93-0"))))] +pub use admin::ServerLogListBuilder; diff --git a/misskey-util/src/builder/admin.rs b/misskey-util/src/builder/admin.rs index 8eb476a5..78ba8e81 100644 --- a/misskey-util/src/builder/admin.rs +++ b/misskey-util/src/builder/admin.rs @@ -8,21 +8,22 @@ use misskey_api::model::ad::{Ad, Place, Priority}; use misskey_api::model::clip::Clip; #[cfg(feature = "12-9-0")] use misskey_api::model::emoji::Emoji; -use misskey_api::model::{ - announcement::Announcement, - log::{Log, LogLevel}, - user::User, -}; +#[cfg(not(feature = "12-93-0"))] +use misskey_api::model::log::{Log, LogLevel}; +use misskey_api::model::{announcement::Announcement, user::User}; use misskey_api::{endpoint, EntityRef}; use misskey_core::Client; use url::Url; +#[cfg(not(feature = "12-93-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-93-0"))))] /// Builder for the [`server_logs`][`crate::ClientExt::server_logs`] method. pub struct ServerLogListBuilder { client: C, request: endpoint::admin::logs::Request, } +#[cfg(not(feature = "12-93-0"))] impl ServerLogListBuilder { /// Creates a builder with the client. pub fn new(client: C) -> Self { @@ -109,6 +110,7 @@ impl ServerLogListBuilder { } } +#[cfg(not(feature = "12-93-0"))] impl ServerLogListBuilder { /// Lists the logs. pub async fn list(&self) -> Result, Error> { diff --git a/misskey-util/src/builder/me.rs b/misskey-util/src/builder/me.rs index b076e214..fa9bb045 100644 --- a/misskey-util/src/builder/me.rs +++ b/misskey-util/src/builder/me.rs @@ -157,6 +157,11 @@ impl MeUpdateBuilder { #[cfg_attr(docsrs, doc(cfg(feature = "12-77-0")))] pub hide_online_status; + /// Sets whether to make the reactions public. + #[cfg(feature = "12-93-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-93-0")))] + pub public_reactions; + /// Sets whether this user requires a follow request from bots. pub require_follow_request_for_bot { careful_bot }; diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index 513762ac..2c3edf82 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -10,6 +10,8 @@ use crate::builder::GalleryPostBuilder; use crate::builder::GalleryPostUpdateBuilder; #[cfg(feature = "12-27-0")] use crate::builder::NotificationBuilder; +#[cfg(not(feature = "12-93-0"))] +use crate::builder::ServerLogListBuilder; #[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] use crate::builder::UserListBuilder; #[cfg(feature = "12-80-0")] @@ -18,7 +20,7 @@ use crate::builder::{ AnnouncementUpdateBuilder, AntennaBuilder, AntennaUpdateBuilder, DriveFileBuilder, DriveFileListBuilder, DriveFileUpdateBuilder, DriveFileUrlBuilder, DriveFolderUpdateBuilder, MeUpdateBuilder, MessagingMessageBuilder, MetaUpdateBuilder, NoteBuilder, PageBuilder, - PageUpdateBuilder, ServerLogListBuilder, + PageUpdateBuilder, }; #[cfg(feature = "12-47-0")] use crate::builder::{ChannelBuilder, ChannelUpdateBuilder}; @@ -41,6 +43,8 @@ use misskey_api::model::channel::Channel; use misskey_api::model::gallery::GalleryPost; #[cfg(feature = "12-67-0")] use misskey_api::model::registry::{RegistryKey, RegistryScope, RegistryValue}; +#[cfg(feature = "12-93-0")] +use misskey_api::model::user::UserOrigin; use misskey_api::model::{ abuse_user_report::AbuseUserReport, announcement::Announcement, @@ -54,6 +58,7 @@ use misskey_api::model::{ messaging::MessagingMessage, meta::Meta, note::{Note, Reaction, Tag}, + note_reaction::NoteReaction, notification::Notification, page::Page, query::Query, @@ -897,6 +902,34 @@ pub trait ClientExt: Client + Sync { PagerStream::new(Box::pin(pager)) } + /// Searches for users in the instance with the specified query string. + #[cfg(feature = "12-93-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-93-0")))] + fn search_local_users(&self, query: impl Into) -> PagerStream> { + let pager = OffsetPager::new( + self, + endpoint::users::search::Request::builder() + .query(query) + .origin(UserOrigin::Local) + .build(), + ); + PagerStream::new(Box::pin(pager)) + } + + /// Searches for users in remote instances with the specified query string. + #[cfg(feature = "12-93-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-93-0")))] + fn search_remote_users(&self, query: impl Into) -> PagerStream> { + let pager = OffsetPager::new( + self, + endpoint::users::search::Request::builder() + .query(query) + .origin(UserOrigin::Remote) + .build(), + ); + PagerStream::new(Box::pin(pager)) + } + /// Lists the users in the instance. /// /// This method actually returns a builder, namely [`UserListBuilder`]. @@ -3480,6 +3513,183 @@ pub trait ClientExt: Client + Sync { } // }}} + // {{{ Reactions + /// Lists the reactions to the specified note. + fn note_reactions( + &self, + note: impl EntityRef, + ) -> PagerStream> { + let pager = OffsetPager::new( + self, + endpoint::notes::reactions::Request::builder() + .note_id(note.entity_ref()) + .build(), + ); + PagerStream::new(Box::pin(pager)) + } + + /// Lists the reactions from the specified user in the specified range of time. + /// + /// The bound `Into>` on the argument type is satisfied by the type + /// of some range expressions such as `..` or `start..` (which are desugared into [`RangeFull`][range_full] and + /// [`RangeFrom`][range_from] respectively). A reaction or [`DateTime`][datetime] can + /// be used to specify the start and end bounds of the range. + /// + /// [range_full]: std::ops::RangeFull + /// [range_from]: std::ops::RangeFrom + /// [datetime]: chrono::DateTime + /// + /// # Examples + /// + /// ``` + /// # use misskey_util::ClientExt; + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let client = misskey_test::test_client().await?; + /// # let user = client.me().await?; + /// use futures::stream::{StreamExt, TryStreamExt}; + /// use chrono::Utc; + /// + /// // `reactions` variable here is a `Stream` to enumerate first 100 reactions. + /// let mut reactions = client.user_reactions(&user, ..).take(100); + /// + /// // Retrieve all reactions until there are no more. + /// while let Some(reaction) = reactions.try_next().await? { + /// // Print the type of reaction. + /// println!("{}", reaction.type_); + /// } + /// # Ok(()) + /// # } + /// ``` + /// + /// ``` + /// # use misskey_util::ClientExt; + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let client = misskey_test::test_client().await?; + /// # let user = client.me().await?; + /// use chrono::{Duration, Utc}; + /// + /// // Get the user reactions since `time`. + /// let time = Utc::now() - Duration::days(1); + /// let mut notes = client.user_notes(&user, time..); + /// # Ok(()) + /// # } + /// ``` + #[cfg(feature = "12-93-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-93-0")))] + fn user_reactions( + &self, + user: impl EntityRef, + range: impl Into>, + ) -> PagerStream> { + let user_id = user.entity_ref(); + let base_request = endpoint::users::reactions::Request::builder() + .user_id(user_id) + .build(); + let pager = match range.into() { + TimelineRange::Id { + since_id, + until_id: None, + } => BackwardPager::with_since_id(self, since_id, base_request), + TimelineRange::Id { + since_id, + until_id: Some(until_id), + } => BackwardPager::new( + self, + endpoint::users::reactions::Request { + since_id, + until_id: Some(until_id), + ..base_request + }, + ), + TimelineRange::DateTime { + since_date, + until_date, + } => BackwardPager::new( + self, + endpoint::users::reactions::Request { + since_date, + until_date: Some(until_date.unwrap_or_else(Utc::now)), + ..base_request + }, + ), + TimelineRange::Unbounded => BackwardPager::new(self, base_request), + }; + PagerStream::new(Box::pin(pager)) + } + + /// Lists the reactions from the specified user since the specified point in reverse order (i.e. the old reaction comes first, the new reaction comes after). + /// + /// # Examples + /// + /// ``` + /// # use misskey_util::ClientExt; + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let client = misskey_test::test_client().await?; + /// # let user = client.me().await?; + /// use futures::stream::{StreamExt, TryStreamExt}; + /// use chrono::{Duration, Utc}; + /// + /// let time = Utc::now() - Duration::days(1); + /// + /// // `reactions_since` variable here is a `Stream` to enumerate first 100 reactions. + /// let mut reactions_since = client.user_reactions_since(&user, time).take(100); + /// + /// // Retrieve all reactions until there are no more. + /// while let Some(reaction) = reactions_since.try_next().await? { + /// // Print the type of reaction. + /// println!("{}", reaction.type_); + /// } + /// # Ok(()) + /// # } + /// ``` + #[cfg(feature = "12-93-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-93-0")))] + fn user_reactions_since( + &self, + user: impl EntityRef, + since: impl Into>, + ) -> PagerStream> { + let user_id = user.entity_ref(); + let base_request = endpoint::users::reactions::Request::builder() + .user_id(user_id) + .build(); + let request = match since.into() { + TimelineCursor::DateTime(since_date) => endpoint::users::reactions::Request { + since_date: Some(since_date), + ..base_request + }, + TimelineCursor::Id(since_id) => endpoint::users::reactions::Request { + since_id: Some(since_id), + ..base_request + }, + }; + let pager = ForwardPager::new(self, request); + PagerStream::new(Box::pin(pager)) + } + + /// Returns a set of streams that fetch reactions from the specified user around the specified point. + #[cfg(feature = "12-93-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-93-0")))] + fn user_reactions_around( + &self, + user: impl EntityRef, + cursor: impl Into>, + ) -> ( + PagerStream>, + PagerStream>, + ) { + let cursor = cursor.into(); + let user_id = user.entity_ref(); + ( + self.user_reactions_since(user_id, cursor), + self.user_reactions(user_id, TimelineRange::until(cursor)), + ) + } + // }}} + // {{{ Admin /// Sets moderator privileges for the specified user. /// @@ -3616,6 +3826,8 @@ pub trait ClientExt: Client + Sync { /// # Ok(()) /// # } /// ``` + #[cfg(not(feature = "12-93-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-93-0"))))] fn server_logs(&self) -> ServerLogListBuilder<&Self> { ServerLogListBuilder::new(self) } diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 6a4ddd57..bbfb8e3f 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-93-0 = ["misskey-api/12-93-0", "misskey-util/12-93-0"] 12-92-0 = ["misskey-api/12-92-0", "misskey-util/12-92-0"] 12-91-0 = ["misskey-api/12-91-0", "misskey-util/12-91-0"] 12-89-1 = ["misskey-api/12-89-1", "misskey-util/12-89-1"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 50e3d6f7..1bbf03d2 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-93-0` | v12.93.0 ~ v12.94.1 | v12.93.0 | //! | `12-92-0` | v12.92.0 | v12.92.0 | //! | `12-91-0` | v12.91.0 | v12.91.0 | //! | `12-89-1` | v12.89.1 ~ v12.90.1 | v12.89.1 | From 185470a345685cce5a7896e3febf966441c61a94 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Thu, 13 Apr 2023 11:12:51 +0900 Subject: [PATCH 17/44] Add: Support v12.95.0 --- .github/workflows/ci.yml | 4 +-- .github/workflows/flaky.yml | 2 ++ .github/workflows/unstable.yml | 4 +-- misskey-api/CHANGELOG.md | 2 ++ misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/notes.rs | 4 +++ misskey-api/src/endpoint/notes/state.rs | 3 ++ .../src/endpoint/notes/thread_muting.rs | 2 ++ .../endpoint/notes/thread_muting/create.rs | 28 ++++++++++++++++ .../endpoint/notes/thread_muting/delete.rs | 32 +++++++++++++++++++ misskey-util/Cargo.toml | 1 + misskey-util/src/client.rs | 31 ++++++++++++++++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 14 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 misskey-api/src/endpoint/notes/thread_muting.rs create mode 100644 misskey-api/src/endpoint/notes/thread_muting/create.rs create mode 100644 misskey-api/src/endpoint/notes/thread_muting/delete.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7428721d..57ee8a53 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.93.0' + MISSKEY_IMAGE: 'misskey/misskey:12.95.0' MISSKEY_ID: aid - - run: cargo test --features 12-93-0 + - run: cargo test --features 12-95-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 858f1c86..1a170610 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.95.0' + flags: --features 12-95-0 - image: 'misskey/misskey:12.93.0' flags: --features 12-93-0 - image: 'misskey/misskey:12.92.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index a2bc2c33..ed00d18d 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.93.0' + MISSKEY_IMAGE: 'misskey/misskey:12.95.0' MISSKEY_ID: aid - - run: cargo test --features 12-93-0 + - run: cargo test --features 12-95-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 1ef66084..fed0e905 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -52,6 +52,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint `users/groups/leave` - Partial support for Misskey v12.93.0 ~ v12.94.1 - endpoint `users/reactions` +- Support for Misskey v12.95.0 + - endpoint `notes/thread-muting/*` ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 9923ac33..eb07a5dc 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-95-0 = ["12-93-0"] 12-93-0 = ["12-92-0"] 12-92-0 = ["12-91-0"] 12-91-0 = ["12-89-1"] diff --git a/misskey-api/src/endpoint/notes.rs b/misskey-api/src/endpoint/notes.rs index 0c75a1d4..f5de3790 100644 --- a/misskey-api/src/endpoint/notes.rs +++ b/misskey-api/src/endpoint/notes.rs @@ -30,6 +30,10 @@ pub mod watching; #[cfg_attr(docsrs, doc(cfg(feature = "12-58-0")))] pub mod clips; +#[cfg(feature = "12-95-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-95-0")))] +pub mod thread_muting; + #[derive(Serialize, Default, Debug, Clone, TypedBuilder)] #[serde(rename_all = "camelCase")] #[builder(doc)] diff --git a/misskey-api/src/endpoint/notes/state.rs b/misskey-api/src/endpoint/notes/state.rs index c02c6b18..21923bea 100644 --- a/misskey-api/src/endpoint/notes/state.rs +++ b/misskey-api/src/endpoint/notes/state.rs @@ -13,6 +13,9 @@ pub struct Request { pub struct Response { pub is_favorited: bool, pub is_watching: bool, + #[cfg(feature = "12-95-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-95-0")))] + pub is_muted_thread: bool, } impl misskey_core::Request for Request { diff --git a/misskey-api/src/endpoint/notes/thread_muting.rs b/misskey-api/src/endpoint/notes/thread_muting.rs new file mode 100644 index 00000000..da1aa3ac --- /dev/null +++ b/misskey-api/src/endpoint/notes/thread_muting.rs @@ -0,0 +1,2 @@ +pub mod create; +pub mod delete; diff --git a/misskey-api/src/endpoint/notes/thread_muting/create.rs b/misskey-api/src/endpoint/notes/thread_muting/create.rs new file mode 100644 index 00000000..4cc00442 --- /dev/null +++ b/misskey-api/src/endpoint/notes/thread_muting/create.rs @@ -0,0 +1,28 @@ +use crate::model::{id::Id, note::Note}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub note_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "notes/thread-muting/create"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let note = client.create_note(Some("test"), None, None).await; + + client.test(Request { note_id: note.id }).await; + } +} diff --git a/misskey-api/src/endpoint/notes/thread_muting/delete.rs b/misskey-api/src/endpoint/notes/thread_muting/delete.rs new file mode 100644 index 00000000..5319886b --- /dev/null +++ b/misskey-api/src/endpoint/notes/thread_muting/delete.rs @@ -0,0 +1,32 @@ +use crate::model::{id::Id, note::Note}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub note_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "notes/thread-muting/delete"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let note = client.create_note(Some("test"), None, None).await; + + client + .test(crate::endpoint::notes::thread_muting::create::Request { note_id: note.id }) + .await; + + client.test(Request { note_id: note.id }).await; + } +} diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index fe4f4760..a400be5f 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-95-0 = ["misskey-api/12-95-0", "12-93-0"] 12-93-0 = ["misskey-api/12-93-0", "12-92-0"] 12-92-0 = ["misskey-api/12-92-0", "12-91-0"] 12-91-0 = ["misskey-api/12-91-0", "12-89-1"] diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index 2c3edf82..47817b5f 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -1248,6 +1248,37 @@ pub trait ClientExt: Client + Sync { }) } + /// Mutes notifications from threads where the specified note belongs to. + #[cfg(feature = "12-95-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-95-0")))] + fn mute_thread(&self, note: impl EntityRef) -> BoxFuture>> { + let note_id = note.entity_ref(); + Box::pin(async move { + self.request(endpoint::notes::thread_muting::create::Request { note_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + + /// Unmutes notifications from threads where the specified note belongs to. + #[cfg(feature = "12-95-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-95-0")))] + fn unmute_thread( + &self, + note: impl EntityRef, + ) -> BoxFuture>> { + let note_id = note.entity_ref(); + Box::pin(async move { + self.request(endpoint::notes::thread_muting::delete::Request { note_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + /// Checks if the specified note is favorited by the user logged in with this client. fn is_favorited( &self, diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index bbfb8e3f..b8e1ea6d 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-95-0 = ["misskey-api/12-95-0", "misskey-util/12-95-0"] 12-93-0 = ["misskey-api/12-93-0", "misskey-util/12-93-0"] 12-92-0 = ["misskey-api/12-92-0", "misskey-util/12-92-0"] 12-91-0 = ["misskey-api/12-91-0", "misskey-util/12-91-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 1bbf03d2..fac229c8 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-95-0` | v12.95.0 | v12.95.0 | //! | `12-93-0` | v12.93.0 ~ v12.94.1 | v12.93.0 | //! | `12-92-0` | v12.92.0 | v12.92.0 | //! | `12-91-0` | v12.91.0 | v12.91.0 | From 3e22ccecbf47c278183fa41df7f035127147743b Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Thu, 13 Apr 2023 19:11:13 +0900 Subject: [PATCH 18/44] Add: Support v12.96.0 --- .github/workflows/ci.yml | 4 +-- .github/workflows/flaky.yml | 2 ++ .github/workflows/unstable.yml | 4 +-- misskey-api/CHANGELOG.md | 1 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/i/update.rs | 13 ++++++++ misskey-api/src/endpoint/notes/create.rs | 16 +++++++++ misskey-api/src/model/note.rs | 2 ++ misskey-api/src/model/user.rs | 41 ++++++++++++++++++++++++ misskey-api/src/test.rs | 1 + misskey-util/Cargo.toml | 1 + misskey-util/src/builder/me.rs | 37 +++++++++++++++++++++ misskey-util/src/builder/note.rs | 3 ++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 15 files changed, 124 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57ee8a53..491de9fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.95.0' + MISSKEY_IMAGE: 'misskey/misskey:12.97.0' MISSKEY_ID: aid - - run: cargo test --features 12-95-0 + - run: cargo test --features 12-96-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 1a170610..79ce52e1 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.97.0' + flags: --features 12-96-0 - image: 'misskey/misskey:12.95.0' flags: --features 12-95-0 - image: 'misskey/misskey:12.93.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index ed00d18d..05cbd287 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.95.0' + MISSKEY_IMAGE: 'misskey/misskey:12.97.0' MISSKEY_ID: aid - - run: cargo test --features 12-95-0 + - run: cargo test --features 12-96-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index fed0e905..529beb40 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -54,6 +54,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint `users/reactions` - Support for Misskey v12.95.0 - endpoint `notes/thread-muting/*` +- Support for Misskey v12.96.0 ~ v12.97.1 ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index eb07a5dc..675d845e 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-96-0 = ["12-95-0"] 12-95-0 = ["12-93-0"] 12-93-0 = ["12-92-0"] 12-92-0 = ["12-91-0"] diff --git a/misskey-api/src/endpoint/i/update.rs b/misskey-api/src/endpoint/i/update.rs index b24cd025..4ae006de 100644 --- a/misskey-api/src/endpoint/i/update.rs +++ b/misskey-api/src/endpoint/i/update.rs @@ -3,6 +3,8 @@ use std::collections::HashSet; #[cfg(feature = "12-48-0")] use crate::model::notification::NotificationType; +#[cfg(feature = "12-96-0")] +use crate::model::user::FfVisibility; #[cfg(feature = "12-70-0")] use crate::model::user::UserEmailNotificationType; use crate::model::{drive::DriveFile, id::Id, page::Page, query::Query, user::User}; @@ -85,6 +87,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub always_mark_nsfw: Option, + #[cfg(feature = "12-96-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-96-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub ff_visibility: Option, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub pinned_page_id: Option>>, @@ -134,6 +141,8 @@ mod tests { #[cfg(feature = "12-48-0")] use crate::model::notification::NotificationType; use crate::model::query::Query; + #[cfg(feature = "12-96-0")] + use crate::model::user::FfVisibility; #[cfg(feature = "12-70-0")] use crate::model::user::UserEmailNotificationType; @@ -171,6 +180,8 @@ mod tests { auto_watch: Some(true), inject_featured_note: Some(true), always_mark_nsfw: Some(true), + #[cfg(feature = "12-96-0")] + ff_visibility: Some(FfVisibility::Public), pinned_page_id: None, muted_words: Some(Query::from_vec(vec![ vec!["mute1".to_string(), "mute2".to_string()], @@ -227,6 +238,8 @@ mod tests { auto_watch: None, inject_featured_note: None, always_mark_nsfw: None, + #[cfg(feature = "12-96-0")] + ff_visibility: None, pinned_page_id: Some(None), muted_words: None, #[cfg(feature = "12-60-0")] diff --git a/misskey-api/src/endpoint/notes/create.rs b/misskey-api/src/endpoint/notes/create.rs index 9cedf13f..2b56e677 100644 --- a/misskey-api/src/endpoint/notes/create.rs +++ b/misskey-api/src/endpoint/notes/create.rs @@ -60,6 +60,8 @@ pub struct Request { pub text: Option, #[builder(default, setter(strip_option, into))] pub cw: Option, + #[cfg(not(feature = "12-96-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-96-0"))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub via_mobile: Option, @@ -119,6 +121,7 @@ mod tests { visible_user_ids: None, text: Some("some text".to_string()), cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, @@ -143,6 +146,7 @@ mod tests { visible_user_ids: None, text: Some("aww yeah".to_string()), cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: Some(true), local_only: Some(true), no_extract_mentions: Some(true), @@ -167,6 +171,7 @@ mod tests { visible_user_ids: None, text: Some("!".to_string()), cw: Some("nsfw".to_string()), + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, @@ -193,6 +198,7 @@ mod tests { visible_user_ids: None, text: Some("hello home".to_string()), cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, @@ -212,6 +218,7 @@ mod tests { visible_user_ids: None, text: Some("hello public".to_string()), cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, @@ -231,6 +238,7 @@ mod tests { visible_user_ids: None, text: Some("hello followers".to_string()), cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, @@ -253,6 +261,7 @@ mod tests { visible_user_ids: Some(vec![admin.id]), text: Some("hello specific person".to_string()), cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, @@ -277,6 +286,7 @@ mod tests { visible_user_ids: None, text: Some("renote".to_string()), cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, @@ -297,6 +307,7 @@ mod tests { visible_user_ids: None, text: None, cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, @@ -321,6 +332,7 @@ mod tests { visible_user_ids: None, text: Some("reply".to_string()), cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, @@ -341,6 +353,7 @@ mod tests { visible_user_ids: None, text: Some("hey".to_string()), cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, @@ -380,6 +393,7 @@ mod tests { visible_user_ids: None, text: Some("poll".to_string()), cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, @@ -408,6 +422,7 @@ mod tests { visible_user_ids: None, text: Some("some text".to_string()), cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, @@ -441,6 +456,7 @@ mod tests { visible_user_ids: None, text: Some("hi channel".to_string()), cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, diff --git a/misskey-api/src/model/note.rs b/misskey-api/src/model/note.rs index 655e3599..35d791d8 100644 --- a/misskey-api/src/model/note.rs +++ b/misskey-api/src/model/note.rs @@ -136,6 +136,8 @@ pub struct Note { pub reply: Option>, #[serde(default)] pub renote: Option>, + #[cfg(not(feature = "12-96-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-96-0"))))] #[serde(default = "default_false")] pub via_mobile: bool, #[serde(default = "default_false")] diff --git a/misskey-api/src/model/user.rs b/misskey-api/src/model/user.rs index 72038550..b07adf76 100644 --- a/misskey-api/src/model/user.rs +++ b/misskey-api/src/model/user.rs @@ -111,6 +111,43 @@ impl Display for OnlineStatus { } } +#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, Copy, Hash)] +#[serde(rename_all = "camelCase")] +pub enum FfVisibility { + Public, + Followers, + Private, +} + +impl Display for FfVisibility { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + FfVisibility::Public => f.write_str("public"), + FfVisibility::Followers => f.write_str("followers"), + FfVisibility::Private => f.write_str("private"), + } + } +} + +#[derive(Debug, Error, Clone)] +#[error("invalid ff visibility")] +pub struct ParseFfVisibilityError { + _priv: (), +} + +impl std::str::FromStr for FfVisibility { + type Err = ParseFfVisibilityError; + + fn from_str(s: &str) -> Result { + match s { + "public" | "Public" => Ok(FfVisibility::Public), + "followers" | "Followers" => Ok(FfVisibility::Followers), + "private" | "Private" => Ok(FfVisibility::Private), + _ => Err(ParseFfVisibilityError { _priv: () }), + } + } +} + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct User { @@ -222,6 +259,10 @@ pub struct User { #[cfg_attr(docsrs, doc(cfg(feature = "12-77-0")))] #[serde(default)] pub hide_online_status: Option, + #[cfg(feature = "12-96-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-96-0")))] + #[serde(default)] + pub ff_visibility: Option, } fn default_false() -> bool { diff --git a/misskey-api/src/test.rs b/misskey-api/src/test.rs index a0460e95..87205b23 100644 --- a/misskey-api/src/test.rs +++ b/misskey-api/src/test.rs @@ -86,6 +86,7 @@ impl ClientExt for T { visible_user_ids: None, text: text.map(|x| x.to_string()), cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: None, local_only: None, no_extract_mentions: None, diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index a400be5f..4fb58afb 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-96-0 = ["misskey-api/12-96-0", "12-95-0"] 12-95-0 = ["misskey-api/12-95-0", "12-93-0"] 12-93-0 = ["misskey-api/12-93-0", "12-92-0"] 12-92-0 = ["misskey-api/12-92-0", "12-91-0"] diff --git a/misskey-util/src/builder/me.rs b/misskey-util/src/builder/me.rs index fa9bb045..3720c3d1 100644 --- a/misskey-util/src/builder/me.rs +++ b/misskey-util/src/builder/me.rs @@ -5,6 +5,8 @@ use crate::Error; #[cfg(feature = "12-48-0")] use misskey_api::model::notification::NotificationType; +#[cfg(feature = "12-96-0")] +use misskey_api::model::user::FfVisibility; #[cfg(feature = "12-70-0")] use misskey_api::model::user::UserEmailNotificationType; use misskey_api::model::{ @@ -197,6 +199,41 @@ impl MeUpdateBuilder { pub receive_announcement_email; } + /// Sets the visibility of following and followers. + #[cfg(feature = "12-96-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-96-0")))] + pub fn ff_visibility(&mut self, ff_visibility: impl Into) -> &mut Self { + self.request.ff_visibility.replace(ff_visibility.into()); + self + } + + /// Sets following/followers to be visible to everyone. + /// + /// This is equivalent to `.ff_visibility(FfVisibility::Public)`. + #[cfg(feature = "12-96-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-96-0")))] + pub fn ff_public(&mut self) -> &mut Self { + self.ff_visibility(FfVisibility::Public) + } + + /// Sets following/followers to be visible only to the followers. + /// + /// This is equivalent to `.ff_visibility(FfVisibility::Followers)`. + #[cfg(feature = "12-96-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-96-0")))] + pub fn ff_followers(&mut self) -> &mut Self { + self.ff_visibility(FfVisibility::Followers) + } + + /// Sets following/followers to be invisible to other users. + /// + /// This is equivalent to `.ff_visibility(FfVisibility::Private)`. + #[cfg(feature = "12-96-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-96-0")))] + pub fn ff_private(&mut self) -> &mut Self { + self.ff_visibility(FfVisibility::Private) + } + /// Sets the muted notification type for this user. /// /// Note that you can subsequently use this method to add more muted notification types to be used for updates. diff --git a/misskey-util/src/builder/note.rs b/misskey-util/src/builder/note.rs index e72c5bbc..bd625b62 100644 --- a/misskey-util/src/builder/note.rs +++ b/misskey-util/src/builder/note.rs @@ -17,6 +17,7 @@ fn initial_notes_create_request() -> endpoint::notes::create::Request { visible_user_ids: None, text: None, cw: None, + #[cfg(not(feature = "12-96-0"))] via_mobile: Some(false), local_only: Some(false), no_extract_mentions: Some(false), @@ -199,6 +200,8 @@ impl NoteBuilder { self } + #[cfg(not(feature = "12-96-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-96-0"))))] /// Sets whether to show the note as posted from a mobile device. pub fn via_mobile(&mut self, via_mobile: bool) -> &mut Self { self.request.via_mobile.replace(via_mobile); diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index b8e1ea6d..aa022d84 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-96-0 = ["misskey-api/12-96-0", "misskey-util/12-96-0"] 12-95-0 = ["misskey-api/12-95-0", "misskey-util/12-95-0"] 12-93-0 = ["misskey-api/12-93-0", "misskey-util/12-93-0"] 12-92-0 = ["misskey-api/12-92-0", "misskey-util/12-92-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index fac229c8..ab9f32fb 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-96-0` | v12.96.0 ~ v12.97.1 | v12.97.0 | //! | `12-95-0` | v12.95.0 | v12.95.0 | //! | `12-93-0` | v12.93.0 ~ v12.94.1 | v12.93.0 | //! | `12-92-0` | v12.92.0 | v12.92.0 | From 81d04a2a16061eb769b61c1e8f6914ec4f5ae5a7 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Thu, 13 Apr 2023 20:48:23 +0900 Subject: [PATCH 19/44] Add: Support v12.98.0 --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 2 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/antennas/notes.rs | 57 +++++++++++++++++++ misskey-api/src/endpoint/following.rs | 4 ++ .../src/endpoint/following/invalidate.rs | 36 ++++++++++++ misskey-api/src/model/drive.rs | 3 + misskey-util/Cargo.toml | 1 + misskey-util/src/client.rs | 29 ++++++++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 13 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 misskey-api/src/endpoint/following/invalidate.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 491de9fe..c3f0901e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.97.0' + MISSKEY_IMAGE: 'misskey/misskey:12.98.0' MISSKEY_ID: aid - - run: cargo test --features 12-96-0 + - run: cargo test --features 12-98-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 79ce52e1..bb6135d4 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.98.0' + flags: --features 12-98-0 - image: 'misskey/misskey:12.97.0' flags: --features 12-96-0 - image: 'misskey/misskey:12.95.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 05cbd287..8a2fec0a 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.97.0' + MISSKEY_IMAGE: 'misskey/misskey:12.98.0' MISSKEY_ID: aid - - run: cargo test --features 12-96-0 + - run: cargo test --features 12-98-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 529beb40..8633c353 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -55,6 +55,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.95.0 - endpoint `notes/thread-muting/*` - Support for Misskey v12.96.0 ~ v12.97.1 +- Support for Misskey v12.98.0 + - endpoint `following/invalidate` ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 675d845e..4fb91209 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-98-0 = ["12-96-0"] 12-96-0 = ["12-95-0"] 12-95-0 = ["12-93-0"] 12-93-0 = ["12-92-0"] diff --git a/misskey-api/src/endpoint/antennas/notes.rs b/misskey-api/src/endpoint/antennas/notes.rs index f72f3773..a78e9ebb 100644 --- a/misskey-api/src/endpoint/antennas/notes.rs +++ b/misskey-api/src/endpoint/antennas/notes.rs @@ -1,5 +1,7 @@ use crate::model::{antenna::Antenna, id::Id, note::Note}; +#[cfg(feature = "12-98-0")] +use chrono::{serde::ts_milliseconds_option, DateTime, Utc}; use serde::Serialize; use typed_builder::TypedBuilder; @@ -18,6 +20,22 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub until_id: Option>, + #[cfg(feature = "12-98-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-98-0")))] + #[serde( + skip_serializing_if = "Option::is_none", + with = "ts_milliseconds_option" + )] + #[builder(default, setter(strip_option, into))] + pub since_date: Option>, + #[cfg(feature = "12-98-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-98-0")))] + #[serde( + skip_serializing_if = "Option::is_none", + with = "ts_milliseconds_option" + )] + #[builder(default, setter(strip_option, into))] + pub until_date: Option>, } impl misskey_core::Request for Request { @@ -50,6 +68,10 @@ mod tests { limit: None, since_id: None, until_id: None, + #[cfg(feature = "12-98-0")] + since_date: None, + #[cfg(feature = "12-98-0")] + until_date: None, }) .await; } @@ -73,6 +95,10 @@ mod tests { limit: Some(100), since_id: None, until_id: None, + #[cfg(feature = "12-98-0")] + since_date: None, + #[cfg(feature = "12-98-0")] + until_date: None, }) .await; } @@ -100,6 +126,37 @@ mod tests { limit: None, since_id: Some(note.id.clone()), until_id: Some(note.id.clone()), + #[cfg(feature = "12-98-0")] + since_date: None, + #[cfg(feature = "12-98-0")] + until_date: None, + }) + .await; + } + + #[cfg(feature = "12-98-0")] + #[tokio::test] + async fn request_with_date() { + let client = TestClient::new(); + let antenna = client + .test( + crate::endpoint::antennas::create::Request::builder() + .name("test") + .keywords("hello awesome") + .build(), + ) + .await; + let now = chrono::Utc::now(); + + client + .user + .test(Request { + antenna_id: antenna.id, + limit: None, + since_id: None, + until_id: None, + since_date: Some(now), + until_date: Some(now), }) .await; } diff --git a/misskey-api/src/endpoint/following.rs b/misskey-api/src/endpoint/following.rs index ed2212af..843d2faa 100644 --- a/misskey-api/src/endpoint/following.rs +++ b/misskey-api/src/endpoint/following.rs @@ -1,3 +1,7 @@ pub mod create; pub mod delete; pub mod requests; + +#[cfg(feature = "12-98-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-98-0")))] +pub mod invalidate; diff --git a/misskey-api/src/endpoint/following/invalidate.rs b/misskey-api/src/endpoint/following/invalidate.rs new file mode 100644 index 00000000..d5fcfece --- /dev/null +++ b/misskey-api/src/endpoint/following/invalidate.rs @@ -0,0 +1,36 @@ +use crate::model::{id::Id, user::User}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub user_id: Id, +} + +impl misskey_core::Request for Request { + type Response = User; + const ENDPOINT: &'static str = "following/invalidate"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let user_id = client.user.me().await.id; + let (new_user, new_client) = client.admin.create_user().await; + + client + .user + .test(crate::endpoint::following::create::Request { + user_id: new_user.id, + }) + .await; + + new_client.test(Request { user_id }).await; + } +} diff --git a/misskey-api/src/model/drive.rs b/misskey-api/src/model/drive.rs index 0af114ef..57a212f0 100644 --- a/misskey-api/src/model/drive.rs +++ b/misskey-api/src/model/drive.rs @@ -14,6 +14,9 @@ pub struct DriveFileProperties { #[cfg(feature = "12-75-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-75-0")))] pub height: Option, + #[cfg(feature = "12-98-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-98-0")))] + pub orientation: Option, #[cfg(feature = "12-75-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-75-0")))] pub avg_color: Option, diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 4fb58afb..682be01a 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-98-0 = ["misskey-api/12-98-0", "12-96-0"] 12-96-0 = ["misskey-api/12-96-0", "12-95-0"] 12-95-0 = ["misskey-api/12-95-0", "12-93-0"] 12-93-0 = ["misskey-api/12-93-0", "12-92-0"] diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index 47817b5f..2ad6474e 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -97,6 +97,8 @@ macro_rules! impl_timeline_method { /// # #[cfg(feature = "12-47-0")] /// # let channel = client.create_channel("test").await?; /// # let list = client.create_user_list("test").await?; + /// # #[cfg(feature = "12-98-0")] + /// # let antenna = client.create_antenna("antenna", "misskey").await?; /// use futures::stream::{StreamExt, TryStreamExt}; /// #[doc = "// `notes` variable here is a `Stream` to enumerate first 100 " $timeline " notes."] @@ -123,6 +125,8 @@ macro_rules! impl_timeline_method { /// # #[cfg(feature = "12-47-0")] /// # let channel = client.create_channel("test").await?; /// # let list = client.create_user_list("test").await?; + /// # #[cfg(feature = "12-98-0")] + /// # let antenna = client.create_antenna("antenna", "misskey").await?; /// use chrono::Utc; /// #[doc = "// Get the " $timeline " notes since `time`."] @@ -195,6 +199,8 @@ macro_rules! impl_timeline_method { /// # #[cfg(feature = "12-47-0")] /// # let channel = client.create_channel("test").await?; /// # let list = client.create_user_list("test").await?; + /// # #[cfg(feature = "12-98-0")] + /// # let antenna = client.create_antenna("antenna", "misskey").await?; /// use futures::stream::{StreamExt, TryStreamExt}; /// use chrono::Utc; /// @@ -364,6 +370,24 @@ pub trait ClientExt: Client + Sync { }) } + #[cfg(feature = "12-98-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-98-0")))] + /// Removes follow from the specified user. + fn remove_follower( + &self, + user: impl EntityRef, + ) -> BoxFuture>> { + let user_id = user.entity_ref(); + Box::pin(async move { + let user = self + .request(endpoint::following::invalidate::Request { user_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(user) + }) + } + /// Mutes the specified user. fn mute(&self, user: impl EntityRef) -> BoxFuture>> { let user_id = user.entity_ref(); @@ -1404,6 +1428,9 @@ pub trait ClientExt: Client + Sync { #[cfg(feature = "12-47-0")] impl_timeline_method! { channel, channels::timeline, channel_id = channel : Channel } + #[cfg(feature = "12-98-0")] + impl_timeline_method! { antenna, antennas::notes, antenna_id = antenna : Antenna } + /// Lists the notes with tags as specified in the given query. /// /// # Examples @@ -2041,6 +2068,8 @@ pub trait ClientExt: Client + Sync { } /// Lists the notes that hit the specified antenna. + #[cfg(not(feature = "12-98-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-98-0"))))] fn antenna_notes(&self, antenna: impl EntityRef) -> PagerStream> { let pager = BackwardPager::new( self, diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index aa022d84..204a0ee0 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-98-0 = ["misskey-api/12-98-0", "misskey-util/12-98-0"] 12-96-0 = ["misskey-api/12-96-0", "misskey-util/12-96-0"] 12-95-0 = ["misskey-api/12-95-0", "misskey-util/12-95-0"] 12-93-0 = ["misskey-api/12-93-0", "misskey-util/12-93-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index ab9f32fb..4aed97c1 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-98-0` | v12.98.0 | v12.98.0 | //! | `12-96-0` | v12.96.0 ~ v12.97.1 | v12.97.0 | //! | `12-95-0` | v12.95.0 | v12.95.0 | //! | `12-93-0` | v12.93.0 ~ v12.94.1 | v12.93.0 | From 46d182af80141afd1c3c7c26428bc3b46063eda7 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Thu, 13 Apr 2023 21:39:18 +0900 Subject: [PATCH 20/44] Add: Partially support v12.99.0 endpoint `export-custom-emojis` is not supported --- .github/workflows/ci.yml | 4 ++-- .github/workflows/flaky.yml | 2 ++ .github/workflows/unstable.yml | 4 ++-- misskey-api/CHANGELOG.md | 1 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/i/update.rs | 9 +++++++++ misskey-api/src/model/user.rs | 3 +++ misskey-util/Cargo.toml | 1 + misskey-util/src/builder/me.rs | 7 +++++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 11 files changed, 30 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c3f0901e..c4a8b229 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.98.0' + MISSKEY_IMAGE: 'misskey/misskey:12.99.1' MISSKEY_ID: aid - - run: cargo test --features 12-98-0 + - run: cargo test --features 12-99-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index bb6135d4..9a721d42 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.99.1' + flags: --features 12-99-0 - image: 'misskey/misskey:12.98.0' flags: --features 12-98-0 - image: 'misskey/misskey:12.97.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 8a2fec0a..9f9d2d5b 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.98.0' + MISSKEY_IMAGE: 'misskey/misskey:12.99.1' MISSKEY_ID: aid - - run: cargo test --features 12-98-0 + - run: cargo test --features 12-99-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 8633c353..78657358 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -57,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.96.0 ~ v12.97.1 - Support for Misskey v12.98.0 - endpoint `following/invalidate` +- Partial support for Misskey v12.99.0 ~ v12.101.1 ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 4fb91209..879b8671 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-99-0 = ["12-98-0"] 12-98-0 = ["12-96-0"] 12-96-0 = ["12-95-0"] 12-95-0 = ["12-93-0"] diff --git a/misskey-api/src/endpoint/i/update.rs b/misskey-api/src/endpoint/i/update.rs index 4ae006de..b0a37763 100644 --- a/misskey-api/src/endpoint/i/update.rs +++ b/misskey-api/src/endpoint/i/update.rs @@ -98,6 +98,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub muted_words: Option>, + #[cfg(feature = "12-99-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-99-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub muted_instances: Option>, #[cfg(feature = "12-60-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-60-0")))] #[serde(skip_serializing_if = "Option::is_none")] @@ -187,6 +192,8 @@ mod tests { vec!["mute1".to_string(), "mute2".to_string()], vec!["mute3".to_string()], ])), + #[cfg(feature = "12-99-0")] + muted_instances: Some(vec!["mute1".to_string(), "mute2".to_string()]), #[cfg(feature = "12-60-0")] no_crawle: Some(true), #[cfg(feature = "12-69-0")] @@ -242,6 +249,8 @@ mod tests { ff_visibility: None, pinned_page_id: Some(None), muted_words: None, + #[cfg(feature = "12-99-0")] + muted_instances: None, #[cfg(feature = "12-60-0")] no_crawle: None, #[cfg(feature = "12-69-0")] diff --git a/misskey-api/src/model/user.rs b/misskey-api/src/model/user.rs index b07adf76..179bfca6 100644 --- a/misskey-api/src/model/user.rs +++ b/misskey-api/src/model/user.rs @@ -263,6 +263,9 @@ pub struct User { #[cfg_attr(docsrs, doc(cfg(feature = "12-96-0")))] #[serde(default)] pub ff_visibility: Option, + #[cfg(feature = "12-99-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-99-0")))] + pub muted_instances: Option>, } fn default_false() -> bool { diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 682be01a..2c4d7540 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-99-0 = ["misskey-api/12-99-0", "12-98-0"] 12-98-0 = ["misskey-api/12-98-0", "12-96-0"] 12-96-0 = ["misskey-api/12-96-0", "12-95-0"] 12-95-0 = ["misskey-api/12-95-0", "12-93-0"] diff --git a/misskey-util/src/builder/me.rs b/misskey-util/src/builder/me.rs index 3720c3d1..5d5e72ce 100644 --- a/misskey-util/src/builder/me.rs +++ b/misskey-util/src/builder/me.rs @@ -344,6 +344,13 @@ impl MeUpdateBuilder { self.request.muted_words.replace(muted_words.into()); self } + + update_builder_string_collection_field! { + /// Sets the muted instances for this user. + #[cfg(feature = "12-99-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-99-0")))] + pub muted_instances; + } } impl MeUpdateBuilder { diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 204a0ee0..50b278f7 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-99-0 = ["misskey-api/12-99-0", "misskey-util/12-99-0"] 12-98-0 = ["misskey-api/12-98-0", "misskey-util/12-98-0"] 12-96-0 = ["misskey-api/12-96-0", "misskey-util/12-96-0"] 12-95-0 = ["misskey-api/12-95-0", "misskey-util/12-95-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 4aed97c1..61b6f4d6 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-99-0` | v12.99.0 ~ v12.101.1 | v12.99.1 | //! | `12-98-0` | v12.98.0 | v12.98.0 | //! | `12-96-0` | v12.96.0 ~ v12.97.1 | v12.97.0 | //! | `12-95-0` | v12.95.0 | v12.95.0 | From cdf4a82a38555d70bd47e59d7a4de9a741f13f5a Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Fri, 14 Apr 2023 05:42:10 +0900 Subject: [PATCH 21/44] Add: Support v12.102.0 --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 4 ++ misskey-api/Cargo.toml | 1 + .../src/endpoint/admin/abuse_user_reports.rs | 15 +++++ misskey-api/src/endpoint/admin/emoji.rs | 27 ++++++++- .../endpoint/admin/emoji/add_aliases_bulk.rs | 41 ++++++++++++++ .../src/endpoint/admin/emoji/delete.rs | 29 ++++++++++ .../src/endpoint/admin/emoji/delete_bulk.rs | 34 +++++++++++ .../src/endpoint/admin/emoji/import_zip.rs | 33 +++++++++++ .../admin/emoji/remove_aliases_bulk.rs | 51 +++++++++++++++++ .../endpoint/admin/emoji/set_aliases_bulk.rs | 41 ++++++++++++++ .../endpoint/admin/emoji/set_category_bulk.rs | 56 +++++++++++++++++++ .../admin/resolve_abuse_user_report.rs | 50 +++++++++++++---- .../src/endpoint/drive/files/create.rs | 9 +++ misskey-api/src/endpoint/users/stats.rs | 2 + misskey-api/src/model/abuse_user_report.rs | 3 + misskey-api/src/streaming/channel/main.rs | 4 ++ misskey-api/src/test/http.rs | 2 + misskey-util/Cargo.toml | 1 + misskey-util/src/builder/drive.rs | 10 ++++ misskey-util/src/client.rs | 18 ++++-- misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 25 files changed, 422 insertions(+), 21 deletions(-) create mode 100644 misskey-api/src/endpoint/admin/emoji/add_aliases_bulk.rs create mode 100644 misskey-api/src/endpoint/admin/emoji/delete.rs create mode 100644 misskey-api/src/endpoint/admin/emoji/delete_bulk.rs create mode 100644 misskey-api/src/endpoint/admin/emoji/import_zip.rs create mode 100644 misskey-api/src/endpoint/admin/emoji/remove_aliases_bulk.rs create mode 100644 misskey-api/src/endpoint/admin/emoji/set_aliases_bulk.rs create mode 100644 misskey-api/src/endpoint/admin/emoji/set_category_bulk.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4a8b229..59674ba4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.99.1' + MISSKEY_IMAGE: 'misskey/misskey:12.102.0' MISSKEY_ID: aid - - run: cargo test --features 12-99-0 + - run: cargo test --features 12-102-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 9a721d42..7b844c9b 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.102.0' + flags: --features 12-102-0 - image: 'misskey/misskey:12.99.1' flags: --features 12-99-0 - image: 'misskey/misskey:12.98.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 9f9d2d5b..60eaf1db 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.99.1' + MISSKEY_IMAGE: 'misskey/misskey:12.102.0' MISSKEY_ID: aid - - run: cargo test --features 12-99-0 + - run: cargo test --features 12-102-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 78657358..02bdc04f 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -58,6 +58,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.98.0 - endpoint `following/invalidate` - Partial support for Misskey v12.99.0 ~ v12.101.1 +- Support for Misskey v12.102.0 ~ v12.103.1 + - endpoint `admin/emoji/*` ### Changed ### Deprecated @@ -72,6 +74,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - For Misskey v12.88.0 ~ - endpoint `admin/logs` and `admin/delete-logs` - For Misskey v12.93.0 ~ +- endpoint `admin/emoji/remove` + - For Misskey v12.102.0 ~ ### Fixed diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 879b8671..c571c75b 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-102-0 = ["12-99-0"] 12-99-0 = ["12-98-0"] 12-98-0 = ["12-96-0"] 12-96-0 = ["12-95-0"] diff --git a/misskey-api/src/endpoint/admin/abuse_user_reports.rs b/misskey-api/src/endpoint/admin/abuse_user_reports.rs index 0229bce5..df760d4f 100644 --- a/misskey-api/src/endpoint/admin/abuse_user_reports.rs +++ b/misskey-api/src/endpoint/admin/abuse_user_reports.rs @@ -50,6 +50,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub target_user_origin: Option, + #[cfg(feature = "12-102-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-102-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub forwarded: Option, /// 1 .. 100 #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] @@ -95,6 +100,8 @@ mod tests { reporter_origin: None, #[cfg(feature = "12-49-0")] target_user_origin: None, + #[cfg(feature = "12-102-0")] + forwarded: None, limit: Some(100), since_id: None, until_id: None, @@ -118,6 +125,8 @@ mod tests { reporter_origin: Some(UserOrigin::Remote), #[cfg(feature = "12-49-0")] target_user_origin: Some(UserOrigin::Combined), + #[cfg(feature = "12-102-0")] + forwarded: None, limit: Some(100), since_id: None, until_id: None, @@ -133,6 +142,8 @@ mod tests { reporter_origin: Some(UserOrigin::Combined), #[cfg(feature = "12-49-0")] target_user_origin: Some(UserOrigin::Local), + #[cfg(feature = "12-102-0")] + forwarded: None, limit: Some(100), since_id: None, until_id: None, @@ -162,6 +173,8 @@ mod tests { reporter_origin: None, #[cfg(feature = "12-49-0")] target_user_origin: None, + #[cfg(feature = "12-102-0")] + forwarded: None, limit: None, since_id: None, until_id: None, @@ -177,6 +190,8 @@ mod tests { reporter_origin: None, #[cfg(feature = "12-49-0")] target_user_origin: None, + #[cfg(feature = "12-102-0")] + forwarded: None, limit: None, since_id: Some(reports[0].id.clone()), until_id: Some(reports[0].id.clone()), diff --git a/misskey-api/src/endpoint/admin/emoji.rs b/misskey-api/src/endpoint/admin/emoji.rs index 248d685f..8b020598 100644 --- a/misskey-api/src/endpoint/admin/emoji.rs +++ b/misskey-api/src/endpoint/admin/emoji.rs @@ -2,5 +2,30 @@ pub mod add; pub mod copy; pub mod list; pub mod list_remote; -pub mod remove; pub mod update; + +#[cfg(not(feature = "12-102-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-102-0"))))] +pub mod remove; + +#[cfg(feature = "12-102-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-102-0")))] +pub mod add_aliases_bulk; +#[cfg(feature = "12-102-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-102-0")))] +pub mod delete; +#[cfg(feature = "12-102-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-102-0")))] +pub mod delete_bulk; +#[cfg(feature = "12-102-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-102-0")))] +pub mod import_zip; +#[cfg(feature = "12-102-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-102-0")))] +pub mod remove_aliases_bulk; +#[cfg(feature = "12-102-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-102-0")))] +pub mod set_aliases_bulk; +#[cfg(feature = "12-102-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-102-0")))] +pub mod set_category_bulk; diff --git a/misskey-api/src/endpoint/admin/emoji/add_aliases_bulk.rs b/misskey-api/src/endpoint/admin/emoji/add_aliases_bulk.rs new file mode 100644 index 00000000..ae935214 --- /dev/null +++ b/misskey-api/src/endpoint/admin/emoji/add_aliases_bulk.rs @@ -0,0 +1,41 @@ +use crate::model::{emoji::Emoji, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub ids: Vec>, + pub aliases: Vec, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/emoji/add-aliases-bulk"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let ids = client + .admin + .test(crate::endpoint::admin::emoji::list::Request::default()) + .await + .iter() + .map(|emoji| emoji.id) + .collect(); + + client + .admin + .test(Request { + ids, + aliases: vec!["alias1".to_string(), "alias2".to_string()], + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/admin/emoji/delete.rs b/misskey-api/src/endpoint/admin/emoji/delete.rs new file mode 100644 index 00000000..0ff28720 --- /dev/null +++ b/misskey-api/src/endpoint/admin/emoji/delete.rs @@ -0,0 +1,29 @@ +use crate::model::{emoji::Emoji, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/emoji/delete"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let image_url = client.avatar_url().await; + let id = client.admin.add_emoji_from_url(image_url).await; + + client.admin.test(Request { id }).await; + } +} diff --git a/misskey-api/src/endpoint/admin/emoji/delete_bulk.rs b/misskey-api/src/endpoint/admin/emoji/delete_bulk.rs new file mode 100644 index 00000000..9acdc139 --- /dev/null +++ b/misskey-api/src/endpoint/admin/emoji/delete_bulk.rs @@ -0,0 +1,34 @@ +use crate::model::{emoji::Emoji, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub ids: Vec>, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/emoji/delete-bulk"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let ids = client + .admin + .test(crate::endpoint::admin::emoji::list::Request::default()) + .await + .iter() + .map(|emoji| emoji.id) + .collect(); + + client.admin.test(Request { ids }).await; + } +} diff --git a/misskey-api/src/endpoint/admin/emoji/import_zip.rs b/misskey-api/src/endpoint/admin/emoji/import_zip.rs new file mode 100644 index 00000000..268eeaa6 --- /dev/null +++ b/misskey-api/src/endpoint/admin/emoji/import_zip.rs @@ -0,0 +1,33 @@ +use crate::model::drive::DriveFile; +use crate::model::id::Id; + +use serde::Serialize; +use typed_builder::TypedBuilder; +#[cfg(any(docsrs, not(feature = "12-9-0")))] +use url::Url; + +#[derive(Serialize, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + pub file_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/emoji/import-zip"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let image_url = client.avatar_url().await; + let file = client.upload_from_url(image_url).await; + client.admin.test(Request { file_id: file.id }).await; + } +} diff --git a/misskey-api/src/endpoint/admin/emoji/remove_aliases_bulk.rs b/misskey-api/src/endpoint/admin/emoji/remove_aliases_bulk.rs new file mode 100644 index 00000000..b54a2a5d --- /dev/null +++ b/misskey-api/src/endpoint/admin/emoji/remove_aliases_bulk.rs @@ -0,0 +1,51 @@ +use crate::model::{emoji::Emoji, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub ids: Vec>, + pub aliases: Vec, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/emoji/remove-aliases-bulk"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + use crate::model::{emoji::Emoji, id::Id}; + + let client = TestClient::new(); + let ids: Vec> = client + .admin + .test(crate::endpoint::admin::emoji::list::Request::default()) + .await + .iter() + .map(|emoji| emoji.id) + .collect(); + + client + .admin + .test(crate::endpoint::admin::emoji::add_aliases_bulk::Request { + ids: ids.clone(), + aliases: vec!["alias1".to_string(), "alias2".to_string()], + }) + .await; + + client + .admin + .test(Request { + ids, + aliases: vec!["alias1".to_string()], + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/admin/emoji/set_aliases_bulk.rs b/misskey-api/src/endpoint/admin/emoji/set_aliases_bulk.rs new file mode 100644 index 00000000..e0a757d7 --- /dev/null +++ b/misskey-api/src/endpoint/admin/emoji/set_aliases_bulk.rs @@ -0,0 +1,41 @@ +use crate::model::{emoji::Emoji, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub ids: Vec>, + pub aliases: Vec, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/emoji/set-aliases-bulk"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let ids = client + .admin + .test(crate::endpoint::admin::emoji::list::Request::default()) + .await + .iter() + .map(|emoji| emoji.id) + .collect(); + + client + .admin + .test(Request { + ids, + aliases: vec!["alias1".to_string(), "alias2".to_string()], + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/admin/emoji/set_category_bulk.rs b/misskey-api/src/endpoint/admin/emoji/set_category_bulk.rs new file mode 100644 index 00000000..1836a690 --- /dev/null +++ b/misskey-api/src/endpoint/admin/emoji/set_category_bulk.rs @@ -0,0 +1,56 @@ +use crate::model::{emoji::Emoji, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub ids: Vec>, + pub category: Option, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/emoji/set-category-bulk"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let image_url = client.avatar_url().await; + let id = client.admin.add_emoji_from_url(image_url).await; + + client + .admin + .test(Request { + ids: vec![id], + category: None, + }) + .await; + } + + #[tokio::test] + async fn request_with_category() { + let client = TestClient::new(); + let ids = client + .admin + .test(crate::endpoint::admin::emoji::list::Request::default()) + .await + .iter() + .map(|emoji| emoji.id) + .collect(); + + client + .admin + .test(Request { + ids, + category: Some("cat".to_string()), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/admin/resolve_abuse_user_report.rs b/misskey-api/src/endpoint/admin/resolve_abuse_user_report.rs index c4c107d6..2d7d9402 100644 --- a/misskey-api/src/endpoint/admin/resolve_abuse_user_report.rs +++ b/misskey-api/src/endpoint/admin/resolve_abuse_user_report.rs @@ -1,11 +1,17 @@ use crate::model::{abuse_user_report::AbuseUserReport, id::Id}; use serde::Serialize; +use typed_builder::TypedBuilder; -#[derive(Serialize, Debug, Clone)] +#[derive(Serialize, Debug, Clone, TypedBuilder)] #[serde(rename_all = "camelCase")] pub struct Request { pub report_id: Id, + #[cfg(feature = "12-102-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-102-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub forward: Option, } impl misskey_core::Request for Request { @@ -33,23 +39,45 @@ mod tests { let reports = client .admin - .test(crate::endpoint::admin::abuse_user_reports::Request { - #[cfg(feature = "12-49-0")] - state: None, - #[cfg(feature = "12-49-0")] - reporter_origin: None, - #[cfg(feature = "12-49-0")] - target_user_origin: None, - limit: None, - since_id: None, - until_id: None, + .test(crate::endpoint::admin::abuse_user_reports::Request::default()) + .await; + + client + .admin + .test(Request { + report_id: reports[0].id.clone(), + #[cfg(feature = "12-102-0")] + forward: None, }) .await; + } + + #[cfg(feature = "12-102-0")] + #[tokio::test] + async fn request_with_forward() { + let client = TestClient::new(); + let (user, _) = client.admin.create_user().await; + + client + .user + .test(crate::endpoint::users::report_abuse::Request { + user_id: user.id.clone(), + comment: "damedesu".to_string(), + }) + .await; + + #[cfg(feature = "12-102-0")] + let reports = client + .admin + .test(crate::endpoint::admin::abuse_user_reports::Request::default()) + .await; client .admin .test(Request { report_id: reports[0].id.clone(), + #[cfg(feature = "12-102-0")] + forward: Some(true), }) .await; } diff --git a/misskey-api/src/endpoint/drive/files/create.rs b/misskey-api/src/endpoint/drive/files/create.rs index 0468efd2..cdd7e5a1 100644 --- a/misskey-api/src/endpoint/drive/files/create.rs +++ b/misskey-api/src/endpoint/drive/files/create.rs @@ -28,6 +28,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option, into))] pub name: Option, + #[cfg(feature = "12-102-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-102-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub comment: Option, #[serde( skip_serializing_if = "Option::is_none", serialize_with = "bool_string_option" @@ -83,6 +88,8 @@ mod tests { Request { folder_id: None, name: None, + #[cfg(feature = "12-102-0")] + comment: None, is_sensitive: None, force: None, }, @@ -107,6 +114,8 @@ mod tests { Request { folder_id: Some(folder.id), name: Some("hello.txt".to_string()), + #[cfg(feature = "12-102-0")] + comment: Some("comment".to_string()), is_sensitive: Some(true), force: Some(true), }, diff --git a/misskey-api/src/endpoint/users/stats.rs b/misskey-api/src/endpoint/users/stats.rs index fe869436..8fce15ce 100644 --- a/misskey-api/src/endpoint/users/stats.rs +++ b/misskey-api/src/endpoint/users/stats.rs @@ -25,6 +25,8 @@ pub struct UserStats { pub page_liked_count: u64, pub drive_files_count: u64, pub drive_usage: u64, + #[cfg(not(feature = "12-102-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-102-0"))))] pub reversi_count: u64, } diff --git a/misskey-api/src/model/abuse_user_report.rs b/misskey-api/src/model/abuse_user_report.rs index 51de3564..fe70c7af 100644 --- a/misskey-api/src/model/abuse_user_report.rs +++ b/misskey-api/src/model/abuse_user_report.rs @@ -32,6 +32,9 @@ pub struct AbuseUserReport { #[cfg(feature = "12-49-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-49-0")))] pub resolved: bool, + #[cfg(feature = "12-102-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-102-0")))] + pub forwarded: bool, } impl_entity!(AbuseUserReport); diff --git a/misskey-api/src/streaming/channel/main.rs b/misskey-api/src/streaming/channel/main.rs index 54f47d5b..c9e84285 100644 --- a/misskey-api/src/streaming/channel/main.rs +++ b/misskey-api/src/streaming/channel/main.rs @@ -40,8 +40,12 @@ pub enum MainStreamEvent { #[cfg_attr(docsrs, doc(cfg(feature = "12-47-0")))] ReadAllChannels, MyTokenRegenerated, + #[cfg(not(feature = "12-102-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-102-0"))))] ReversiNoInvites, /// TODO: Implement + #[cfg(not(feature = "12-102-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-102-0"))))] ReversiInvited {}, /// TODO: Implement PageEvent {}, diff --git a/misskey-api/src/test/http.rs b/misskey-api/src/test/http.rs index dff2ea39..a06c0c77 100644 --- a/misskey-api/src/test/http.rs +++ b/misskey-api/src/test/http.rs @@ -74,6 +74,8 @@ impl HttpClientExt for HttpClient { crate::endpoint::drive::files::create::Request { folder_id: None, name: Some(file_name.to_string()), + #[cfg(feature = "12-102-0")] + comment: None, is_sensitive: None, force: Some(true), }, diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 2c4d7540..9a348d51 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-102-0 = ["misskey-api/12-102-0", "12-99-0"] 12-99-0 = ["misskey-api/12-99-0", "12-98-0"] 12-98-0 = ["misskey-api/12-98-0", "12-96-0"] 12-96-0 = ["misskey-api/12-96-0", "12-95-0"] diff --git a/misskey-util/src/builder/drive.rs b/misskey-util/src/builder/drive.rs index 7a68c6fb..1ed34d5a 100644 --- a/misskey-util/src/builder/drive.rs +++ b/misskey-util/src/builder/drive.rs @@ -187,6 +187,8 @@ impl DriveFileBuilder { let path = path.as_ref().to_owned(); let request = endpoint::drive::files::create::Request { name: path.file_name().map(|s| s.to_string_lossy().into_owned()), + #[cfg(feature = "12-102-0")] + comment: None, folder_id: None, is_sensitive: Some(false), force: Some(false), @@ -223,6 +225,14 @@ impl DriveFileBuilder { self } + #[cfg(feature = "12-102-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-102-0")))] + /// Sets the comment of the file. + pub fn comment(&mut self, comment: impl Into) -> &mut Self { + self.request.comment.replace(comment.into()); + self + } + /// Sets whether the file contains NSFW content. pub fn sensitive(&mut self, sensitive: bool) -> &mut Self { self.request.is_sensitive = Some(sensitive); diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index 2ad6474e..8146989a 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -3849,10 +3849,14 @@ pub trait ClientExt: Client + Sync { ) -> BoxFuture>> { let report_id = report.entity_ref(); Box::pin(async move { - self.request(endpoint::admin::resolve_abuse_user_report::Request { report_id }) - .await - .map_err(Error::Client)? - .into_result()?; + self.request(endpoint::admin::resolve_abuse_user_report::Request { + report_id, + #[cfg(feature = "12-102-0")] + forward: None, + }) + .await + .map_err(Error::Client)? + .into_result()?; Ok(()) }) } @@ -4101,8 +4105,12 @@ pub trait ClientExt: Client + Sync { emoji: impl EntityRef, ) -> BoxFuture>> { let emoji_id = emoji.entity_ref(); + #[cfg(not(feature = "12-102-0"))] + let request = endpoint::admin::emoji::remove::Request { id: emoji_id }; + #[cfg(feature = "12-102-0")] + let request = endpoint::admin::emoji::delete::Request { id: emoji_id }; Box::pin(async move { - self.request(endpoint::admin::emoji::remove::Request { id: emoji_id }) + self.request(request) .await .map_err(Error::Client)? .into_result()?; diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 50b278f7..205fd309 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-102-0 = ["misskey-api/12-102-0", "misskey-util/12-102-0"] 12-99-0 = ["misskey-api/12-99-0", "misskey-util/12-99-0"] 12-98-0 = ["misskey-api/12-98-0", "misskey-util/12-98-0"] 12-96-0 = ["misskey-api/12-96-0", "misskey-util/12-96-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 61b6f4d6..2897f8cd 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-102-0` | v12.102.0 ~ v12.103.1 | v12.102.0 | //! | `12-99-0` | v12.99.0 ~ v12.101.1 | v12.99.1 | //! | `12-98-0` | v12.98.0 | v12.98.0 | //! | `12-96-0` | v12.96.0 ~ v12.97.1 | v12.97.0 | From d0b367e1d4ed560d32e33ceebf82a06e39f4e01a Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Fri, 14 Apr 2023 08:03:36 +0900 Subject: [PATCH 22/44] Add: Support v12.104.0 --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 4 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/charts.rs | 9 ++- .../src/endpoint/charts/active_users.rs | 9 ++- misskey-api/src/endpoint/charts/ap_request.rs | 77 +++++++++++++++++++ misskey-api/src/endpoint/charts/federation.rs | 9 ++- misskey-api/src/endpoint/charts/user/drive.rs | 13 ++-- misskey-api/src/endpoint/i/update.rs | 9 +++ misskey-api/src/endpoint/stats.rs | 4 + misskey-api/src/model/chart.rs | 77 +++++++++++++++++++ misskey-api/src/model/user.rs | 4 + misskey-util/Cargo.toml | 1 + misskey-util/src/builder/me.rs | 5 ++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 18 files changed, 222 insertions(+), 12 deletions(-) create mode 100644 misskey-api/src/endpoint/charts/ap_request.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 59674ba4..12c79b12 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.102.0' + MISSKEY_IMAGE: 'misskey/misskey:12.104.0' MISSKEY_ID: aid - - run: cargo test --features 12-102-0 + - run: cargo test --features 12-104-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 7b844c9b..11f8d3e2 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.104.0' + flags: --features 12-104-0 - image: 'misskey/misskey:12.102.0' flags: --features 12-102-0 - image: 'misskey/misskey:12.99.1' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 60eaf1db..02a0c47a 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.102.0' + MISSKEY_IMAGE: 'misskey/misskey:12.104.0' MISSKEY_ID: aid - - run: cargo test --features 12-102-0 + - run: cargo test --features 12-104-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 02bdc04f..ab4ced72 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -60,6 +60,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Partial support for Misskey v12.99.0 ~ v12.101.1 - Support for Misskey v12.102.0 ~ v12.103.1 - endpoint `admin/emoji/*` +- Support for Misskey v12.104.0 + - endpoint `charts/ap-request` ### Changed ### Deprecated @@ -76,6 +78,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - For Misskey v12.93.0 ~ - endpoint `admin/emoji/remove` - For Misskey v12.102.0 ~ +- endpoint `charts/network` + - For Misskey v12.104.0 ~ ### Fixed diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index c571c75b..688538ab 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-104-0 = ["12-102-0"] 12-102-0 = ["12-99-0"] 12-99-0 = ["12-98-0"] 12-98-0 = ["12-96-0"] diff --git a/misskey-api/src/endpoint/charts.rs b/misskey-api/src/endpoint/charts.rs index e73a2297..5cd20136 100644 --- a/misskey-api/src/endpoint/charts.rs +++ b/misskey-api/src/endpoint/charts.rs @@ -3,7 +3,14 @@ pub mod drive; pub mod federation; pub mod hashtag; pub mod instance; -pub mod network; pub mod notes; pub mod user; pub mod users; + +#[cfg(not(feature = "12-104-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-104-0"))))] +pub mod network; + +#[cfg(feature = "12-104-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-104-0")))] +pub mod ap_request; diff --git a/misskey-api/src/endpoint/charts/active_users.rs b/misskey-api/src/endpoint/charts/active_users.rs index 295459f5..3b3fe242 100644 --- a/misskey-api/src/endpoint/charts/active_users.rs +++ b/misskey-api/src/endpoint/charts/active_users.rs @@ -1,6 +1,8 @@ use crate::model::chart::{ActiveUsersChart, ChartSpan}; -use serde::{Deserialize, Serialize}; +#[cfg(not(feature = "12-104-0"))] +use serde::Deserialize; +use serde::Serialize; use typed_builder::TypedBuilder; #[derive(Serialize, Debug, Clone, TypedBuilder)] @@ -16,6 +18,8 @@ pub struct Request { pub offset: Option, } +#[cfg(not(feature = "12-104-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-104-0"))))] #[derive(Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct Response { @@ -24,7 +28,10 @@ pub struct Response { } impl misskey_core::Request for Request { + #[cfg(not(feature = "12-104-0"))] type Response = Response; + #[cfg(feature = "12-104-0")] + type Response = ActiveUsersChart; const ENDPOINT: &'static str = "charts/active-users"; } diff --git a/misskey-api/src/endpoint/charts/ap_request.rs b/misskey-api/src/endpoint/charts/ap_request.rs new file mode 100644 index 00000000..00c21dbf --- /dev/null +++ b/misskey-api/src/endpoint/charts/ap_request.rs @@ -0,0 +1,77 @@ +use crate::model::chart::{ApRequestChart, ChartSpan}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + pub span: ChartSpan, + /// 1 .. 500 + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub limit: Option, + #[builder(default, setter(strip_option))] + pub offset: Option, +} + +impl misskey_core::Request for Request { + type Response = ApRequestChart; + const ENDPOINT: &'static str = "charts/ap-request"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + use crate::model::chart::ChartSpan; + + let client = TestClient::new(); + client + .test(Request { + span: ChartSpan::Day, + limit: None, + offset: None, + }) + .await; + client + .test(Request { + span: ChartSpan::Hour, + limit: None, + offset: None, + }) + .await; + } + + #[tokio::test] + async fn request_with_limit() { + use crate::model::chart::ChartSpan; + + let client = TestClient::new(); + client + .test(Request { + span: ChartSpan::Day, + limit: Some(500), + offset: None, + }) + .await; + } + + #[tokio::test] + async fn request_with_offset() { + use crate::model::chart::ChartSpan; + + let client = TestClient::new(); + client + .test(Request { + span: ChartSpan::Day, + limit: None, + offset: Some(5), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/charts/federation.rs b/misskey-api/src/endpoint/charts/federation.rs index ab261ef1..21b9a45e 100644 --- a/misskey-api/src/endpoint/charts/federation.rs +++ b/misskey-api/src/endpoint/charts/federation.rs @@ -1,6 +1,8 @@ use crate::model::chart::{ChartSpan, FederationChart}; -use serde::{Deserialize, Serialize}; +#[cfg(not(feature = "12-104-0"))] +use serde::Deserialize; +use serde::Serialize; use typed_builder::TypedBuilder; #[derive(Serialize, Debug, Clone, TypedBuilder)] @@ -16,6 +18,8 @@ pub struct Request { pub offset: Option, } +#[cfg(not(feature = "12-104-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-104-0"))))] #[derive(Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct Response { @@ -23,7 +27,10 @@ pub struct Response { } impl misskey_core::Request for Request { + #[cfg(not(feature = "12-104-0"))] type Response = Response; + #[cfg(feature = "12-104-0")] + type Response = FederationChart; const ENDPOINT: &'static str = "charts/federation"; } diff --git a/misskey-api/src/endpoint/charts/user/drive.rs b/misskey-api/src/endpoint/charts/user/drive.rs index 00e83772..1b0fdb36 100644 --- a/misskey-api/src/endpoint/charts/user/drive.rs +++ b/misskey-api/src/endpoint/charts/user/drive.rs @@ -1,8 +1,8 @@ -use crate::model::{ - chart::{ChartSpan, DriveChart}, - id::Id, - user::User, -}; +#[cfg(not(feature = "12-104-0"))] +use crate::model::chart::DriveChart; +#[cfg(feature = "12-104-0")] +use crate::model::chart::UserDriveChart; +use crate::model::{chart::ChartSpan, id::Id, user::User}; use serde::Serialize; use typed_builder::TypedBuilder; @@ -22,7 +22,10 @@ pub struct Request { } impl misskey_core::Request for Request { + #[cfg(not(feature = "12-104-0"))] type Response = DriveChart; + #[cfg(feature = "12-104-0")] + type Response = UserDriveChart; const ENDPOINT: &'static str = "charts/user/drive"; } diff --git a/misskey-api/src/endpoint/i/update.rs b/misskey-api/src/endpoint/i/update.rs index b0a37763..be571fc1 100644 --- a/misskey-api/src/endpoint/i/update.rs +++ b/misskey-api/src/endpoint/i/update.rs @@ -108,6 +108,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub no_crawle: Option, + #[cfg(feature = "12-104-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-104-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub show_timeline_replies: Option, #[cfg(feature = "12-69-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-69-0")))] #[serde(skip_serializing_if = "Option::is_none")] @@ -196,6 +201,8 @@ mod tests { muted_instances: Some(vec!["mute1".to_string(), "mute2".to_string()]), #[cfg(feature = "12-60-0")] no_crawle: Some(true), + #[cfg(feature = "12-104-0")] + show_timeline_replies: Some(true), #[cfg(feature = "12-69-0")] receive_announcement_email: Some(true), #[cfg(feature = "12-48-0")] @@ -253,6 +260,8 @@ mod tests { muted_instances: None, #[cfg(feature = "12-60-0")] no_crawle: None, + #[cfg(feature = "12-104-0")] + show_timeline_replies: None, #[cfg(feature = "12-69-0")] receive_announcement_email: None, #[cfg(feature = "12-48-0")] diff --git a/misskey-api/src/endpoint/stats.rs b/misskey-api/src/endpoint/stats.rs index d1766a2c..fb209134 100644 --- a/misskey-api/src/endpoint/stats.rs +++ b/misskey-api/src/endpoint/stats.rs @@ -15,7 +15,11 @@ pub struct Response { #[cfg_attr(docsrs, doc(cfg(feature = "12-62-0")))] pub reactions_count: u64, pub instances: u64, + #[cfg(not(feature = "12-104-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-104-0"))))] pub drive_usage_local: u64, + #[cfg(not(feature = "12-104-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-104-0"))))] pub drive_usage_remote: u64, } diff --git a/misskey-api/src/model/chart.rs b/misskey-api/src/model/chart.rs index 57af920f..0022cb2c 100644 --- a/misskey-api/src/model/chart.rs +++ b/misskey-api/src/model/chart.rs @@ -29,8 +29,12 @@ impl std::str::FromStr for ChartSpan { #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct DriveChart { + #[cfg(not(feature = "12-104-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-104-0"))))] #[serde(alias = "totalFiles")] pub total_count: Vec, + #[cfg(not(feature = "12-104-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-104-0"))))] #[serde(alias = "totalUsage")] pub total_size: Vec, #[serde(alias = "incFiles")] @@ -43,6 +47,27 @@ pub struct DriveChart { pub dec_size: Vec, } +#[cfg(feature = "12-104-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-104-0")))] +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct UserDriveChart { + #[serde(alias = "totalFiles")] + pub total_count: Vec, + #[serde(alias = "totalUsage")] + pub total_size: Vec, + #[serde(alias = "incFiles")] + pub inc_count: Vec, + #[serde(alias = "incUsage")] + pub inc_size: Vec, + #[serde(alias = "decFiles")] + pub dec_count: Vec, + #[serde(alias = "decUsage")] + pub dec_size: Vec, +} + +#[cfg(not(feature = "12-104-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-104-0"))))] #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct FederationChart { @@ -51,6 +76,29 @@ pub struct FederationChart { pub dec: Vec, } +#[cfg(feature = "12-104-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-104-0")))] +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct InstanceChart { + pub total: Vec, + pub inc: Vec, + pub dec: Vec, +} + +#[cfg(feature = "12-104-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-104-0")))] +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct FederationChart { + pub instance: InstanceChart, + pub delivered_instances: Vec, + pub inbox_instances: Vec, + pub stalled: Vec, +} + +#[cfg(not(feature = "12-104-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-104-0"))))] #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct ActiveUsersChart { @@ -62,6 +110,22 @@ pub struct ActiveUsersChart { pub users: Vec, } +#[cfg(feature = "12-104-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-104-0")))] +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct ActiveUsersChart { + pub read_write: Vec, + pub read: Vec, + pub write: Vec, + pub registered_within_week: Vec, + pub registered_within_month: Vec, + pub registered_within_year: Vec, + pub registered_outside_week: Vec, + pub registered_outside_month: Vec, + pub registered_outside_year: Vec, +} + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct HashtagChart { @@ -96,6 +160,9 @@ pub struct NotesDiffsChart { pub normal: Vec, pub reply: Vec, pub renote: Vec, + #[cfg(feature = "12-104-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-104-0")))] + pub with_file: Vec, } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -137,3 +204,13 @@ pub struct NetworkChart { pub struct ReactionsChart { pub count: Vec, } + +#[cfg(feature = "12-104-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-104-0")))] +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct ApRequestChart { + pub deliver_failed: Vec, + pub deliver_succeeded: Vec, + pub inbox_received: Vec, +} diff --git a/misskey-api/src/model/user.rs b/misskey-api/src/model/user.rs index 179bfca6..14c0f60a 100644 --- a/misskey-api/src/model/user.rs +++ b/misskey-api/src/model/user.rs @@ -211,6 +211,10 @@ pub struct User { pub is_admin: bool, #[serde(default = "default_false")] pub is_moderator: bool, + #[cfg(feature = "12-104-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-104-0")))] + #[serde(default = "default_false")] + pub show_timeline_replies: bool, #[serde(default)] pub is_locked: Option, #[serde(default)] diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 9a348d51..3ff13319 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-104-0 = ["misskey-api/12-104-0", "12-102-0"] 12-102-0 = ["misskey-api/12-102-0", "12-99-0"] 12-99-0 = ["misskey-api/12-99-0", "12-98-0"] 12-98-0 = ["misskey-api/12-98-0", "12-96-0"] diff --git a/misskey-util/src/builder/me.rs b/misskey-util/src/builder/me.rs index 5d5e72ce..d7070673 100644 --- a/misskey-util/src/builder/me.rs +++ b/misskey-util/src/builder/me.rs @@ -193,6 +193,11 @@ impl MeUpdateBuilder { #[cfg_attr(docsrs, doc(cfg(feature = "12-60-0")))] pub no_crawle; + /// Sets whether to show replies to other users in the timeline. + #[cfg(feature = "12-104-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-104-0")))] + pub show_replies_in_timeline { show_timeline_replies }; + /// Sets whether to receive announcement emails. #[cfg(feature = "12-69-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-69-0")))] diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 205fd309..521037ac 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-104-0 = ["misskey-api/12-104-0", "misskey-util/12-104-0"] 12-102-0 = ["misskey-api/12-102-0", "misskey-util/12-102-0"] 12-99-0 = ["misskey-api/12-99-0", "misskey-util/12-99-0"] 12-98-0 = ["misskey-api/12-98-0", "misskey-util/12-98-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 2897f8cd..81686b8a 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-104-0` | v12.104.0 | v12.104.0 | //! | `12-102-0` | v12.102.0 ~ v12.103.1 | v12.102.0 | //! | `12-99-0` | v12.99.0 ~ v12.101.1 | v12.99.1 | //! | `12-98-0` | v12.98.0 | v12.98.0 | From d179d3c8a7d4ab55571468081c2e3044eb338601 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Fri, 14 Apr 2023 08:42:20 +0900 Subject: [PATCH 23/44] Add: Support v12.105.0 --- .github/workflows/ci.yml | 4 ++-- .github/workflows/flaky.yml | 4 ++-- .github/workflows/unstable.yml | 4 ++-- misskey-api/CHANGELOG.md | 1 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/admin/update_meta.rs | 7 +++++++ misskey-api/src/model/meta.rs | 3 +++ misskey-util/Cargo.toml | 1 + misskey-util/src/builder/admin.rs | 4 ++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 11 files changed, 25 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12c79b12..5234903b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.104.0' + MISSKEY_IMAGE: 'misskey/misskey:12.105.0' MISSKEY_ID: aid - - run: cargo test --features 12-104-0 + - run: cargo test --features 12-105-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 11f8d3e2..148dcaf0 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,8 +12,8 @@ jobs: strategy: matrix: include: - - image: 'misskey/misskey:12.104.0' - flags: --features 12-104-0 + - image: 'misskey/misskey:12.105.0' + flags: --features 12-105-0 - image: 'misskey/misskey:12.102.0' flags: --features 12-102-0 - image: 'misskey/misskey:12.99.1' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 02a0c47a..e54f29a6 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.104.0' + MISSKEY_IMAGE: 'misskey/misskey:12.105.0' MISSKEY_ID: aid - - run: cargo test --features 12-104-0 + - run: cargo test --features 12-105-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index ab4ced72..d970ac20 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -62,6 +62,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint `admin/emoji/*` - Support for Misskey v12.104.0 - endpoint `charts/ap-request` +- Support for Misskey v12.105.0 ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 688538ab..a741b0cc 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-105-0 = ["12-104-0"] 12-104-0 = ["12-102-0"] 12-102-0 = ["12-99-0"] 12-99-0 = ["12-98-0"] diff --git a/misskey-api/src/endpoint/admin/update_meta.rs b/misskey-api/src/endpoint/admin/update_meta.rs index 21e5aaa4..71b52823 100644 --- a/misskey-api/src/endpoint/admin/update_meta.rs +++ b/misskey-api/src/endpoint/admin/update_meta.rs @@ -34,6 +34,11 @@ pub struct Request { pub hidden_tags: Option>, #[builder(default, setter(strip_option))] pub blocked_hosts: Option>, + #[cfg(feature = "12-105-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-105-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub theme_color: Option>, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub mascot_image_url: Option>, @@ -290,6 +295,8 @@ mod tests { pinned_users: Some(vec!["@admin".to_string(), "@testuser".to_string()]), hidden_tags: Some(vec!["not_good".to_string()]), blocked_hosts: Some(vec!["not.good.host".to_string()]), + #[cfg(feature = "12-105-0")] + theme_color: Some(Some("#31748f".to_string())), mascot_image_url: Some(Some(image_url.to_string())), bannar_url: Some(Some(image_url.to_string())), icon_url: Some(Some(image_url.to_string())), diff --git a/misskey-api/src/model/meta.rs b/misskey-api/src/model/meta.rs index dac120b3..190251e9 100644 --- a/misskey-api/src/model/meta.rs +++ b/misskey-api/src/model/meta.rs @@ -53,6 +53,9 @@ pub struct Meta { pub recaptcha_site_key: Option, #[serde(rename = "swPublickey")] pub sw_public_key: Option, + #[cfg(feature = "12-105-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-105-0")))] + pub theme_color: Option, pub mascot_image_url: Option, pub bannar_url: Option, pub error_image_url: Option, diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 3ff13319..399f088b 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-105-0 = ["misskey-api/12-105-0", "12-104-0"] 12-104-0 = ["misskey-api/12-104-0", "12-102-0"] 12-102-0 = ["misskey-api/12-102-0", "12-99-0"] 12-99-0 = ["misskey-api/12-99-0", "12-98-0"] diff --git a/misskey-util/src/builder/admin.rs b/misskey-util/src/builder/admin.rs index 78ba8e81..a8b11467 100644 --- a/misskey-util/src/builder/admin.rs +++ b/misskey-util/src/builder/admin.rs @@ -174,6 +174,10 @@ impl MetaUpdateBuilder { } update_builder_string_option_field! { + #[doc_name = "theme color for the instance"] + #[cfg(feature = "12-105-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-105-0")))] + pub theme_color; #[doc_name = "URL of the mascot image for the instance"] pub mascot_image_url; #[doc_name = "URL of the banner image for the instance"] diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 521037ac..c5d244ee 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-105-0 = ["misskey-api/12-105-0", "misskey-util/12-105-0"] 12-104-0 = ["misskey-api/12-104-0", "misskey-util/12-104-0"] 12-102-0 = ["misskey-api/12-102-0", "misskey-util/12-102-0"] 12-99-0 = ["misskey-api/12-99-0", "misskey-util/12-99-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 81686b8a..d524578d 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-105-0` | v12.105.0 | v12.105.0 | //! | `12-104-0` | v12.104.0 | v12.104.0 | //! | `12-102-0` | v12.102.0 ~ v12.103.1 | v12.102.0 | //! | `12-99-0` | v12.99.0 ~ v12.101.1 | v12.99.1 | From 2997efa169875de051387174f6f0f346792bd7fb Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Fri, 14 Apr 2023 09:49:28 +0900 Subject: [PATCH 24/44] Add: Support v12.106.0 --- .github/workflows/ci.yml | 4 ++-- .github/workflows/flaky.yml | 2 ++ .github/workflows/unstable.yml | 4 ++-- misskey-api/CHANGELOG.md | 3 +++ misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint.rs | 6 +++++- misskey-api/src/endpoint/admin.rs | 5 ++++- misskey-api/src/model/chart.rs | 10 ++++++++-- misskey-util/Cargo.toml | 1 + misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 11 files changed, 30 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5234903b..1cf155ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.105.0' + MISSKEY_IMAGE: 'misskey/misskey:12.106.0' MISSKEY_ID: aid - - run: cargo test --features 12-105-0 + - run: cargo test --features 12-106-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 148dcaf0..45909505 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.106.0' + flags: --features 12-106-0 - image: 'misskey/misskey:12.105.0' flags: --features 12-105-0 - image: 'misskey/misskey:12.102.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index e54f29a6..450f987e 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.105.0' + MISSKEY_IMAGE: 'misskey/misskey:12.106.0' MISSKEY_ID: aid - - run: cargo test --features 12-105-0 + - run: cargo test --features 12-106-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index d970ac20..282fda52 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -63,6 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.104.0 - endpoint `charts/ap-request` - Support for Misskey v12.105.0 +- Support for Misskey v12.106.0 ~ v12.106.3 ### Changed ### Deprecated @@ -81,6 +82,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - For Misskey v12.102.0 ~ - endpoint `charts/network` - For Misskey v12.104.0 ~ +- endpoint `stats` + - For Misskey v12.106.0 ~ ### Fixed diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index a741b0cc..c5038003 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-106-0 = ["12-105-0"] 12-105-0 = ["12-104-0"] 12-104-0 = ["12-102-0"] 12-102-0 = ["12-99-0"] diff --git a/misskey-api/src/endpoint.rs b/misskey-api/src/endpoint.rs index 50610458..1f0ca0b1 100644 --- a/misskey-api/src/endpoint.rs +++ b/misskey-api/src/endpoint.rs @@ -59,7 +59,6 @@ pub mod notes; pub mod notifications; pub mod pages; pub mod pinned_users; -pub mod stats; pub mod username; pub mod users; @@ -86,3 +85,8 @@ pub mod gallery; #[cfg(feature = "12-92-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-92-0")))] pub mod email_address; + +// misskey-dev/misskey#8308 +#[cfg(not(feature = "12-106-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-106-0"))))] +pub mod stats; diff --git a/misskey-api/src/endpoint/admin.rs b/misskey-api/src/endpoint/admin.rs index 9eca0c8d..9050ef7c 100644 --- a/misskey-api/src/endpoint/admin.rs +++ b/misskey-api/src/endpoint/admin.rs @@ -6,7 +6,6 @@ pub mod get_table_stats; pub mod invite; pub mod moderators; pub mod reset_password; -pub mod resync_chart; pub mod server_info; pub mod show_moderation_logs; pub mod show_user; @@ -45,3 +44,7 @@ pub mod delete_logs; #[cfg(not(feature = "12-93-0"))] #[cfg_attr(docsrs, doc(cfg(not(feature = "12-93-0"))))] pub mod logs; + +#[cfg(not(feature = "12-106-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-106-0"))))] +pub mod resync_chart; diff --git a/misskey-api/src/model/chart.rs b/misskey-api/src/model/chart.rs index 0022cb2c..df6d4049 100644 --- a/misskey-api/src/model/chart.rs +++ b/misskey-api/src/model/chart.rs @@ -76,8 +76,8 @@ pub struct FederationChart { pub dec: Vec, } -#[cfg(feature = "12-104-0")] -#[cfg_attr(docsrs, doc(cfg(feature = "12-104-0")))] +#[cfg(all(feature = "12-104-0", not(feature = "12-106-0")))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "12-104-0", not(feature = "12-106-0")))))] #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct InstanceChart { @@ -91,10 +91,16 @@ pub struct InstanceChart { #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct FederationChart { + #[cfg(not(feature = "12-106-0"))] pub instance: InstanceChart, pub delivered_instances: Vec, pub inbox_instances: Vec, pub stalled: Vec, + #[cfg(feature = "12-106-0")] + pub sub: Vec, + #[cfg(feature = "12-106-0")] + #[serde(rename = "pub")] + pub pub_: Vec, } #[cfg(not(feature = "12-104-0"))] diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 399f088b..eea08452 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-106-0 = ["misskey-api/12-106-0", "12-105-0"] 12-105-0 = ["misskey-api/12-105-0", "12-104-0"] 12-104-0 = ["misskey-api/12-104-0", "12-102-0"] 12-102-0 = ["misskey-api/12-102-0", "12-99-0"] diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index c5d244ee..09e3e0dc 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-106-0 = ["misskey-api/12-106-0", "misskey-util/12-106-0"] 12-105-0 = ["misskey-api/12-105-0", "misskey-util/12-105-0"] 12-104-0 = ["misskey-api/12-104-0", "misskey-util/12-104-0"] 12-102-0 = ["misskey-api/12-102-0", "misskey-util/12-102-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index d524578d..f0262795 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-106-0` | v12.106.0 ~ v12.106.3 | v12.106.0 | //! | `12-105-0` | v12.105.0 | v12.105.0 | //! | `12-104-0` | v12.104.0 | v12.104.0 | //! | `12-102-0` | v12.102.0 ~ v12.103.1 | v12.102.0 | From e9c674d9ff700233ab68f89a983356ca9147e71f Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Fri, 14 Apr 2023 19:19:26 +0900 Subject: [PATCH 25/44] Add: Support v12.107.0 --- .github/workflows/ci.yml | 4 ++-- .github/workflows/flaky.yml | 2 ++ .github/workflows/unstable.yml | 4 ++-- misskey-api/CHANGELOG.md | 3 ++- misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint.rs | 4 ++-- misskey-util/Cargo.toml | 1 + misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 9 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1cf155ee..3840c354 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.106.0' + MISSKEY_IMAGE: 'misskey/misskey:12.107.0' MISSKEY_ID: aid - - run: cargo test --features 12-106-0 + - run: cargo test --features 12-107-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 45909505..fa118aa5 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.107.0' + flags: --features 12-107-0 - image: 'misskey/misskey:12.106.0' flags: --features 12-106-0 - image: 'misskey/misskey:12.105.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 450f987e..c58b7646 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.106.0' + MISSKEY_IMAGE: 'misskey/misskey:12.107.0' MISSKEY_ID: aid - - run: cargo test --features 12-106-0 + - run: cargo test --features 12-107-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 282fda52..770dffcd 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -64,6 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint `charts/ap-request` - Support for Misskey v12.105.0 - Support for Misskey v12.106.0 ~ v12.106.3 +- Support for Misskey v12.107.0 ### Changed ### Deprecated @@ -83,7 +84,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint `charts/network` - For Misskey v12.104.0 ~ - endpoint `stats` - - For Misskey v12.106.0 ~ + - For Misskey v12.106.0 ~ v12.106.3 ### Fixed diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index c5038003..b5513c76 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-107-0 = ["12-106-0"] 12-106-0 = ["12-105-0"] 12-105-0 = ["12-104-0"] 12-104-0 = ["12-102-0"] diff --git a/misskey-api/src/endpoint.rs b/misskey-api/src/endpoint.rs index 1f0ca0b1..bf6fcf22 100644 --- a/misskey-api/src/endpoint.rs +++ b/misskey-api/src/endpoint.rs @@ -87,6 +87,6 @@ pub mod gallery; pub mod email_address; // misskey-dev/misskey#8308 -#[cfg(not(feature = "12-106-0"))] -#[cfg_attr(docsrs, doc(cfg(not(feature = "12-106-0"))))] +#[cfg(any(not(feature = "12-106-0"), feature = "12-107-0"))] +#[cfg_attr(docsrs, doc(cfg(any(not(feature = "12-106-0"), feature = "12-107-0"))))] pub mod stats; diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index eea08452..0bfa9277 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-107-0 = ["misskey-api/12-107-0", "12-106-0"] 12-106-0 = ["misskey-api/12-106-0", "12-105-0"] 12-105-0 = ["misskey-api/12-105-0", "12-104-0"] 12-104-0 = ["misskey-api/12-104-0", "12-102-0"] diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 09e3e0dc..8ed944cd 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-107-0 = ["misskey-api/12-107-0", "misskey-util/12-107-0"] 12-106-0 = ["misskey-api/12-106-0", "misskey-util/12-106-0"] 12-105-0 = ["misskey-api/12-105-0", "misskey-util/12-105-0"] 12-104-0 = ["misskey-api/12-104-0", "misskey-util/12-104-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index f0262795..d0fc4d96 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-107-0` | v12.107.0 | v12.107.0 | //! | `12-106-0` | v12.106.0 ~ v12.106.3 | v12.106.0 | //! | `12-105-0` | v12.105.0 | v12.105.0 | //! | `12-104-0` | v12.104.0 | v12.104.0 | From 2c867b0a04387b9ee523ae24ad6c46066dda48a7 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Sun, 16 Apr 2023 11:26:24 +0900 Subject: [PATCH 26/44] Add: Support v12.108.0 --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 3 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/admin/show_users.rs | 102 ++++++++++++++++++ misskey-api/src/endpoint/admin/update_meta.rs | 20 ++++ misskey-api/src/endpoint/email_address.rs | 2 + misskey-api/src/endpoint/i/update.rs | 33 +++++- misskey-api/src/endpoint/mute/create.rs | 39 ++++++- misskey-api/src/endpoint/mute/delete.rs | 8 +- misskey-api/src/endpoint/mute/list.rs | 8 +- misskey-api/src/model/chart.rs | 6 ++ misskey-api/src/model/meta.rs | 7 +- misskey-api/src/model/muting.rs | 3 + misskey-api/src/model/notification.rs | 6 ++ misskey-api/src/streaming/channel/main.rs | 3 +- .../src/streaming/channel/user_list.rs | 2 + misskey-util/Cargo.toml | 1 + misskey-util/src/builder.rs | 6 +- misskey-util/src/builder/admin.rs | 4 + misskey-util/src/builder/me.rs | 79 ++++++++++++++ misskey-util/src/client.rs | 18 +++- misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 25 files changed, 342 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3840c354..4a11e3f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.107.0' + MISSKEY_IMAGE: 'misskey/misskey:12.108.1' MISSKEY_ID: aid - - run: cargo test --features 12-107-0 + - run: cargo test --features 12-108-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index fa118aa5..33ffcd02 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.108.1' + flags: --features 12-108-0 - image: 'misskey/misskey:12.107.0' flags: --features 12-107-0 - image: 'misskey/misskey:12.106.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index c58b7646..f809d20e 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.107.0' + MISSKEY_IMAGE: 'misskey/misskey:12.108.1' MISSKEY_ID: aid - - run: cargo test --features 12-107-0 + - run: cargo test --features 12-108-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 770dffcd..300db77b 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -65,6 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.105.0 - Support for Misskey v12.106.0 ~ v12.106.3 - Support for Misskey v12.107.0 +- Support for Misskey v12.108.0 ~ v12.108.1 ### Changed ### Deprecated @@ -85,6 +86,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - For Misskey v12.104.0 ~ - endpoint `stats` - For Misskey v12.106.0 ~ v12.106.3 +- endpoint `email-address/available` + - For Misskey v12.108.0 ### Fixed diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index b5513c76..1b4d49fc 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-108-0 = ["12-107-0"] 12-107-0 = ["12-106-0"] 12-106-0 = ["12-105-0"] 12-105-0 = ["12-104-0"] diff --git a/misskey-api/src/endpoint/admin/show_users.rs b/misskey-api/src/endpoint/admin/show_users.rs index bcd5debe..c925ec85 100644 --- a/misskey-api/src/endpoint/admin/show_users.rs +++ b/misskey-api/src/endpoint/admin/show_users.rs @@ -64,12 +64,24 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub origin: Option, + #[cfg(not(feature = "12-108-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option, into))] pub username: Option, + #[cfg(feature = "12-108-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + #[builder(default)] + pub username: String, + #[cfg(not(feature = "12-108-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option, into))] pub hostname: Option, + #[cfg(feature = "12-108-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + #[builder(default)] + pub hostname: String, } impl misskey_core::Request for Request { @@ -101,8 +113,14 @@ mod tests { sort: None, state: None, origin: None, + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; } @@ -118,8 +136,14 @@ mod tests { sort: None, state: None, origin: None, + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; } @@ -138,8 +162,14 @@ mod tests { sort: Some(SortOrder::Ascending(UserSortKey::Follower)), state: None, origin: None, + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; client @@ -150,8 +180,14 @@ mod tests { sort: Some(SortOrder::Ascending(UserSortKey::CreatedAt)), state: None, origin: None, + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; client @@ -162,8 +198,14 @@ mod tests { sort: Some(SortOrder::Descending(UserSortKey::UpdatedAt)), state: None, origin: None, + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; } @@ -180,8 +222,14 @@ mod tests { sort: None, state: Some(UserState::All), origin: None, + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; client @@ -192,8 +240,14 @@ mod tests { sort: None, state: Some(UserState::Admin), origin: None, + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; client @@ -204,8 +258,14 @@ mod tests { sort: None, state: Some(UserState::Available), origin: None, + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; // client @@ -228,8 +288,14 @@ mod tests { sort: None, state: Some(UserState::Moderator), origin: None, + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; // TODO: Uncomment with cfg when `adminOrModerator` value is fixed in Misskey @@ -251,8 +317,14 @@ mod tests { sort: None, state: Some(UserState::Silenced), origin: None, + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; client @@ -263,8 +335,14 @@ mod tests { sort: None, state: Some(UserState::Suspended), origin: None, + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; } @@ -283,8 +361,14 @@ mod tests { sort: None, state: None, origin: Some(UserOrigin::Local), + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; client @@ -295,8 +379,14 @@ mod tests { sort: None, state: None, origin: Some(UserOrigin::Remote), + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; client @@ -307,8 +397,14 @@ mod tests { sort: None, state: None, origin: Some(UserOrigin::Combined), + #[cfg(not(feature = "12-108-0"))] username: None, + #[cfg(feature = "12-108-0")] + username: String::new(), + #[cfg(not(feature = "12-108-0"))] hostname: None, + #[cfg(feature = "12-108-0")] + hostname: String::new(), }) .await; } @@ -325,8 +421,14 @@ mod tests { sort: None, state: None, origin: None, + #[cfg(not(feature = "12-108-0"))] username: Some("admin".to_string()), + #[cfg(feature = "12-108-0")] + username: "admin".to_string(), + #[cfg(not(feature = "12-108-0"))] hostname: Some("host".to_string()), + #[cfg(feature = "12-108-0")] + hostname: "host".to_string(), }) .await; } diff --git a/misskey-api/src/endpoint/admin/update_meta.rs b/misskey-api/src/endpoint/admin/update_meta.rs index 71b52823..d88a0c0b 100644 --- a/misskey-api/src/endpoint/admin/update_meta.rs +++ b/misskey-api/src/endpoint/admin/update_meta.rs @@ -64,6 +64,18 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub description: Option>, + #[cfg(feature = "12-108-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub default_light_theme: Option>, + #[cfg(feature = "12-108-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub default_dark_theme: Option>, + #[cfg(not(feature = "12-108-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub max_note_text_length: Option, @@ -76,6 +88,8 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub cache_remote_files: Option, + #[cfg(not(feature = "12-108-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub proxy_remote_files: Option, @@ -306,10 +320,16 @@ mod tests { logo_image_url: Some(Some(image_url.to_string())), name: None, description: Some(Some("description!".to_string())), + #[cfg(feature = "12-108-0")] + default_light_theme: Some(Some("{}".to_string())), + #[cfg(feature = "12-108-0")] + default_dark_theme: Some(Some("{}".to_string())), + #[cfg(not(feature = "12-108-0"))] max_note_text_length: Some(1000), local_drive_capacity_mb: Some(1000), remote_drive_capacity_mb: Some(1000), cache_remote_files: Some(true), + #[cfg(not(feature = "12-108-0"))] proxy_remote_files: Some(true), #[cfg(feature = "12-92-0")] email_required_for_signup: Some(true), diff --git a/misskey-api/src/endpoint/email_address.rs b/misskey-api/src/endpoint/email_address.rs index d158f16f..85d19262 100644 --- a/misskey-api/src/endpoint/email_address.rs +++ b/misskey-api/src/endpoint/email_address.rs @@ -1 +1,3 @@ +// misskey-dev/misskey#8404 +#[cfg(not(feature = "12-108-0"))] pub mod available; diff --git a/misskey-api/src/endpoint/i/update.rs b/misskey-api/src/endpoint/i/update.rs index be571fc1..3358d09d 100644 --- a/misskey-api/src/endpoint/i/update.rs +++ b/misskey-api/src/endpoint/i/update.rs @@ -7,11 +7,15 @@ use crate::model::notification::NotificationType; use crate::model::user::FfVisibility; #[cfg(feature = "12-70-0")] use crate::model::user::UserEmailNotificationType; +#[cfg(feature = "12-108-0")] +use crate::model::user::UserField; use crate::model::{drive::DriveFile, id::Id, page::Page, query::Query, user::User}; use serde::Serialize; use typed_builder::TypedBuilder; +#[cfg(not(feature = "12-108-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] #[derive(Serialize, Default, Debug, Clone)] pub struct UserFieldRequest { pub name: Option, @@ -43,9 +47,16 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub banner_id: Option>>, + #[cfg(not(feature = "12-108-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub fields: Option<[UserFieldRequest; 4]>, + #[cfg(feature = "12-108-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub fields: Option>, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub is_locked: Option, @@ -92,9 +103,16 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub ff_visibility: Option, + #[cfg(not(feature = "12-108-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub pinned_page_id: Option>>, + #[cfg(feature = "12-108-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub pinned_page_id: Option>>, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub muted_words: Option>, @@ -137,7 +155,9 @@ impl misskey_core::Request for Request { #[cfg(test)] mod tests { - use super::{Request, UserFieldRequest}; + use super::Request; + #[cfg(not(feature = "12-108-0"))] + use super::UserFieldRequest; use crate::test::{ClientExt, TestClient}; #[tokio::test] @@ -155,6 +175,8 @@ mod tests { use crate::model::user::FfVisibility; #[cfg(feature = "12-70-0")] use crate::model::user::UserEmailNotificationType; + #[cfg(feature = "12-108-0")] + use crate::model::user::UserField; let client = TestClient::new(); client @@ -166,6 +188,7 @@ mod tests { birthday: None, avatar_id: None, banner_id: None, + #[cfg(not(feature = "12-108-0"))] fields: Some([ UserFieldRequest { name: Some("key".to_string()), @@ -175,6 +198,11 @@ mod tests { Default::default(), Default::default(), ]), + #[cfg(feature = "12-108-0")] + fields: Some(vec![UserField { + name: "key".to_string(), + value: "value".to_string(), + }]), is_locked: Some(true), #[cfg(feature = "12-63-0")] is_explorable: Some(false), @@ -254,7 +282,10 @@ mod tests { always_mark_nsfw: None, #[cfg(feature = "12-96-0")] ff_visibility: None, + #[cfg(not(feature = "12-108-0"))] pinned_page_id: Some(None), + #[cfg(feature = "12-108-0")] + pinned_page_id: None, muted_words: None, #[cfg(feature = "12-99-0")] muted_instances: None, diff --git a/misskey-api/src/endpoint/mute/create.rs b/misskey-api/src/endpoint/mute/create.rs index 899f9928..5a6a6a4c 100644 --- a/misskey-api/src/endpoint/mute/create.rs +++ b/misskey-api/src/endpoint/mute/create.rs @@ -1,11 +1,24 @@ use crate::model::{id::Id, user::User}; +#[cfg(feature = "12-108-0")] +use chrono::serde::ts_milliseconds_option; +#[cfg(feature = "12-108-0")] +use chrono::{DateTime, Utc}; use serde::Serialize; +use typed_builder::TypedBuilder; -#[derive(Serialize, Debug, Clone)] +#[derive(Serialize, Debug, Clone, TypedBuilder)] #[serde(rename_all = "camelCase")] pub struct Request { pub user_id: Id, + #[cfg(feature = "12-108-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + #[serde( + skip_serializing_if = "Option::is_none", + with = "ts_milliseconds_option" + )] + #[builder(default, setter(strip_option, into))] + pub expires_at: Option>, } impl misskey_core::Request for Request { @@ -23,6 +36,28 @@ mod tests { let client = TestClient::new(); let (user, _) = client.admin.create_user().await; - client.user.test(Request { user_id: user.id }).await; + client + .user + .test(Request { + user_id: user.id, + #[cfg(feature = "12-108-0")] + expires_at: None, + }) + .await; + } + + #[cfg(feature = "12-108-0")] + #[tokio::test] + async fn request_with_expires_at() { + let client = TestClient::new(); + let (user, _) = client.admin.create_user().await; + + client + .user + .test(Request { + user_id: user.id, + expires_at: Some(chrono::Utc::now() + chrono::Duration::hours(1)), + }) + .await; } } diff --git a/misskey-api/src/endpoint/mute/delete.rs b/misskey-api/src/endpoint/mute/delete.rs index df4bac3d..2547e7bf 100644 --- a/misskey-api/src/endpoint/mute/delete.rs +++ b/misskey-api/src/endpoint/mute/delete.rs @@ -24,9 +24,11 @@ mod tests { let (user, _) = client.admin.create_user().await; client .user - .test(crate::endpoint::mute::create::Request { - user_id: user.id.clone(), - }) + .test( + crate::endpoint::mute::create::Request::builder() + .user_id(user.id.clone()) + .build(), + ) .await; client.user.test(Request { user_id: user.id }).await; diff --git a/misskey-api/src/endpoint/mute/list.rs b/misskey-api/src/endpoint/mute/list.rs index 2b333403..ee4dc72c 100644 --- a/misskey-api/src/endpoint/mute/list.rs +++ b/misskey-api/src/endpoint/mute/list.rs @@ -57,9 +57,11 @@ mod tests { client .user - .test(crate::endpoint::mute::create::Request { - user_id: user.id.clone(), - }) + .test( + crate::endpoint::mute::create::Request::builder() + .user_id(user.id) + .build(), + ) .await; let mutings = client diff --git a/misskey-api/src/model/chart.rs b/misskey-api/src/model/chart.rs index df6d4049..94e77bfe 100644 --- a/misskey-api/src/model/chart.rs +++ b/misskey-api/src/model/chart.rs @@ -101,6 +101,12 @@ pub struct FederationChart { #[cfg(feature = "12-106-0")] #[serde(rename = "pub")] pub pub_: Vec, + #[cfg(feature = "12-108-0")] + pub pubsub: Vec, + #[cfg(feature = "12-108-0")] + pub sub_active: Vec, + #[cfg(feature = "12-108-0")] + pub pub_active: Vec, } #[cfg(not(feature = "12-104-0"))] diff --git a/misskey-api/src/model/meta.rs b/misskey-api/src/model/meta.rs index 190251e9..34477c33 100644 --- a/misskey-api/src/model/meta.rs +++ b/misskey-api/src/model/meta.rs @@ -24,7 +24,12 @@ pub struct Meta { pub tos_url: Option, pub repository_url: Url, pub feedback_url: Option, + #[cfg(not(feature = "12-108-0"))] pub secure: bool, + #[cfg(feature = "12-108-0")] + pub default_dark_theme: Option, + #[cfg(feature = "12-108-0")] + pub default_light_theme: Option, pub disable_registration: bool, pub disable_local_timeline: bool, pub disable_global_timeline: bool, @@ -36,7 +41,7 @@ pub struct Meta { #[cfg(not(feature = "12-58-0"))] pub cache_remote_files: bool, /// This field is [`bool`] (i.e. not [`Option`]) on non-feature="12-58-0". - #[cfg(feature = "12-58-0")] + #[cfg(all(feature = "12-58-0", not(feature = "12-108-0")))] pub proxy_remote_files: Option, #[cfg(not(feature = "12-58-0"))] pub proxy_remote_files: bool, diff --git a/misskey-api/src/model/muting.rs b/misskey-api/src/model/muting.rs index d5ed9dd0..88e1fc37 100644 --- a/misskey-api/src/model/muting.rs +++ b/misskey-api/src/model/muting.rs @@ -8,6 +8,9 @@ use serde::{Deserialize, Serialize}; pub struct Muting { pub id: Id, pub created_at: DateTime, + #[cfg(feature = "12-108-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + pub expires_at: Option>, pub mutee_id: Id, pub mutee: User, } diff --git a/misskey-api/src/model/notification.rs b/misskey-api/src/model/notification.rs index ca4dca0f..fb9ca4ee 100644 --- a/misskey-api/src/model/notification.rs +++ b/misskey-api/src/model/notification.rs @@ -63,6 +63,10 @@ pub enum NotificationBody { note: Note, choice: u64, }, + #[cfg(feature = "12-108-0")] + PollEnded { + note: Note, + }, GroupInvited { invitation: UserGroupInvitation, }, @@ -97,6 +101,8 @@ impl std::str::FromStr for NotificationType { "quote" | "Quote" => Ok(NotificationType::Quote), "reaction" | "Reaction" => Ok(NotificationType::Reaction), "pollVote" | "PollVote" => Ok(NotificationType::PollVote), + #[cfg(feature = "12-108-0")] + "pollEnded" | "PollEnded" => Ok(NotificationType::PollEnded), "groupInvited" | "GroupInvited" => Ok(NotificationType::GroupInvited), "app" | "App" => Ok(NotificationType::App), _ => Err(ParseNotificationTypeError { _priv: () }), diff --git a/misskey-api/src/streaming/channel/main.rs b/misskey-api/src/streaming/channel/main.rs index c9e84285..bde833fd 100644 --- a/misskey-api/src/streaming/channel/main.rs +++ b/misskey-api/src/streaming/channel/main.rs @@ -161,12 +161,13 @@ mod tests { let mut stream = client.channel(Request::default()).await.unwrap(); + let url = client.avatar_url().await; let expected_marker = ulid_crate::Ulid::new().to_string(); let expected_comment = ulid_crate::Ulid::new().to_string(); futures::future::join( client.test(crate::endpoint::drive::files::upload_from_url::Request { - url: url::Url::parse("http://example.com/index.html").unwrap(), + url, folder_id: None, is_sensitive: None, force: None, diff --git a/misskey-api/src/streaming/channel/user_list.rs b/misskey-api/src/streaming/channel/user_list.rs index 70ce4296..dc909ead 100644 --- a/misskey-api/src/streaming/channel/user_list.rs +++ b/misskey-api/src/streaming/channel/user_list.rs @@ -87,6 +87,7 @@ mod tests { .await; } + #[cfg(not(feature = "12-108-0"))] #[tokio::test] async fn stream_added() { let client = TestClient::new().await; @@ -125,6 +126,7 @@ mod tests { .await; } + #[cfg(not(feature = "12-108-0"))] #[tokio::test] async fn stream_removed() { let client = TestClient::new().await; diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 0bfa9277..2d33209d 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-108-0 = ["misskey-api/12-108-0", "12-107-0"] 12-107-0 = ["misskey-api/12-107-0", "12-106-0"] 12-106-0 = ["misskey-api/12-106-0", "12-105-0"] 12-105-0 = ["misskey-api/12-105-0", "12-104-0"] diff --git a/misskey-util/src/builder.rs b/misskey-util/src/builder.rs index 87fdb60e..41fec762 100644 --- a/misskey-util/src/builder.rs +++ b/misskey-util/src/builder.rs @@ -34,7 +34,7 @@ pub use drive::{ DriveFileBuilder, DriveFileListBuilder, DriveFileUpdateBuilder, DriveFileUrlBuilder, DriveFolderUpdateBuilder, }; -pub use me::{IntoUserFields, MeUpdateBuilder}; +pub use me::MeUpdateBuilder; pub use messaging::MessagingMessageBuilder; pub use note::NoteBuilder; pub use page::{PageBuilder, PageUpdateBuilder}; @@ -67,3 +67,7 @@ pub use user::UserListBuilder; #[cfg(not(feature = "12-93-0"))] #[cfg_attr(docsrs, doc(cfg(not(feature = "12-93-0"))))] pub use admin::ServerLogListBuilder; + +#[cfg(not(feature = "12-108-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] +pub use me::IntoUserFields; diff --git a/misskey-util/src/builder/admin.rs b/misskey-util/src/builder/admin.rs index a8b11467..9293a8ca 100644 --- a/misskey-util/src/builder/admin.rs +++ b/misskey-util/src/builder/admin.rs @@ -201,6 +201,8 @@ impl MetaUpdateBuilder { } /// Sets the maximum number of characters for posts in the instance. + #[cfg(not(feature = "12-108-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] pub fn max_note_text_length(&mut self, max_note_text_length: u64) -> &mut Self { self.request .max_note_text_length @@ -225,6 +227,8 @@ impl MetaUpdateBuilder { pub cache_remote_files; /// Sets whether or not the instance would proxy remote files that are not available /// locally. + #[cfg(not(feature = "12-108-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] pub proxy_remote_files; } diff --git a/misskey-util/src/builder/me.rs b/misskey-util/src/builder/me.rs index d7070673..f17ea6b2 100644 --- a/misskey-util/src/builder/me.rs +++ b/misskey-util/src/builder/me.rs @@ -26,11 +26,14 @@ use misskey_core::Client; /// /// [set_fields]: MeUpdateBuilder::set_fields /// [user_field]: misskey_api::model::user::UserField +#[cfg(not(feature = "12-108-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] pub trait IntoUserFields { /// Performs the conversion. fn into_user_fields(self) -> [Option; 4]; } +#[cfg(not(feature = "12-108-0"))] macro_rules! impl_into_field_requests { (expand default) => { None }; (expand $i:ident) => { Some($i) }; @@ -59,9 +62,13 @@ macro_rules! impl_into_field_requests { }; } +#[cfg(not(feature = "12-108-0"))] impl_into_field_requests! { 1; f1 => f1, default, default, default } +#[cfg(not(feature = "12-108-0"))] impl_into_field_requests! { 2; f1, f2 => f1, f2, default, default } +#[cfg(not(feature = "12-108-0"))] impl_into_field_requests! { 3; f1, f2, f3 => f1, f2, f3, default } +#[cfg(not(feature = "12-108-0"))] impl_into_field_requests! { 4; f1, f2, f3, f4 => f1, f2, f3, f4 } /// Builder for the [`update_me`][`crate::ClientExt::update_me`] method. @@ -96,9 +103,23 @@ impl MeUpdateBuilder { pub avatar: impl EntityRef { avatar_id = avatar.entity_ref() }; pub banner: impl EntityRef { banner_id = banner.entity_ref() }; #[doc_name = "pinned page"] + #[cfg(not(feature = "12-108-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] pub pinned_page: impl EntityRef { pinned_page_id = pinned_page.entity_ref() }; } + /// Sets the pinned page. + #[cfg(feature = "12-108-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + pub fn pinned_page( + &mut self, + pinned_page: impl IntoIterator>, + ) -> &mut Self { + let pinned_page_id = pinned_page.into_iter().map(|p| p.entity_ref()).collect(); + self.request.pinned_page_id.replace(pinned_page_id); + self + } + /// Sets the fields in this user's profile. /// /// Since the user has four fields, it takes an array of length 1 to 4 as its argument. @@ -121,6 +142,8 @@ impl MeUpdateBuilder { /// # Ok(()) /// # } /// ``` + #[cfg(not(feature = "12-108-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] pub fn set_fields(&mut self, fields: impl IntoUserFields) -> &mut Self { fn to_request(field: UserField) -> endpoint::i::update::UserFieldRequest { endpoint::i::update::UserFieldRequest { @@ -139,6 +162,62 @@ impl MeUpdateBuilder { self } + /// Sets the fields in this user's profile. + /// + /// Since users can set up to 16 fields, it takes a collection with no more than 16 items + /// as its argument. + /// + /// # Examples + /// + /// ``` + /// # use misskey_util::ClientExt; + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let client = misskey_test::test_client().await?; + /// client + /// .update_me() + /// .set_fields([ + /// ("Website", "https://example.com/"), + /// ("Twitter", "@username"), + /// ]) + /// .update() + /// .await?; + /// # Ok(()) + /// # } + /// ``` + #[cfg(feature = "12-108-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + pub fn set_fields( + &mut self, + fields: impl IntoIterator, impl Into)>, + ) -> &mut Self { + let fields = fields + .into_iter() + .map(|(name, value)| UserField { + name: name.into(), + value: value.into(), + }) + .collect(); + self.request.fields.replace(fields); + self + } + + /// Adds a field with the given name and value to the fields in this user's profile. + #[cfg(feature = "12-108-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + pub fn add_field(&mut self, name: impl Into, value: impl Into) -> &mut Self { + let field = UserField { + name: name.into(), + value: value.into(), + }; + if let Some(fields) = self.request.fields.as_mut() { + fields.push(field); + } else { + self.request.fields.replace(vec![field]); + } + self + } + /// Deletes all the fields in this user's profile. pub fn delete_fields(&mut self) -> &mut Self { self.request.fields.replace(Default::default()); diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index 8146989a..fd266f10 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -392,10 +392,14 @@ pub trait ClientExt: Client + Sync { fn mute(&self, user: impl EntityRef) -> BoxFuture>> { let user_id = user.entity_ref(); Box::pin(async move { - self.request(endpoint::mute::create::Request { user_id }) - .await - .map_err(Error::Client)? - .into_result()?; + self.request(endpoint::mute::create::Request { + user_id, + #[cfg(feature = "12-108-0")] + expires_at: None, + }) + .await + .map_err(Error::Client)? + .into_result()?; Ok(()) }) } @@ -3336,12 +3340,16 @@ pub trait ClientExt: Client + Sync { } /// Pins the specified page to the profile. + #[cfg(not(feature = "12-108-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] fn pin_page(&self, page: impl EntityRef) -> BoxFuture>> { let page_id = page.entity_ref(); Box::pin(async move { self.update_me().set_pinned_page(page_id).update().await }) } /// Unpins the page from the profile. + #[cfg(not(feature = "12-108-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] fn unpin_page(&self) -> BoxFuture>> { Box::pin(async move { self.update_me().delete_pinned_page().update().await }) } @@ -3984,7 +3992,7 @@ pub trait ClientExt: Client + Sync { /// client /// .update_meta() /// .set_name("The Instance of Saturn") - /// .max_note_text_length(5000) + /// .local_drive_capacity(5000) /// .update() /// .await?; /// # Ok(()) diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 8ed944cd..d64cd966 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-108-0 = ["misskey-api/12-108-0", "misskey-util/12-108-0"] 12-107-0 = ["misskey-api/12-107-0", "misskey-util/12-107-0"] 12-106-0 = ["misskey-api/12-106-0", "misskey-util/12-106-0"] 12-105-0 = ["misskey-api/12-105-0", "misskey-util/12-105-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index d0fc4d96..3062820b 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-108-0` | v12.108.0 ~ v12.108.1 | v12.108.1 | //! | `12-107-0` | v12.107.0 | v12.107.0 | //! | `12-106-0` | v12.106.0 ~ v12.106.3 | v12.106.0 | //! | `12-105-0` | v12.105.0 | v12.105.0 | From 4541b388511f9f71b5679e7f3cc840b17ad889d5 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Sun, 16 Apr 2023 14:45:17 +0900 Subject: [PATCH 27/44] Add: Support v12.109.0 --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 4 +- misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/admin.rs | 4 + misskey-api/src/endpoint/admin/meta.rs | 24 ++++++ misskey-api/src/endpoint/email_address.rs | 2 +- misskey-api/src/endpoint/meta.rs | 1 + misskey-api/src/model/meta.rs | 91 +++++++++++++++++++++++ misskey-util/Cargo.toml | 1 + misskey-util/src/client.rs | 18 +++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 14 files changed, 152 insertions(+), 6 deletions(-) create mode 100644 misskey-api/src/endpoint/admin/meta.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a11e3f6..9b44ed3e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.108.1' + MISSKEY_IMAGE: 'misskey/misskey:12.109.2' MISSKEY_ID: aid - - run: cargo test --features 12-108-0 + - run: cargo test --features 12-109-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 33ffcd02..4eaab742 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.109.2' + flags: --features 12-109-0 - image: 'misskey/misskey:12.108.1' flags: --features 12-108-0 - image: 'misskey/misskey:12.107.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index f809d20e..129d72e9 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.108.1' + MISSKEY_IMAGE: 'misskey/misskey:12.109.2' MISSKEY_ID: aid - - run: cargo test --features 12-108-0 + - run: cargo test --features 12-109-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 300db77b..a11f5c64 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -66,6 +66,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.106.0 ~ v12.106.3 - Support for Misskey v12.107.0 - Support for Misskey v12.108.0 ~ v12.108.1 +- Support for Misskey v12.109.0 ~ v12.110.1 + - endpoint `admin/meta` ### Changed ### Deprecated @@ -87,7 +89,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint `stats` - For Misskey v12.106.0 ~ v12.106.3 - endpoint `email-address/available` - - For Misskey v12.108.0 + - For Misskey v12.108.0 ~ v12.108.1 ### Fixed diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index 1b4d49fc..f491bae5 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-109-0 = ["12-108-0"] 12-108-0 = ["12-107-0"] 12-107-0 = ["12-106-0"] 12-106-0 = ["12-105-0"] diff --git a/misskey-api/src/endpoint/admin.rs b/misskey-api/src/endpoint/admin.rs index 9050ef7c..ee9b76fb 100644 --- a/misskey-api/src/endpoint/admin.rs +++ b/misskey-api/src/endpoint/admin.rs @@ -48,3 +48,7 @@ pub mod logs; #[cfg(not(feature = "12-106-0"))] #[cfg_attr(docsrs, doc(cfg(not(feature = "12-106-0"))))] pub mod resync_chart; + +#[cfg(feature = "12-109-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-109-0")))] +pub mod meta; diff --git a/misskey-api/src/endpoint/admin/meta.rs b/misskey-api/src/endpoint/admin/meta.rs new file mode 100644 index 00000000..cec60782 --- /dev/null +++ b/misskey-api/src/endpoint/admin/meta.rs @@ -0,0 +1,24 @@ +use crate::model::meta::AdminMeta; + +use serde::Serialize; + +#[derive(Serialize, Default, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request {} + +impl misskey_core::Request for Request { + type Response = AdminMeta; + const ENDPOINT: &'static str = "admin/meta"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.admin.test(Request::default()).await; + } +} diff --git a/misskey-api/src/endpoint/email_address.rs b/misskey-api/src/endpoint/email_address.rs index 85d19262..6b0e5c98 100644 --- a/misskey-api/src/endpoint/email_address.rs +++ b/misskey-api/src/endpoint/email_address.rs @@ -1,3 +1,3 @@ // misskey-dev/misskey#8404 -#[cfg(not(feature = "12-108-0"))] +#[cfg(any(not(feature = "12-108-0"), feature = "12-109-0"))] pub mod available; diff --git a/misskey-api/src/endpoint/meta.rs b/misskey-api/src/endpoint/meta.rs index d0070029..18a045de 100644 --- a/misskey-api/src/endpoint/meta.rs +++ b/misskey-api/src/endpoint/meta.rs @@ -25,6 +25,7 @@ mod tests { client.test(Request::default()).await; } + #[cfg(not(feature = "12-109-0"))] #[tokio::test] async fn request_by_admin() { let client = TestClient::new(); diff --git a/misskey-api/src/model/meta.rs b/misskey-api/src/model/meta.rs index 34477c33..ff309f89 100644 --- a/misskey-api/src/model/meta.rs +++ b/misskey-api/src/model/meta.rs @@ -12,6 +12,8 @@ use url::Url; pub struct Meta { #[serde(default)] pub features: Option, + #[cfg(not(feature = "12-109-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "12-109-0"))))] #[serde(default, flatten)] pub admin: Option, pub maintainer_name: Option, @@ -66,9 +68,11 @@ pub struct Meta { pub error_image_url: Option, pub icon_url: Option, pub max_note_text_length: u64, + #[serde(default)] pub emojis: Vec, #[cfg(feature = "12-81-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] + #[serde(default)] pub ads: Vec, /// This field is [`bool`] (i.e. not [`Option`]) on non-feature="12-58-0". #[cfg(feature = "12-58-0")] @@ -118,6 +122,8 @@ pub struct MetaAd { pub image_url: String, } +#[cfg(not(feature = "12-109-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-109-0"))))] #[derive(Deserialize, Serialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct AdminMeta { @@ -172,6 +178,91 @@ pub struct AdminMeta { pub deepl_is_pro: bool, } +#[cfg(feature = "12-109-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-109-0")))] +#[derive(Deserialize, Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct AdminMeta { + pub maintainer_name: Option, + pub maintainer_email: Option, + pub version: String, + pub name: Option, + pub uri: String, + pub description: Option, + pub langs: Vec, + pub tos_url: Option, + pub repository_url: Url, + pub feedback_url: Option, + pub disable_registration: bool, + pub disable_local_timeline: bool, + pub disable_global_timeline: bool, + pub drive_capacity_per_local_user_mb: u64, + pub drive_capacity_per_remote_user_mb: u64, + pub email_required_for_signup: bool, + pub enable_hcaptcha: bool, + pub hcaptcha_site_key: Option, + pub enable_recaptcha: bool, + pub recaptcha_site_key: Option, + #[serde(rename = "swPublickey")] + pub sw_public_key: Option, + pub theme_color: Option, + pub mascot_image_url: Option, + pub banner_url: Option, + pub error_image_url: Option, + pub icon_url: Option, + pub background_image_url: Option, + pub logo_image_url: Option, + pub max_note_text_length: u64, + pub default_light_theme: Option, + pub default_dark_theme: Option, + pub enable_email: bool, + pub enable_twitter_integration: bool, + pub enable_github_integration: bool, + pub enable_discord_integration: bool, + pub enable_service_worker: bool, + pub translator_available: bool, + pub pinned_pages: Option>, + pub pinned_clip_id: Option>, + pub cache_remote_files: Option, + pub use_star_for_reaction_fallback: bool, + pub pinned_users: Vec, + pub hidden_tags: Vec, + pub blocked_hosts: Vec, + pub hcaptcha_secret_key: Option, + pub recaptcha_secret_key: Option, + pub proxy_account_id: Option>, + pub twitter_consumer_key: Option, + pub twitter_consumer_secret: Option, + pub github_client_id: Option, + pub github_client_secret: Option, + pub discord_client_id: Option, + pub discord_client_secret: Option, + pub summaly_proxy: Option, + pub email: Option, + pub smtp_secure: bool, + pub smtp_host: Option, + pub smtp_port: Option, + pub smtp_user: Option, + pub smtp_pass: Option, + pub sw_private_key: Option, + pub use_object_storage: bool, + pub object_storage_base_url: Option, + pub object_storage_bucket: Option, + pub object_storage_prefix: Option, + pub object_storage_endpoint: Option, + pub object_storage_region: Option, + pub object_storage_port: Option, + pub object_storage_access_key: Option, + pub object_storage_secret_key: Option, + #[serde(rename = "objectStorageUseSSL")] + pub object_storage_use_ssl: bool, + pub object_storage_use_proxy: bool, + pub object_storage_set_public_read: bool, + pub object_storage_s3_force_path_style: bool, + pub deepl_auth_key: Option, + pub deepl_is_pro: bool, +} + #[derive(Deserialize, Serialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct FeaturesMeta { diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 2d33209d..5d2ce4fa 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-109-0 = ["misskey-api/12-109-0", "12-108-0"] 12-108-0 = ["misskey-api/12-108-0", "12-107-0"] 12-107-0 = ["misskey-api/12-107-0", "12-106-0"] 12-106-0 = ["misskey-api/12-106-0", "12-105-0"] diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index fd266f10..963400ee 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -41,6 +41,8 @@ use misskey_api::model::ad::Ad; use misskey_api::model::channel::Channel; #[cfg(feature = "12-79-0")] use misskey_api::model::gallery::GalleryPost; +#[cfg(feature = "12-109-0")] +use misskey_api::model::meta::AdminMeta; #[cfg(feature = "12-67-0")] use misskey_api::model::registry::{RegistryKey, RegistryScope, RegistryValue}; #[cfg(feature = "12-93-0")] @@ -4258,6 +4260,22 @@ pub trait ClientExt: Client + Sync { let pager = BackwardPager::new(self, endpoint::admin::ad::list::Request::default()); PagerStream::new(Box::pin(pager)) } + + /// Gets detailed information about the instance. + /// + /// This operation may require moderator privileges. + #[cfg(feature = "12-109-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-109-0")))] + fn admin_meta(&self) -> BoxFuture>> { + Box::pin(async move { + let meta = self + .request(endpoint::admin::meta::Request::default()) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(meta) + }) + } // }}} // {{{ Miscellaneous diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index d64cd966..e8079e85 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-109-0 = ["misskey-api/12-109-0", "misskey-util/12-109-0"] 12-108-0 = ["misskey-api/12-108-0", "misskey-util/12-108-0"] 12-107-0 = ["misskey-api/12-107-0", "misskey-util/12-107-0"] 12-106-0 = ["misskey-api/12-106-0", "misskey-util/12-106-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 3062820b..0d3dc167 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -102,6 +102,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-109-0` | v12.109.0 ~ v12.110.1 | v12.109.2 | //! | `12-108-0` | v12.108.0 ~ v12.108.1 | v12.108.1 | //! | `12-107-0` | v12.107.0 | v12.107.0 | //! | `12-106-0` | v12.106.0 ~ v12.106.3 | v12.106.0 | From 6826b18f74e1313e28e23ffe456e877b33bd87d9 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Sun, 16 Apr 2023 22:51:38 +0900 Subject: [PATCH 28/44] Change: Use HttpClient in streaming tests and examples for making requests to endpoints --- example/follow-back/Cargo.toml | 2 +- example/follow-back/src/main.rs | 15 ++++---- example/ping-pong/Cargo.toml | 2 +- example/ping-pong/src/main.rs | 13 ++++--- example/streaming/Cargo.toml | 2 +- example/streaming/src/main.rs | 11 +++--- example/word-reply/Cargo.toml | 2 +- example/word-reply/src/main.rs | 13 ++++--- misskey-api/src/streaming/channel/admin.rs | 7 ++-- misskey-api/src/streaming/channel/antenna.rs | 10 +++--- misskey-api/src/streaming/channel/channel.rs | 10 +++--- misskey-api/src/streaming/channel/drive.rs | 34 +++++++++++-------- .../src/streaming/channel/global_timeline.rs | 5 +-- misskey-api/src/streaming/channel/hashtag.rs | 10 +++--- .../src/streaming/channel/home_timeline.rs | 5 +-- .../src/streaming/channel/hybrid_timeline.rs | 5 +-- .../src/streaming/channel/local_timeline.rs | 5 +-- misskey-api/src/streaming/channel/main.rs | 32 +++++++++-------- .../src/streaming/channel/messaging.rs | 31 ++++++++++------- .../src/streaming/channel/messaging_index.rs | 14 ++++---- .../src/streaming/channel/user_list.rs | 14 ++++---- misskey-api/src/streaming/emoji.rs | 7 ++-- misskey-api/src/streaming/note.rs | 30 ++++++++++------ misskey-api/src/test.rs | 21 ++++++++++++ misskey-util/src/streaming.rs | 23 +++++++------ misskey/src/lib.rs | 14 +++++--- 26 files changed, 207 insertions(+), 130 deletions(-) diff --git a/example/follow-back/Cargo.toml b/example/follow-back/Cargo.toml index 22ae6baf..fbf19a46 100644 --- a/example/follow-back/Cargo.toml +++ b/example/follow-back/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" publish = false [dependencies] -misskey = { path = "../../misskey", version = "0.2.0", features = ["websocket-client"] } +misskey = { path = "../../misskey", version = "0.2.0", features = ["http-client", "websocket-client"] } tokio = { version = "1.0", features = ["full"] } structopt = "0.3.16" url = "2.1.1" diff --git a/example/follow-back/src/main.rs b/example/follow-back/src/main.rs index 2cf99f62..c07699a7 100644 --- a/example/follow-back/src/main.rs +++ b/example/follow-back/src/main.rs @@ -2,7 +2,7 @@ use anyhow::Result; use futures::stream::TryStreamExt; use misskey::prelude::*; use misskey::streaming::channel::main::MainStreamEvent; -use misskey::WebSocketClient; +use misskey::{HttpClient, WebSocketClient}; use structopt::StructOpt; use url::Url; @@ -18,15 +18,18 @@ struct Opt { async fn main() -> Result<()> { let opt = Opt::from_args(); - // Build a client and connect to Misskey. - let client = WebSocketClient::builder(opt.url) + // Create `HttpClient`. + let http_client = HttpClient::with_token(opt.url.clone(), opt.i.clone())?; + + // Build `WebSocketClient` and connect to Misskey. + let ws_client = WebSocketClient::builder(opt.url) .token(opt.i) .connect() .await?; // Connect to the main stream. // the main stream is a channel that streams events about the connected account, such as notifications. - let mut stream = client.main_stream().await?; + let mut stream = ws_client.main_stream().await?; // Wait for the next event using `try_next` method from `TryStreamExt`. while let Some(event) = stream.try_next().await? { @@ -36,8 +39,8 @@ async fn main() -> Result<()> { println!("followed from @{}", user.username); // Follow back `user` if you haven't already. - if !client.is_following(&user).await? { - client.follow(&user).await?; + if !http_client.is_following(&user).await? { + http_client.follow(&user).await?; } } // other events are just ignored diff --git a/example/ping-pong/Cargo.toml b/example/ping-pong/Cargo.toml index e2590c7a..4b7c9e18 100644 --- a/example/ping-pong/Cargo.toml +++ b/example/ping-pong/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" publish = false [dependencies] -misskey = { path = "../../misskey", version = "0.2.0", features = ["websocket-client"] } +misskey = { path = "../../misskey", version = "0.2.0", features = ["http-client", "websocket-client"] } tokio = { version = "1.0", features = ["full"] } structopt = "0.3.16" url = "2.1.1" diff --git a/example/ping-pong/src/main.rs b/example/ping-pong/src/main.rs index 620273d2..84501eb1 100644 --- a/example/ping-pong/src/main.rs +++ b/example/ping-pong/src/main.rs @@ -3,7 +3,7 @@ use futures::stream::TryStreamExt; use misskey::model::note::Note; use misskey::prelude::*; use misskey::streaming::channel::main::MainStreamEvent; -use misskey::WebSocketClient; +use misskey::{HttpClient, WebSocketClient}; use structopt::StructOpt; use url::Url; @@ -19,15 +19,18 @@ struct Opt { async fn main() -> Result<()> { let opt = Opt::from_args(); - // Build a client and connect to Misskey. - let client = WebSocketClient::builder(opt.url) + // Create `HttpClient`. + let http_client = HttpClient::with_token(opt.url.clone(), opt.i.clone())?; + + // Build `WebSocketClient` and connect to Misskey. + let ws_client = WebSocketClient::builder(opt.url) .token(opt.i) .connect() .await?; // Connect to the main stream. // the main stream is a channel that streams events about the connected account, such as notifications. - let mut stream = client.main_stream().await?; + let mut stream = ws_client.main_stream().await?; // Wait for the next event using `try_next` method from `TryStreamExt`. while let Some(event) = stream.try_next().await? { @@ -42,7 +45,7 @@ async fn main() -> Result<()> { println!("got ping from @{}", user.username); // Create a pong note as a reply to the mention - client.reply(note_id, "pong").await?; + http_client.reply(note_id, "pong").await?; } // other events are just ignored _ => {} diff --git a/example/streaming/Cargo.toml b/example/streaming/Cargo.toml index fa1c4e17..53a6e9cd 100644 --- a/example/streaming/Cargo.toml +++ b/example/streaming/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" publish = false [dependencies] -misskey = { path = "../../misskey", version = "0.2.0", features = ["websocket-client"] } +misskey = { path = "../../misskey", version = "0.2.0", features = ["http-client", "websocket-client"] } tokio = { version = "1.0", features = ["full"] } structopt = "0.3.16" url = "2.1.1" diff --git a/example/streaming/src/main.rs b/example/streaming/src/main.rs index 8c2752a5..15aa788d 100644 --- a/example/streaming/src/main.rs +++ b/example/streaming/src/main.rs @@ -1,7 +1,7 @@ use anyhow::Result; use futures::stream::TryStreamExt; use misskey::prelude::*; -use misskey::WebSocketClient; +use misskey::{HttpClient, WebSocketClient}; use structopt::StructOpt; use url::Url; @@ -17,20 +17,23 @@ struct Opt { async fn main() -> Result<()> { let opt = Opt::from_args(); + // Create `HttpClient`. + let http_client = HttpClient::with_token(opt.url.clone(), opt.i.clone())?; + // Configure and build a client using `WebSocketClientBuilder`. - let client = WebSocketClient::builder(opt.url) + let ws_client = WebSocketClient::builder(opt.url) .token(opt.i) .connect() .await?; // Run two asynchronous tasks simultaneously. - futures::try_join!(post(&client), timeline(&client))?; + futures::try_join!(post(&http_client), timeline(&ws_client))?; Ok(()) } // Post what you entered -async fn post(client: &WebSocketClient) -> Result<()> { +async fn post(client: &HttpClient) -> Result<()> { // We use async I/O from `tokio` for now use tokio::io::{self, AsyncBufReadExt, BufReader}; diff --git a/example/word-reply/Cargo.toml b/example/word-reply/Cargo.toml index 10a5d671..bcf4b006 100644 --- a/example/word-reply/Cargo.toml +++ b/example/word-reply/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" publish = false [dependencies] -misskey = { path = "../../misskey", version = "0.2.0", features = ["websocket-client"] } +misskey = { path = "../../misskey", version = "0.2.0", features = ["http-client", "websocket-client"] } tokio = { version = "1.0", features = ["full"] } structopt = "0.3.16" url = "2.1.1" diff --git a/example/word-reply/src/main.rs b/example/word-reply/src/main.rs index 62dd65aa..09d657c9 100644 --- a/example/word-reply/src/main.rs +++ b/example/word-reply/src/main.rs @@ -2,7 +2,7 @@ use anyhow::Result; use futures::stream::TryStreamExt; use misskey::model::query::Query; use misskey::prelude::*; -use misskey::WebSocketClient; +use misskey::{HttpClient, WebSocketClient}; use structopt::StructOpt; use url::Url; @@ -24,14 +24,17 @@ struct Opt { async fn main() -> Result<()> { let opt = Opt::from_args(); + // Create `HttpClient`. + let http_client = HttpClient::with_token(opt.url.clone(), opt.i.clone())?; + // Build a client and connect to Misskey. - let client = WebSocketClient::builder(opt.url) + let ws_client = WebSocketClient::builder(opt.url) .token(opt.i) .connect() .await?; // Create a new antenna. - let antenna = client + let antenna = http_client .build_antenna() .name("word-reply example") .include(Query::from_vec( @@ -42,14 +45,14 @@ async fn main() -> Result<()> { .await?; // Connect to the antenna's timeline. - let mut stream = client.antenna_timeline(&antenna).await?; + let mut stream = ws_client.antenna_timeline(&antenna).await?; // Wait for the next note using `try_next` method from `TryStreamExt`. while let Some(note) = stream.try_next().await? { println!("received a note from @{}", note.user.username); // Create a note as a reply to the note - client.reply(¬e, &opt.reply).await?; + http_client.reply(¬e, &opt.reply).await?; } Ok(()) diff --git a/misskey-api/src/streaming/channel/admin.rs b/misskey-api/src/streaming/channel/admin.rs index 1755ee2b..ab87f12a 100644 --- a/misskey-api/src/streaming/channel/admin.rs +++ b/misskey-api/src/streaming/channel/admin.rs @@ -33,7 +33,7 @@ impl misskey_core::streaming::ConnectChannelRequest for Request { #[cfg(test)] mod tests { use super::{AdminStreamEvent, Request}; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; @@ -46,12 +46,13 @@ mod tests { #[tokio::test] async fn stream() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let (user, _) = client.admin.create_user().await; + let (user, _) = http_client.admin.create_user().await; let mut stream = client.admin.channel(Request::default()).await.unwrap(); future::join( - client.test(crate::endpoint::users::report_abuse::Request { + http_client.test(crate::endpoint::users::report_abuse::Request { user_id: user.id, comment: "looks bad".to_string(), }), diff --git a/misskey-api/src/streaming/channel/antenna.rs b/misskey-api/src/streaming/channel/antenna.rs index 113e5384..cc1b5a0d 100644 --- a/misskey-api/src/streaming/channel/antenna.rs +++ b/misskey-api/src/streaming/channel/antenna.rs @@ -25,7 +25,7 @@ impl misskey_core::streaming::ConnectChannelRequest for Request { #[cfg(test)] mod tests { use super::Request; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; @@ -33,8 +33,9 @@ mod tests { async fn subscribe_unsubscribe() { use crate::model::{antenna::AntennaSource, query::Query}; + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let antenna = client + let antenna = http_client .test(crate::endpoint::antennas::create::Request { name: "test".to_string(), src: AntennaSource::All, @@ -65,8 +66,9 @@ mod tests { async fn stream() { use crate::model::{antenna::AntennaSource, query::Query}; + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let antenna = client + let antenna = http_client .test(crate::endpoint::antennas::create::Request { name: "test".to_string(), src: AntennaSource::All, @@ -91,7 +93,7 @@ mod tests { .await .unwrap(); - future::join(client.create_note(Some("hello"), None, None), async { + future::join(http_client.create_note(Some("hello"), None, None), async { stream.next().await.unwrap().unwrap() }) .await; diff --git a/misskey-api/src/streaming/channel/channel.rs b/misskey-api/src/streaming/channel/channel.rs index 9052825b..2b87d89c 100644 --- a/misskey-api/src/streaming/channel/channel.rs +++ b/misskey-api/src/streaming/channel/channel.rs @@ -30,14 +30,15 @@ impl misskey_core::streaming::ConnectChannelRequest for Request { #[cfg(test)] mod tests { use super::Request; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; #[tokio::test] async fn subscribe_unsubscribe() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let channel = client + let channel = http_client .test( crate::endpoint::channels::create::Request::builder() .name("test") @@ -56,8 +57,9 @@ mod tests { #[tokio::test] async fn stream() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let channel = client + let channel = http_client .test( crate::endpoint::channels::create::Request::builder() .name("test") @@ -73,7 +75,7 @@ mod tests { .unwrap(); future::join( - client.test( + http_client.test( crate::endpoint::notes::create::Request::builder() .text("some text") .channel_id(channel.id) diff --git a/misskey-api/src/streaming/channel/drive.rs b/misskey-api/src/streaming/channel/drive.rs index 2443c6c3..598f6dfe 100644 --- a/misskey-api/src/streaming/channel/drive.rs +++ b/misskey-api/src/streaming/channel/drive.rs @@ -30,7 +30,7 @@ impl misskey_core::streaming::ConnectChannelRequest for Request { #[cfg(test)] mod tests { use super::{DriveStreamEvent, Request}; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; @@ -43,11 +43,12 @@ mod tests { #[tokio::test] async fn stream_folder_created() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; let mut stream = client.channel(Request::default()).await.unwrap(); future::join( - client.test(crate::endpoint::drive::folders::create::Request::default()), + http_client.test(crate::endpoint::drive::folders::create::Request::default()), async { loop { match stream.next().await.unwrap().unwrap() { @@ -62,14 +63,15 @@ mod tests { #[tokio::test] async fn stream_folder_updated() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let folder = client + let folder = http_client .test(crate::endpoint::drive::folders::create::Request::default()) .await; let mut stream = client.channel(Request::default()).await.unwrap(); future::join( - client.test(crate::endpoint::drive::folders::update::Request { + http_client.test(crate::endpoint::drive::folders::update::Request { folder_id: folder.id, name: Some("test".to_string()), parent_id: None, @@ -88,14 +90,15 @@ mod tests { #[tokio::test] async fn stream_folder_deleted() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let folder = client + let folder = http_client .test(crate::endpoint::drive::folders::create::Request::default()) .await; let mut stream = client.channel(Request::default()).await.unwrap(); future::join( - client.test(crate::endpoint::drive::folders::delete::Request { + http_client.test(crate::endpoint::drive::folders::delete::Request { folder_id: folder.id, }), async { @@ -112,11 +115,12 @@ mod tests { #[tokio::test] async fn stream_file_created() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let url = client.avatar_url().await; + let url = http_client.avatar_url().await; let mut stream = client.channel(Request::default()).await.unwrap(); - future::join(client.upload_from_url(url), async { + future::join(http_client.upload_from_url(url), async { loop { match stream.next().await.unwrap().unwrap() { DriveStreamEvent::FileCreated(_) => break, @@ -129,13 +133,14 @@ mod tests { #[tokio::test] async fn stream_file_updated() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let url = client.avatar_url().await; - let file = client.upload_from_url(url).await; + let url = http_client.avatar_url().await; + let file = http_client.upload_from_url(url).await; let mut stream = client.channel(Request::default()).await.unwrap(); future::join( - client.test( + http_client.test( crate::endpoint::drive::files::update::Request::builder() .file_id(file.id) .name("test") @@ -155,13 +160,14 @@ mod tests { #[tokio::test] async fn stream_file_deleted() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let url = client.avatar_url().await; - let file = client.upload_from_url(url).await; + let url = http_client.avatar_url().await; + let file = http_client.upload_from_url(url).await; let mut stream = client.channel(Request::default()).await.unwrap(); future::join( - client.test(crate::endpoint::drive::files::delete::Request { file_id: file.id }), + http_client.test(crate::endpoint::drive::files::delete::Request { file_id: file.id }), async { loop { match stream.next().await.unwrap().unwrap() { diff --git a/misskey-api/src/streaming/channel/global_timeline.rs b/misskey-api/src/streaming/channel/global_timeline.rs index 5eb9c56e..0c58d6a4 100644 --- a/misskey-api/src/streaming/channel/global_timeline.rs +++ b/misskey-api/src/streaming/channel/global_timeline.rs @@ -22,7 +22,7 @@ impl misskey_core::streaming::ConnectChannelRequest for Request { #[cfg(test)] mod tests { use super::Request; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; @@ -36,12 +36,13 @@ mod tests { #[tokio::test] async fn stream() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; let mut stream = client.channel(Request::default()).await.unwrap(); future::join( - client.create_note(Some("The world is fancy!"), None, None), + http_client.create_note(Some("The world is fancy!"), None, None), async { stream.next().await.unwrap().unwrap() }, ) .await; diff --git a/misskey-api/src/streaming/channel/hashtag.rs b/misskey-api/src/streaming/channel/hashtag.rs index e4e158c6..9bfeab22 100644 --- a/misskey-api/src/streaming/channel/hashtag.rs +++ b/misskey-api/src/streaming/channel/hashtag.rs @@ -26,7 +26,7 @@ impl misskey_core::streaming::ConnectChannelRequest for Request { mod tests { use super::Request; use crate::model::query::Query; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; @@ -45,6 +45,7 @@ mod tests { #[tokio::test] async fn stream() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; let mut stream = client .channel(Request { @@ -53,9 +54,10 @@ mod tests { .await .unwrap(); - future::join(client.create_note(Some("#test #good"), None, None), async { - stream.next().await.unwrap().unwrap() - }) + future::join( + http_client.create_note(Some("#test #good"), None, None), + async { stream.next().await.unwrap().unwrap() }, + ) .await; } } diff --git a/misskey-api/src/streaming/channel/home_timeline.rs b/misskey-api/src/streaming/channel/home_timeline.rs index 26e07b5a..8cd711c6 100644 --- a/misskey-api/src/streaming/channel/home_timeline.rs +++ b/misskey-api/src/streaming/channel/home_timeline.rs @@ -22,7 +22,7 @@ impl misskey_core::streaming::ConnectChannelRequest for Request { #[cfg(test)] mod tests { use super::Request; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; @@ -36,12 +36,13 @@ mod tests { #[tokio::test] async fn stream() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; let mut stream = client.channel(Request::default()).await.unwrap(); future::join( - client.create_note(Some("The world is fancy!"), None, None), + http_client.create_note(Some("The world is fancy!"), None, None), async { stream.next().await.unwrap().unwrap() }, ) .await; diff --git a/misskey-api/src/streaming/channel/hybrid_timeline.rs b/misskey-api/src/streaming/channel/hybrid_timeline.rs index 32ee5cfa..0c28e5e6 100644 --- a/misskey-api/src/streaming/channel/hybrid_timeline.rs +++ b/misskey-api/src/streaming/channel/hybrid_timeline.rs @@ -22,7 +22,7 @@ impl misskey_core::streaming::ConnectChannelRequest for Request { #[cfg(test)] mod tests { use super::Request; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; @@ -36,12 +36,13 @@ mod tests { #[tokio::test] async fn stream() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; let mut stream = client.channel(Request::default()).await.unwrap(); future::join( - client.create_note(Some("The world is fancy!"), None, None), + http_client.create_note(Some("The world is fancy!"), None, None), async { stream.next().await.unwrap().unwrap() }, ) .await; diff --git a/misskey-api/src/streaming/channel/local_timeline.rs b/misskey-api/src/streaming/channel/local_timeline.rs index 55a26d67..981e2e1b 100644 --- a/misskey-api/src/streaming/channel/local_timeline.rs +++ b/misskey-api/src/streaming/channel/local_timeline.rs @@ -22,7 +22,7 @@ impl misskey_core::streaming::ConnectChannelRequest for Request { #[cfg(test)] mod tests { use super::Request; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; @@ -36,12 +36,13 @@ mod tests { #[tokio::test] async fn stream() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; let mut stream = client.channel(Request::default()).await.unwrap(); future::join( - client.create_note(Some("The world is fancy!"), None, None), + http_client.create_note(Some("The world is fancy!"), None, None), async { stream.next().await.unwrap().unwrap() }, ) .await; diff --git a/misskey-api/src/streaming/channel/main.rs b/misskey-api/src/streaming/channel/main.rs index bde833fd..7d9ad04c 100644 --- a/misskey-api/src/streaming/channel/main.rs +++ b/misskey-api/src/streaming/channel/main.rs @@ -87,7 +87,7 @@ impl misskey_core::streaming::ConnectChannelRequest for Request { #[cfg(test)] mod tests { use super::{MainStreamEvent, Request}; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; @@ -100,18 +100,17 @@ mod tests { #[tokio::test] async fn reply() { - let test_client = TestClient::new().await; + let admin_client = HttpTestClient::new().admin; // create fresh user (for new main stream) to avoid events // to be captured by other test cases - let (_, client) = test_client.admin.create_streaming_user().await; + let (_, http_client, client) = admin_client.create_http_and_ws_client().await; let mut stream = client.channel(Request::default()).await.unwrap(); future::join( async { - let note = client.create_note(Some("awesome"), None, None).await; - test_client - .user + let note = http_client.create_note(Some("awesome"), None, None).await; + admin_client .create_note(Some("nice"), None, Some(note.id)) .await; }, @@ -129,14 +128,14 @@ mod tests { #[tokio::test] async fn mention() { - let test_client = TestClient::new().await; + let http_client = HttpTestClient::new(); // ditto - let (me, client) = test_client.admin.create_streaming_user().await; + let (me, client) = http_client.admin.create_streaming_user().await; let mut stream = client.channel(Request::default()).await.unwrap(); futures::future::join( - test_client + http_client .user .create_note(Some(&format!("@{} hello", me.username)), None, None), async { @@ -157,16 +156,19 @@ mod tests { use crate::model::drive::DriveFile; // ditto - let (_, client) = TestClient::new().await.admin.create_streaming_user().await; + let (_, http_client, client) = HttpTestClient::new() + .admin + .create_http_and_ws_client() + .await; let mut stream = client.channel(Request::default()).await.unwrap(); - let url = client.avatar_url().await; + let url = http_client.avatar_url().await; let expected_marker = ulid_crate::Ulid::new().to_string(); let expected_comment = ulid_crate::Ulid::new().to_string(); futures::future::join( - client.test(crate::endpoint::drive::files::upload_from_url::Request { + http_client.test(crate::endpoint::drive::files::upload_from_url::Request { url, folder_id: None, is_sensitive: None, @@ -198,14 +200,14 @@ mod tests { async fn registry_updated() { use serde_json::json; - let test_client = TestClient::new().await; + let http_client = HttpTestClient::new(); // ditto - let (_, client) = test_client.admin.create_streaming_user().await; + let (_, http_client, client) = http_client.admin.create_http_and_ws_client().await; let mut stream = client.channel(Request::default()).await.unwrap(); future::join( - client.test(crate::endpoint::i::registry::set::Request { + http_client.test(crate::endpoint::i::registry::set::Request { key: "stream_test".into(), value: json!({ "test": [] }), scope: None, diff --git a/misskey-api/src/streaming/channel/messaging.rs b/misskey-api/src/streaming/channel/messaging.rs index 930cf90f..40a5c7fd 100644 --- a/misskey-api/src/streaming/channel/messaging.rs +++ b/misskey-api/src/streaming/channel/messaging.rs @@ -37,14 +37,15 @@ impl misskey_core::streaming::ConnectChannelRequest for Request { #[cfg(test)] mod tests { use super::{Message, MessagingStreamEvent, Request}; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, SinkExt, StreamExt}; #[tokio::test] async fn subscribe_unsubscribe_otherparty() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let admin = client.admin.me().await; + let admin = http_client.admin.me().await; let mut stream = client .user .channel(Request::Otherparty(admin.id)) @@ -55,8 +56,9 @@ mod tests { #[tokio::test] async fn subscribe_unsubscribe_group() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let group = client + let group = http_client .test(crate::endpoint::users::groups::create::Request { name: "test".to_string(), }) @@ -67,9 +69,10 @@ mod tests { #[tokio::test] async fn stream_message() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let user = client.user.me().await; - let admin = client.admin.me().await; + let user = http_client.user.me().await; + let admin = http_client.admin.me().await; let mut stream = client .user .channel(Request::Otherparty(admin.id)) @@ -77,7 +80,7 @@ mod tests { .unwrap(); future::join( - client + http_client .admin .test(crate::endpoint::messaging::messages::create::Request { text: Some("hi".to_string()), @@ -99,10 +102,11 @@ mod tests { #[tokio::test] async fn stream_deleted() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let user = client.user.me().await; - let admin = client.admin.me().await; - let message = client + let user = http_client.user.me().await; + let admin = http_client.admin.me().await; + let message = http_client .admin .test(crate::endpoint::messaging::messages::create::Request { text: Some("hi".to_string()), @@ -118,7 +122,7 @@ mod tests { .unwrap(); future::join( - client + http_client .admin .test(crate::endpoint::messaging::messages::delete::Request { message_id: message.id, @@ -137,10 +141,11 @@ mod tests { #[tokio::test] async fn stream_read() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let admin = client.admin.me().await; - let user = client.user.me().await; - let message = client + let admin = http_client.admin.me().await; + let user = http_client.user.me().await; + let message = http_client .user .test(crate::endpoint::messaging::messages::create::Request { text: Some("hi".to_string()), diff --git a/misskey-api/src/streaming/channel/messaging_index.rs b/misskey-api/src/streaming/channel/messaging_index.rs index 6e98be8b..9aea9da4 100644 --- a/misskey-api/src/streaming/channel/messaging_index.rs +++ b/misskey-api/src/streaming/channel/messaging_index.rs @@ -24,7 +24,7 @@ impl misskey_core::streaming::ConnectChannelRequest for Request { #[cfg(test)] mod tests { use super::{MessagingIndexStreamEvent, Request}; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; @@ -37,12 +37,13 @@ mod tests { #[tokio::test] async fn stream_message() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let user = client.user.me().await; + let user = http_client.user.me().await; let mut stream = client.user.channel(Request::default()).await.unwrap(); future::join( - client + http_client .admin .test(crate::endpoint::messaging::messages::create::Request { text: Some("hi".to_string()), @@ -64,9 +65,10 @@ mod tests { #[tokio::test] async fn stream_read() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let user = client.user.me().await; - let message = client + let user = http_client.user.me().await; + let message = http_client .admin .test(crate::endpoint::messaging::messages::create::Request { text: Some("hi".to_string()), @@ -78,7 +80,7 @@ mod tests { let mut stream = client.user.channel(Request::default()).await.unwrap(); future::join( - client + http_client .user .test(crate::endpoint::messaging::messages::read::Request { message_id: message.id, diff --git a/misskey-api/src/streaming/channel/user_list.rs b/misskey-api/src/streaming/channel/user_list.rs index dc909ead..1236c3c8 100644 --- a/misskey-api/src/streaming/channel/user_list.rs +++ b/misskey-api/src/streaming/channel/user_list.rs @@ -30,14 +30,15 @@ impl misskey_core::streaming::ConnectChannelRequest for Request { #[cfg(test)] mod tests { use super::{Request, UserListEvent}; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; #[tokio::test] async fn subscribe_unsubscribe() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let list = client + let list = http_client .test(crate::endpoint::users::lists::create::Request { name: "test".to_string(), }) @@ -49,15 +50,16 @@ mod tests { #[tokio::test] async fn stream_note() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let admin = client.admin.me().await; - let list = client + let admin = http_client.admin.me().await; + let list = http_client .user .test(crate::endpoint::users::lists::create::Request { name: "test".to_string(), }) .await; - client + http_client .user .test(crate::endpoint::users::lists::push::Request { list_id: list.id.clone(), @@ -72,7 +74,7 @@ mod tests { .unwrap(); future::join( - client + http_client .admin .create_note(Some("The world is fancy!"), None, None), async { diff --git a/misskey-api/src/streaming/emoji.rs b/misskey-api/src/streaming/emoji.rs index 7341090a..cf9f4470 100644 --- a/misskey-api/src/streaming/emoji.rs +++ b/misskey-api/src/streaming/emoji.rs @@ -15,18 +15,19 @@ impl misskey_core::streaming::BroadcastEvent for EmojiAddedEvent { #[cfg(test)] mod tests { use super::EmojiAddedEvent; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; #[tokio::test] async fn broadcast() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let url = client.avatar_url().await; + let url = http_client.avatar_url().await; let mut stream = client.broadcast::().await.unwrap(); - future::join(client.admin.add_emoji_from_url(url), async { + future::join(http_client.admin.add_emoji_from_url(url), async { stream.next().await.unwrap().unwrap() }) .await; diff --git a/misskey-api/src/streaming/note.rs b/misskey-api/src/streaming/note.rs index d4e1a48c..4be40faf 100644 --- a/misskey-api/src/streaming/note.rs +++ b/misskey-api/src/streaming/note.rs @@ -27,14 +27,15 @@ impl misskey_core::streaming::SubNoteEvent for NoteUpdateEvent {} #[cfg(test)] mod tests { use super::NoteUpdateEvent; - use crate::test::{websocket::TestClient, ClientExt}; + use crate::test::{http::TestClient as HttpTestClient, websocket::TestClient, ClientExt}; use futures::{future, StreamExt}; #[tokio::test] async fn subscribe_unsubscribe() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let note = client.create_note(Some("test"), None, None).await; + let note = http_client.create_note(Some("test"), None, None).await; let mut stream = client .subnote::(note.id.to_string()) @@ -47,8 +48,9 @@ mod tests { async fn reacted() { use crate::model::note::Reaction; + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let note = client + let note = http_client .user .create_note(Some("looks good"), None, None) .await; @@ -56,7 +58,7 @@ mod tests { let mut stream = client.user.subnote(note.id.to_string()).await.unwrap(); future::join( - client + http_client .admin .test(crate::endpoint::notes::reactions::create::Request { note_id: note.id, @@ -78,12 +80,13 @@ mod tests { async fn unreacted() { use crate::model::note::Reaction; + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let note = client + let note = http_client .user .create_note(Some("not so good"), None, None) .await; - client + http_client .admin .test(crate::endpoint::notes::reactions::create::Request { note_id: note.id.clone(), @@ -94,7 +97,7 @@ mod tests { let mut stream = client.user.subnote(note.id.to_string()).await.unwrap(); future::join( - client + http_client .admin .test(crate::endpoint::notes::reactions::delete::Request { note_id: note.id }), async { @@ -111,13 +114,17 @@ mod tests { #[tokio::test] async fn deleted() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; - let note = client.user.create_note(Some("hmm..."), None, None).await; + let note = http_client + .user + .create_note(Some("hmm..."), None, None) + .await; let mut stream = client.user.subnote(note.id.to_string()).await.unwrap(); future::join( - client + http_client .user .test(crate::endpoint::notes::delete::Request { note_id: note.id }), async { @@ -134,6 +141,7 @@ mod tests { #[tokio::test] async fn poll_voted() { + let http_client = HttpTestClient::new(); let client = TestClient::new().await; let poll = crate::endpoint::notes::create::PollRequest { choices: vec!["a".to_string(), "b".to_string()], @@ -141,7 +149,7 @@ mod tests { expires_at: Some(chrono::Utc::now() + chrono::Duration::hours(1)), expired_after: None, }; - let note = client + let note = http_client .user .test( crate::endpoint::notes::create::Request::builder() @@ -155,7 +163,7 @@ mod tests { let mut stream = client.user.subnote(note.id.to_string()).await.unwrap(); futures::future::join( - client + http_client .user .test(crate::endpoint::notes::polls::vote::Request { note_id: note.id, diff --git a/misskey-api/src/test.rs b/misskey-api/src/test.rs index 87205b23..2c4547f3 100644 --- a/misskey-api/src/test.rs +++ b/misskey-api/src/test.rs @@ -17,6 +17,7 @@ pub trait ClientExt { async fn test(&self, req: R) -> R::Response; async fn create_user(&self) -> (User, HttpClient); async fn create_streaming_user(&self) -> (User, WebSocketClient); + async fn create_http_and_ws_client(&self) -> (User, HttpClient, WebSocketClient); async fn me(&self) -> User; async fn create_note( &self, @@ -75,6 +76,26 @@ impl ClientExt for T { ) } + async fn create_http_and_ws_client(&self) -> (User, HttpClient, WebSocketClient) { + let ulid = Ulid::new().to_string(); + let res = self + .test(crate::endpoint::admin::accounts::create::Request { + username: ulid[..20].to_owned(), + password: "test".to_string(), + }) + .await; + + ( + res.user, + HttpClient::with_token(env::api_url(), res.token.clone()).unwrap(), + WebSocketClient::builder(env::websocket_url()) + .token(res.token) + .connect() + .await + .unwrap(), + ) + } + async fn create_note( &self, text: Option<&str>, diff --git a/misskey-util/src/streaming.rs b/misskey-util/src/streaming.rs index bea0eaf0..b888be84 100644 --- a/misskey-util/src/streaming.rs +++ b/misskey-util/src/streaming.rs @@ -40,13 +40,14 @@ pub trait StreamingClientExt: StreamingClient + Sync { /// # #[tokio::main] /// # async fn main() -> anyhow::Result<()> { /// # use misskey_api as misskey; - /// # let client = misskey_test::test_websocket_client(misskey_test::env::token()).await?; + /// # let http_client = misskey_test::test_client().await?; + /// # let ws_client = misskey_test::test_websocket_client(misskey_test::env::token()).await?; /// # misskey_test::persist(std::time::Duration::from_secs(3), async move { /// use futures::stream::TryStreamExt; /// use misskey::streaming::note::NoteUpdateEvent; /// - /// let note = client.create_note("Hello!").await?; - /// let mut note_stream = client.subscribe_note(¬e).await?; + /// let note = http_client.create_note("Hello!").await?; + /// let mut note_stream = ws_client.subscribe_note(¬e).await?; /// // Wait for the next event in the stream. /// while let Some(event) = note_stream.try_next().await? { /// match event { @@ -93,7 +94,8 @@ pub trait StreamingClientExt: StreamingClient + Sync { /// # use misskey_util::StreamingClientExt; /// # #[tokio::main] /// # async fn main() -> anyhow::Result<()> { - /// # let client = misskey_test::test_websocket_client(misskey_test::env::token()).await?; + /// # let http_client = misskey_test::test_client().await?; + /// # let ws_client = misskey_test::test_websocket_client(misskey_test::env::token()).await?; /// # mod misskey { /// # pub use misskey_api::streaming; /// # pub use misskey_util::ClientExt; @@ -103,15 +105,15 @@ pub trait StreamingClientExt: StreamingClient + Sync { /// use misskey::ClientExt; /// use misskey::streaming::channel::main::MainStreamEvent; /// - /// let mut main_stream = client.main_stream().await?; + /// let mut main_stream = ws_client.main_stream().await?; /// // Wait for the next event in the main stream. /// while let Some(event) = main_stream.try_next().await? { /// match event { /// // Check if the event is 'followed' /// MainStreamEvent::Followed(user) => { /// // Follow back `user` if you haven't already. - /// if !client.is_following(&user).await? { - /// client.follow(&user).await?; + /// if !http_client.is_following(&user).await? { + /// http_client.follow(&user).await?; /// } /// } /// // other events are just ignored here @@ -151,7 +153,8 @@ pub trait StreamingClientExt: StreamingClient + Sync { /// # use misskey_util::StreamingClientExt; /// # #[tokio::main] /// # async fn main() -> anyhow::Result<()> { - /// # let client = misskey_test::test_websocket_client(misskey_test::env::token()).await?; + /// # let http_client = misskey_test::test_client().await?; + /// # let ws_client = misskey_test::test_websocket_client(misskey_test::env::token()).await?; /// # mod misskey { /// # pub use misskey_api::model; /// # pub use misskey_util::ClientExt; @@ -161,13 +164,13 @@ pub trait StreamingClientExt: StreamingClient + Sync { /// use misskey::ClientExt; /// use misskey::model::note::Note; /// - /// let mut home = client.home_timeline().await?; + /// let mut home = ws_client.home_timeline().await?; /// // Wait for the next note in the home timeline. /// while let Some(note) = home.try_next().await? { /// // if the note's text contains "Hello", react with "🙌". /// match note { /// Note { id, text: Some(text), .. } if text.contains("Hello") => { - /// client.react(id, "🙌").await?; + /// http_client.react(id, "🙌").await?; /// } /// _ => {} /// } diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 0d3dc167..6b042528 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -36,18 +36,22 @@ //! use futures::stream::TryStreamExt; //! use misskey::prelude::*; //! use misskey::streaming::channel::main::MainStreamEvent; -//! use misskey::WebSocketClient; +//! use misskey::{HttpClient, WebSocketClient}; //! //! # #[tokio::main] //! # async fn main() -> anyhow::Result<()> { -//! let client = WebSocketClient::builder("wss://your.instance.example/streaming") +//! let http_client = HttpClient::builder("https://your.instance.example/api/") +//! .token("API_TOKEN") +//! .build()?; +//! +//! let ws_client = WebSocketClient::builder("wss://your.instance.example/streaming") //! .token("YOUR_API_TOKEN") //! .connect() //! .await?; //! //! // Connect to the main stream. //! // The main stream is a channel that streams events about the connected account. -//! let mut stream = client.main_stream().await?; +//! let mut stream = ws_client.main_stream().await?; //! //! // Wait for the next event in the main stream. //! while let Some(event) = stream.try_next().await? { @@ -57,8 +61,8 @@ //! println!("followed from @{}", user.username); //! //! // Follow back `user` if you haven't already. -//! if !client.is_following(&user).await? { -//! client.follow(&user).await?; +//! if !http_client.is_following(&user).await? { +//! http_client.follow(&user).await?; //! } //! } //! // other events are just ignored here From 0181dbeb340adc4c8e3c6395cc708e5e376d3821 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Mon, 17 Apr 2023 00:59:07 +0900 Subject: [PATCH 29/44] Change: Remove Client trait from WebSocketClient --- misskey-websocket/CHANGELOG.md | 4 ++++ misskey-websocket/Cargo.toml | 2 ++ misskey-websocket/src/broker/channel.rs | 2 ++ misskey-websocket/src/broker/handler.rs | 26 ++++++++++++++++++---- misskey-websocket/src/broker/model.rs | 10 +++++++-- misskey-websocket/src/client.rs | 29 +++++++++++++++---------- misskey-websocket/src/model.rs | 2 ++ misskey-websocket/src/model/incoming.rs | 10 ++++++++- misskey-websocket/src/model/outgoing.rs | 5 ++++- 9 files changed, 70 insertions(+), 20 deletions(-) diff --git a/misskey-websocket/CHANGELOG.md b/misskey-websocket/CHANGELOG.md index b9d1c357..131f4151 100644 --- a/misskey-websocket/CHANGELOG.md +++ b/misskey-websocket/CHANGELOG.md @@ -18,6 +18,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Deprecated ### Removed + +- implementation of `Client` to `WebSocketClient` + - For Misskey v12.111.0 ~ + ### Fixed ### Security diff --git a/misskey-websocket/Cargo.toml b/misskey-websocket/Cargo.toml index 176fe55c..1c249115 100644 --- a/misskey-websocket/Cargo.toml +++ b/misskey-websocket/Cargo.toml @@ -19,6 +19,8 @@ inspect-contents = [] tokio-runtime = ["tokio", "async-tungstenite/tokio-runtime", "async-tungstenite/tokio-rustls-webpki-roots"] async-std-runtime = ["async-std", "async-tungstenite/async-std-runtime", "async-tungstenite/async-tls"] +12-111-0 = [] + [dependencies] misskey-core = { path = "../misskey-core", version = "0.2.0" } serde = { version = "1.0.83", features = ["derive"] } diff --git a/misskey-websocket/src/broker/channel.rs b/misskey-websocket/src/broker/channel.rs index a518fad8..cb370cd8 100644 --- a/misskey-websocket/src/broker/channel.rs +++ b/misskey-websocket/src/broker/channel.rs @@ -1,10 +1,12 @@ mod channel_pong; mod control; +#[cfg(not(feature = "12-111-0"))] mod response_oneshot; mod response_stream; pub(crate) use channel_pong::{channel_pong_channel, ChannelPongSender}; pub(crate) use control::{control_channel, ControlReceiver, ControlSender}; +#[cfg(not(feature = "12-111-0"))] pub(crate) use response_oneshot::{response_channel, ResponseSender}; pub(crate) use response_stream::{ response_stream_channel, ResponseStreamReceiver, ResponseStreamSender, diff --git a/misskey-websocket/src/broker/handler.rs b/misskey-websocket/src/broker/handler.rs index faa8dc07..71fade88 100644 --- a/misskey-websocket/src/broker/handler.rs +++ b/misskey-websocket/src/broker/handler.rs @@ -1,23 +1,28 @@ use std::collections::HashMap; +#[cfg(not(feature = "12-111-0"))] +use crate::broker::channel::ResponseSender; use crate::broker::{ - channel::{ChannelPongSender, ResponseSender, ResponseStreamSender}, + channel::{ChannelPongSender, ResponseStreamSender}, model::{BroadcastId, BrokerControl}, }; use crate::error::Result; +#[cfg(not(feature = "12-111-0"))] +use crate::model::{incoming::ApiMessage, ApiRequestId}; use crate::model::{ incoming::{ - ApiMessage, ChannelMessage, ConnectedMessage, IncomingMessage, IncomingMessageType, - NoteUpdatedMessage, + ChannelMessage, ConnectedMessage, IncomingMessage, IncomingMessageType, NoteUpdatedMessage, }, outgoing::OutgoingMessage, - ApiRequestId, ChannelId, SubNoteId, + ChannelId, SubNoteId, }; use log::{info, warn}; +#[cfg(not(feature = "12-111-0"))] use misskey_core::model::ApiResult; use serde_json::value::{self, Value}; +#[cfg(not(feature = "12-111-0"))] #[derive(Debug)] struct ApiHandler { message: OutgoingMessage, @@ -39,6 +44,7 @@ struct ChannelHandler { #[derive(Debug)] pub(crate) struct Handler { + #[cfg(not(feature = "12-111-0"))] api: HashMap, sub_note: HashMap, channel: HashMap, @@ -48,6 +54,7 @@ pub(crate) struct Handler { impl Handler { pub fn new() -> Handler { Handler { + #[cfg(not(feature = "12-111-0"))] api: HashMap::new(), sub_note: HashMap::new(), channel: HashMap::new(), @@ -58,6 +65,7 @@ impl Handler { pub fn restore_messages(&mut self) -> Vec { let mut messages = Vec::new(); + #[cfg(not(feature = "12-111-0"))] for ApiHandler { message, .. } in self.api.values() { messages.push(message.clone()); } @@ -76,6 +84,7 @@ impl Handler { pub fn control(&mut self, ctrl: BrokerControl) -> Option { match ctrl { + #[cfg(not(feature = "12-111-0"))] BrokerControl::Api { id, endpoint, @@ -149,6 +158,7 @@ impl Handler { } } + #[cfg(not(feature = "12-111-0"))] pub fn is_empty(&self) -> bool { self.api.is_empty() && self.sub_note.is_empty() @@ -156,8 +166,16 @@ impl Handler { && self.broadcast.values().all(|m| m.is_empty()) } + #[cfg(feature = "12-111-0")] + pub fn is_empty(&self) -> bool { + self.sub_note.is_empty() + && self.channel.is_empty() + && self.broadcast.values().all(|m| m.is_empty()) + } + pub async fn handle(&mut self, msg: IncomingMessage) -> Result<()> { match msg.type_ { + #[cfg(not(feature = "12-111-0"))] IncomingMessageType::Api(id) => { if let Some(ApiHandler { sender, .. }) = self.api.remove(&id) { let msg: ApiResult = value::from_value(msg.body)?; diff --git a/misskey-websocket/src/broker/model.rs b/misskey-websocket/src/broker/model.rs index dce5658b..6683a651 100644 --- a/misskey-websocket/src/broker/model.rs +++ b/misskey-websocket/src/broker/model.rs @@ -3,12 +3,17 @@ use std::pin::Pin; use std::sync::Arc; use std::task::{Context, Poll}; -use crate::broker::channel::{ChannelPongSender, ResponseSender, ResponseStreamSender}; +#[cfg(not(feature = "12-111-0"))] +use crate::broker::channel::ResponseSender; +use crate::broker::channel::{ChannelPongSender, ResponseStreamSender}; use crate::error::Error; -use crate::model::{ApiRequestId, ChannelId, SubNoteId}; +#[cfg(not(feature = "12-111-0"))] +use crate::model::ApiRequestId; +use crate::model::{ChannelId, SubNoteId}; use async_rwlock::RwLock; use futures_util::future::{BoxFuture, Future, FutureExt}; +#[cfg(not(feature = "12-111-0"))] use misskey_core::model::ApiResult; use serde_json::Value; use uuid::Uuid; @@ -24,6 +29,7 @@ impl BroadcastId { #[derive(Debug)] pub(crate) enum BrokerControl { + #[cfg(not(feature = "12-111-0"))] Api { id: ApiRequestId, endpoint: &'static str, diff --git a/misskey-websocket/src/client.rs b/misskey-websocket/src/client.rs index b9c2718d..8721d1f3 100644 --- a/misskey-websocket/src/client.rs +++ b/misskey-websocket/src/client.rs @@ -1,24 +1,25 @@ use std::fmt::{self, Debug}; -use crate::broker::{ - channel::{response_channel, ControlSender}, - model::{BrokerControl, SharedBrokerState}, - Broker, ReconnectConfig, -}; +#[cfg(not(feature = "12-111-0"))] +use crate::broker::{channel::response_channel, model::BrokerControl}; +use crate::broker::{channel::ControlSender, model::SharedBrokerState, Broker, ReconnectConfig}; use crate::error::{Error, Result}; -use crate::model::{ApiRequestId, SubNoteId}; +#[cfg(not(feature = "12-111-0"))] +use crate::model::ApiRequestId; +use crate::model::SubNoteId; use async_tungstenite::tungstenite::http::HeaderMap; +#[cfg(not(feature = "12-111-0"))] +use futures_util::sink::SinkExt; use futures_util::{ future::{BoxFuture, FutureExt, TryFutureExt}, - sink::{Sink, SinkExt}, + sink::Sink, stream::{BoxStream, Stream, StreamExt}, }; -use misskey_core::model::ApiResult; -use misskey_core::{ - streaming::{BoxStreamSink, StreamingClient}, - Client, -}; +use misskey_core::streaming::{BoxStreamSink, StreamingClient}; +#[cfg(not(feature = "12-111-0"))] +use misskey_core::{model::ApiResult, Client}; +#[cfg(not(feature = "12-111-0"))] use serde_json::value; use url::Url; @@ -168,6 +169,9 @@ impl WebSocketClient { } } +// API call through streaming is disabled for Misskey v12.111.0 and later. +// https://github.com/misskey-dev/misskey/commit/3770bb6 +#[cfg(not(feature = "12-111-0"))] impl Client for WebSocketClient { type Error = Error; @@ -257,6 +261,7 @@ impl StreamingClient for WebSocketClient { } } +#[cfg(not(feature = "12-111-0"))] #[cfg(test)] mod tests { use super::{builder::WebSocketClientBuilder, WebSocketClient}; diff --git a/misskey-websocket/src/model.rs b/misskey-websocket/src/model.rs index 12ae3e7d..7ee6730e 100644 --- a/misskey-websocket/src/model.rs +++ b/misskey-websocket/src/model.rs @@ -18,10 +18,12 @@ impl ChannelId { } } +#[cfg(not(feature = "12-111-0"))] #[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Hash, Debug)] #[serde(transparent)] pub struct ApiRequestId(pub Uuid); +#[cfg(not(feature = "12-111-0"))] impl ApiRequestId { pub fn uuid() -> Self { ApiRequestId(Uuid::new_v4()) diff --git a/misskey-websocket/src/model/incoming.rs b/misskey-websocket/src/model/incoming.rs index 486a4e2c..be129c44 100644 --- a/misskey-websocket/src/model/incoming.rs +++ b/misskey-websocket/src/model/incoming.rs @@ -1,12 +1,16 @@ -use crate::model::{ApiRequestId, ChannelId, SubNoteId}; +#[cfg(not(feature = "12-111-0"))] +use crate::model::ApiRequestId; +use crate::model::{ChannelId, SubNoteId}; use serde::de::{self, Deserializer}; use serde::Deserialize; use serde_json::Value; +#[cfg(not(feature = "12-111-0"))] use uuid::Uuid; #[derive(Debug, Clone, PartialEq, Eq)] pub enum IncomingMessageType { + #[cfg(not(feature = "12-111-0"))] Api(ApiRequestId), Channel, Connected, @@ -40,6 +44,7 @@ impl<'de> Deserialize<'de> for IncomingMessageType { _ => (), } + #[cfg(not(feature = "12-111-0"))] if let Some(id) = value.strip_prefix("api:") { let uuid = Uuid::try_parse(id) .map_err(|e| e.to_string()) @@ -48,6 +53,9 @@ impl<'de> Deserialize<'de> for IncomingMessageType { } else { Ok(IncomingMessageType::Other(value.to_string())) } + + #[cfg(feature = "12-111-0")] + Ok(IncomingMessageType::Other(value.to_string())) } } diff --git a/misskey-websocket/src/model/outgoing.rs b/misskey-websocket/src/model/outgoing.rs index 8a18dc17..e240f587 100644 --- a/misskey-websocket/src/model/outgoing.rs +++ b/misskey-websocket/src/model/outgoing.rs @@ -1,4 +1,6 @@ -use crate::model::{ApiRequestId, ChannelId, SubNoteId}; +#[cfg(not(feature = "12-111-0"))] +use crate::model::ApiRequestId; +use crate::model::{ChannelId, SubNoteId}; use serde::Serialize; use serde_json::Value; @@ -6,6 +8,7 @@ use serde_json::Value; #[derive(Serialize, Debug, Clone)] #[serde(rename_all = "camelCase", tag = "type", content = "body")] pub enum OutgoingMessage { + #[cfg(not(feature = "12-111-0"))] Api { id: ApiRequestId, endpoint: &'static str, From 968de8ec54e159490a8c3d0faf1bfaacda254ff4 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Mon, 17 Apr 2023 01:04:05 +0900 Subject: [PATCH 30/44] Add: Add missing fields in Signin --- misskey-api/src/model/signin.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/misskey-api/src/model/signin.rs b/misskey-api/src/model/signin.rs index 36f54719..9189b0a1 100644 --- a/misskey-api/src/model/signin.rs +++ b/misskey-api/src/model/signin.rs @@ -1,4 +1,4 @@ -use std::net::IpAddr; +use std::{collections::HashMap, net::IpAddr}; use crate::model::{id::Id, user::User}; @@ -13,6 +13,8 @@ pub struct Signin { pub ip: IpAddr, pub id: Id, pub created_at: DateTime, + pub user: Option, + pub headers: HashMap, } impl_entity!(Signin); From ff3eada1cf3e82602da2331f9418400d31b02958 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Mon, 17 Apr 2023 01:05:27 +0900 Subject: [PATCH 31/44] Add: Support v12.111.0 --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 1 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/admin/show_user.rs | 61 ++++++++++++++++++- .../src/endpoint/notifications/read.rs | 45 ++++++++++++++ misskey-api/src/model/user.rs | 2 + misskey-util/Cargo.toml | 1 + misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 11 files changed, 118 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b44ed3e..f3d3aba1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.109.2' + MISSKEY_IMAGE: 'misskey/misskey:12.111.0' MISSKEY_ID: aid - - run: cargo test --features 12-109-0 + - run: cargo test --features 12-111-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 4eaab742..0085e6fe 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.111.0' + flags: --features 12-111-0 - image: 'misskey/misskey:12.109.2' flags: --features 12-109-0 - image: 'misskey/misskey:12.108.1' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 129d72e9..83abed42 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.109.2' + MISSKEY_IMAGE: 'misskey/misskey:12.111.0' MISSKEY_ID: aid - - run: cargo test --features 12-109-0 + - run: cargo test --features 12-111-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index a11f5c64..58676227 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -68,6 +68,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.108.0 ~ v12.108.1 - Support for Misskey v12.109.0 ~ v12.110.1 - endpoint `admin/meta` +- Support for Misskey v12.111.0 ~ v12.111.1 ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index f491bae5..feb4c037 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-111-0 = ["12-109-0"] 12-109-0 = ["12-108-0"] 12-108-0 = ["12-107-0"] 12-107-0 = ["12-106-0"] diff --git a/misskey-api/src/endpoint/admin/show_user.rs b/misskey-api/src/endpoint/admin/show_user.rs index 466879a3..ebf6a722 100644 --- a/misskey-api/src/endpoint/admin/show_user.rs +++ b/misskey-api/src/endpoint/admin/show_user.rs @@ -1,7 +1,16 @@ -use crate::model::{drive::DriveFile, id::Id, user::User}; +#[cfg(feature = "12-111-0")] +use std::collections::HashMap; +#[cfg(not(feature = "12-111-0"))] +use crate::model::drive::DriveFile; +use crate::model::{id::Id, user::User}; +#[cfg(feature = "12-111-0")] +use crate::model::{notification::NotificationType, signin::Signin, user::IntegrationValue}; + +#[cfg(not(feature = "12-111-0"))] use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; +#[cfg(not(feature = "12-111-0"))] use url::Url; #[derive(Serialize, Debug, Clone)] @@ -10,6 +19,8 @@ pub struct Request { pub user_id: Id, } +#[cfg(not(feature = "12-111-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "12-111-0"))))] #[derive(Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct Response { @@ -55,6 +66,42 @@ pub struct Response { pub token: Option, } +#[cfg(feature = "12-111-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-111-0")))] +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Response { + #[serde(default)] + pub email: Option, + #[serde(default)] + pub email_verified: Option, + #[serde(default)] + pub auto_accept_followed: Option, + #[serde(default)] + pub no_crawle: Option, + #[serde(default)] + pub always_mark_nsfw: Option, + #[serde(default)] + pub careful_bot: Option, + #[serde(default)] + pub inject_featured_note: Option, + #[serde(default)] + pub receive_announcement_email: Option, + #[serde(default)] + pub integrations: Option>, + #[serde(default)] + pub muted_words: Option>>, + #[serde(default)] + pub muted_instances: Option>, + #[serde(default)] + pub muting_notification_types: Option>, + pub is_moderator: bool, + pub is_silenced: bool, + pub is_suspended: bool, + #[serde(default)] + pub signins: Option>, +} + impl misskey_core::Request for Request { type Response = Response; const ENDPOINT: &'static str = "admin/show-user"; @@ -72,4 +119,16 @@ mod tests { client.admin.test(Request { user_id: user.id }).await; } + + #[tokio::test] + async fn request_moderator() { + let client = TestClient::new(); + let user_id = client.user.me().await.id; + client + .admin + .test(crate::endpoint::admin::moderators::add::Request { user_id }) + .await; + + client.user.test(Request { user_id }).await; + } } diff --git a/misskey-api/src/endpoint/notifications/read.rs b/misskey-api/src/endpoint/notifications/read.rs index 188bd44c..7ffb8104 100644 --- a/misskey-api/src/endpoint/notifications/read.rs +++ b/misskey-api/src/endpoint/notifications/read.rs @@ -13,9 +13,25 @@ impl misskey_core::Request for Request { const ENDPOINT: &'static str = "notifications/read"; } +#[cfg(feature = "12-111-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-111-0")))] +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct RequestWithNotificationIds { + pub notification_ids: Vec>, +} + +#[cfg(feature = "12-111-0")] +impl misskey_core::Request for RequestWithNotificationIds { + type Response = (); + const ENDPOINT: &'static str = "notifications/read"; +} + #[cfg(test)] mod tests { use super::Request; + #[cfg(feature = "12-111-0")] + use super::RequestWithNotificationIds; use crate::test::{ClientExt, TestClient}; #[tokio::test] @@ -46,4 +62,33 @@ mod tests { }) .await; } + + #[cfg(feature = "12-111-0")] + #[tokio::test] + async fn request_with_notification_ids() { + let client = TestClient::new(); + client + .admin + .test(crate::endpoint::notifications::create::Request { + body: "hi".to_string(), + header: None, + icon: None, + }) + .await; + + let notifications = client + .admin + .test(crate::endpoint::i::notifications::Request::default()) + .await; + + client + .admin + .test(RequestWithNotificationIds { + notification_ids: notifications + .iter() + .map(|notification| notification.id) + .collect(), + }) + .await; + } } diff --git a/misskey-api/src/model/user.rs b/misskey-api/src/model/user.rs index 14c0f60a..39d730f8 100644 --- a/misskey-api/src/model/user.rs +++ b/misskey-api/src/model/user.rs @@ -353,3 +353,5 @@ pub struct UserRelation { pub is_blocked: bool, pub is_muted: bool, } + +pub type IntegrationValue = serde_json::Value; diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 5d2ce4fa..01ff361f 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-111-0 = ["misskey-api/12-111-0", "12-109-0"] 12-109-0 = ["misskey-api/12-109-0", "12-108-0"] 12-108-0 = ["misskey-api/12-108-0", "12-107-0"] 12-107-0 = ["misskey-api/12-107-0", "12-106-0"] diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index e8079e85..dda293dd 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-111-0 = ["misskey-api/12-111-0", "misskey-util/12-111-0", "misskey-websocket?/12-111-0"] 12-109-0 = ["misskey-api/12-109-0", "misskey-util/12-109-0"] 12-108-0 = ["misskey-api/12-108-0", "misskey-util/12-108-0"] 12-107-0 = ["misskey-api/12-107-0", "misskey-util/12-107-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 6b042528..df7c11c8 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -106,6 +106,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-111-0` | v12.111.0 ~ v12.111.1 | v12.111.0 | //! | `12-109-0` | v12.109.0 ~ v12.110.1 | v12.109.2 | //! | `12-108-0` | v12.108.0 ~ v12.108.1 | v12.108.1 | //! | `12-107-0` | v12.107.0 | v12.107.0 | From c508618d6af896245f578fa537b4d1a02cc196cb Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Mon, 17 Apr 2023 08:00:15 +0900 Subject: [PATCH 32/44] Add: Partially support v12.112.0 endpoint `fetch-rss` is not supported --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 6 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/admin.rs | 16 +++ .../src/endpoint/admin/delete_account.rs | 28 ++++ .../endpoint/admin/drive_capacity_override.rs | 35 +++++ .../src/endpoint/admin/get_user_ips.rs | 35 +++++ misskey-api/src/endpoint/admin/show_user.rs | 12 +- misskey-api/src/endpoint/admin/update_meta.rs | 42 ++++++ .../src/endpoint/admin/update_user_note.rs | 35 +++++ misskey-api/src/endpoint/clips.rs | 4 + misskey-api/src/endpoint/clips/remove_note.rs | 48 +++++++ misskey-api/src/endpoint/i/update.rs | 9 ++ misskey-api/src/endpoint/users.rs | 46 +++++++ misskey-api/src/model/meta.rs | 115 ++++++++++++++++ misskey-util/Cargo.toml | 1 + misskey-util/src/builder/admin.rs | 124 ++++++++++++++++++ misskey-util/src/builder/me.rs | 5 + misskey-util/src/builder/user.rs | 10 ++ misskey-util/src/client.rs | 19 +++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 24 files changed, 598 insertions(+), 5 deletions(-) create mode 100644 misskey-api/src/endpoint/admin/delete_account.rs create mode 100644 misskey-api/src/endpoint/admin/drive_capacity_override.rs create mode 100644 misskey-api/src/endpoint/admin/get_user_ips.rs create mode 100644 misskey-api/src/endpoint/admin/update_user_note.rs create mode 100644 misskey-api/src/endpoint/clips/remove_note.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3d3aba1..c835a380 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.111.0' + MISSKEY_IMAGE: 'misskey/misskey:12.112.2' MISSKEY_ID: aid - - run: cargo test --features 12-111-0 + - run: cargo test --features 12-112-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 0085e6fe..42aee55d 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.112.2' + flags: --features 12-112-0 - image: 'misskey/misskey:12.111.0' flags: --features 12-111-0 - image: 'misskey/misskey:12.109.2' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 83abed42..763c193c 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.111.0' + MISSKEY_IMAGE: 'misskey/misskey:12.112.2' MISSKEY_ID: aid - - run: cargo test --features 12-111-0 + - run: cargo test --features 12-112-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 58676227..5f493c7d 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -69,6 +69,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.109.0 ~ v12.110.1 - endpoint `admin/meta` - Support for Misskey v12.111.0 ~ v12.111.1 +- Partial support for Misskey v12.112.0 ~ v12.112.2 + - endpoint `admin/delete-account` + - endpoint `admin/get-user-ips` + - endpoint `admin/update-user-note` + - endpoint `admin/drive-capacity-override` + - endpoint `clips/remove-note` ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index feb4c037..d0b0ea67 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-112-0 = ["12-111-0"] 12-111-0 = ["12-109-0"] 12-109-0 = ["12-108-0"] 12-108-0 = ["12-107-0"] diff --git a/misskey-api/src/endpoint/admin.rs b/misskey-api/src/endpoint/admin.rs index ee9b76fb..9c4fbc87 100644 --- a/misskey-api/src/endpoint/admin.rs +++ b/misskey-api/src/endpoint/admin.rs @@ -52,3 +52,19 @@ pub mod resync_chart; #[cfg(feature = "12-109-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-109-0")))] pub mod meta; + +#[cfg(feature = "12-112-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] +pub mod delete_account; + +#[cfg(feature = "12-112-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] +pub mod get_user_ips; + +#[cfg(feature = "12-112-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] +pub mod update_user_note; + +#[cfg(feature = "12-112-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] +pub mod drive_capacity_override; diff --git a/misskey-api/src/endpoint/admin/delete_account.rs b/misskey-api/src/endpoint/admin/delete_account.rs new file mode 100644 index 00000000..dcc50c3d --- /dev/null +++ b/misskey-api/src/endpoint/admin/delete_account.rs @@ -0,0 +1,28 @@ +use crate::model::{id::Id, user::User}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub user_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/delete-account"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let (user, _) = client.admin.create_user().await; + + client.admin.test(Request { user_id: user.id }).await; + } +} diff --git a/misskey-api/src/endpoint/admin/drive_capacity_override.rs b/misskey-api/src/endpoint/admin/drive_capacity_override.rs new file mode 100644 index 00000000..2b5e6faa --- /dev/null +++ b/misskey-api/src/endpoint/admin/drive_capacity_override.rs @@ -0,0 +1,35 @@ +use crate::model::{id::Id, user::User}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub user_id: Id, + pub override_mb: Option, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/drive-capacity-override"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let user_id = client.user.me().await.id; + + client + .admin + .test(Request { + user_id, + override_mb: Some(1000), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/admin/get_user_ips.rs b/misskey-api/src/endpoint/admin/get_user_ips.rs new file mode 100644 index 00000000..7fea1514 --- /dev/null +++ b/misskey-api/src/endpoint/admin/get_user_ips.rs @@ -0,0 +1,35 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; + +use crate::model::{id::Id, user::User}; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + user_id: Id, +} + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Ip { + pub ip: String, + pub created_at: DateTime, +} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "admin/get-user-ips"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let user_id = client.user.me().await.id; + client.admin.test(Request { user_id }).await; + } +} diff --git a/misskey-api/src/endpoint/admin/show_user.rs b/misskey-api/src/endpoint/admin/show_user.rs index ebf6a722..b90ad7de 100644 --- a/misskey-api/src/endpoint/admin/show_user.rs +++ b/misskey-api/src/endpoint/admin/show_user.rs @@ -7,7 +7,7 @@ use crate::model::{id::Id, user::User}; #[cfg(feature = "12-111-0")] use crate::model::{notification::NotificationType, signin::Signin, user::IntegrationValue}; -#[cfg(not(feature = "12-111-0"))] +#[cfg(any(not(feature = "12-111-0"), feature = "12-112-0"))] use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; #[cfg(not(feature = "12-111-0"))] @@ -81,6 +81,10 @@ pub struct Response { pub no_crawle: Option, #[serde(default)] pub always_mark_nsfw: Option, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + #[serde(default)] + pub auto_sensitive: Option, #[serde(default)] pub careful_bot: Option, #[serde(default)] @@ -98,6 +102,12 @@ pub struct Response { pub is_moderator: bool, pub is_silenced: bool, pub is_suspended: bool, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub last_active_date: Option>, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub moderation_note: Option, #[serde(default)] pub signins: Option>, } diff --git a/misskey-api/src/endpoint/admin/update_meta.rs b/misskey-api/src/endpoint/admin/update_meta.rs index d88a0c0b..5197c7e6 100644 --- a/misskey-api/src/endpoint/admin/update_meta.rs +++ b/misskey-api/src/endpoint/admin/update_meta.rs @@ -1,5 +1,7 @@ #[cfg(feature = "12-62-0")] use crate::model::clip::Clip; +#[cfg(feature = "12-112-0")] +use crate::model::meta::{SensitiveMediaDetection, SensitiveMediaDetectionSensitivity}; use crate::model::{id::Id, user::User}; use serde::Serialize; @@ -122,6 +124,26 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub recaptcha_secret_key: Option>, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub sensitive_media_detection: Option, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub sensitive_media_detection_sensitivity: Option, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub set_sensitive_flag_automatically: Option, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub enable_sensitive_media_detection_for_videos: Option, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub proxy_account_id: Option>>, @@ -264,6 +286,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub object_storage_s3_force_path_style: Option, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub enable_ip_logging: Option, } impl misskey_core::Request for Request { @@ -292,6 +319,9 @@ mod tests { #[tokio::test] async fn request_with_options() { + #[cfg(feature = "12-112-0")] + use crate::model::meta::{SensitiveMediaDetection, SensitiveMediaDetectionSensitivity}; + let client = TestClient::new(); let image_url = client.avatar_url().await; @@ -342,6 +372,16 @@ mod tests { enable_recaptcha: Some(false), recaptcha_site_key: Some(None), recaptcha_secret_key: Some(None), + #[cfg(feature = "12-112-0")] + sensitive_media_detection: Some(SensitiveMediaDetection::None), + #[cfg(feature = "12-112-0")] + sensitive_media_detection_sensitivity: Some( + SensitiveMediaDetectionSensitivity::Medium, + ), + #[cfg(feature = "12-112-0")] + set_sensitive_flag_automatically: Some(false), + #[cfg(feature = "12-112-0")] + enable_sensitive_media_detection_for_videos: Some(false), proxy_account_id: Some(None), maintainer_name: Some(Some("coord_e".to_string())), maintainer_email: Some(Some("me@coord-e.com".to_string())), @@ -390,6 +430,8 @@ mod tests { object_storage_set_public_read: Some(false), #[cfg(feature = "12-69-0")] object_storage_s3_force_path_style: Some(false), + #[cfg(feature = "12-112-0")] + enable_ip_logging: Some(false), }) .await; } diff --git a/misskey-api/src/endpoint/admin/update_user_note.rs b/misskey-api/src/endpoint/admin/update_user_note.rs new file mode 100644 index 00000000..28a3f809 --- /dev/null +++ b/misskey-api/src/endpoint/admin/update_user_note.rs @@ -0,0 +1,35 @@ +use crate::model::{id::Id, user::User}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub user_id: Id, + pub text: String, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/update-user-note"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let user_id = client.user.me().await.id; + + client + .admin + .test(Request { + user_id, + text: "comment".to_string(), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/clips.rs b/misskey-api/src/endpoint/clips.rs index 3ed8b49a..cd48a518 100644 --- a/misskey-api/src/endpoint/clips.rs +++ b/misskey-api/src/endpoint/clips.rs @@ -8,3 +8,7 @@ pub mod update; #[cfg(feature = "12-57-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-57-0")))] pub mod add_note; + +#[cfg(feature = "12-112-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] +pub mod remove_note; diff --git a/misskey-api/src/endpoint/clips/remove_note.rs b/misskey-api/src/endpoint/clips/remove_note.rs new file mode 100644 index 00000000..906f7be6 --- /dev/null +++ b/misskey-api/src/endpoint/clips/remove_note.rs @@ -0,0 +1,48 @@ +use crate::model::{clip::Clip, id::Id, note::Note}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub clip_id: Id, + pub note_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "clips/remove-note"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let note = client.create_note(Some("test"), None, None).await; + let clip = client + .test( + crate::endpoint::clips::create::Request::builder() + .name("testclip".to_string()) + .build(), + ) + .await; + client + .user + .test(crate::endpoint::clips::add_note::Request { + clip_id: clip.id, + note_id: note.id, + }) + .await; + + client + .test(Request { + clip_id: clip.id, + note_id: note.id, + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/i/update.rs b/misskey-api/src/endpoint/i/update.rs index 3358d09d..083771d8 100644 --- a/misskey-api/src/endpoint/i/update.rs +++ b/misskey-api/src/endpoint/i/update.rs @@ -98,6 +98,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub always_mark_nsfw: Option, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub auto_sensitive: Option, #[cfg(feature = "12-96-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-96-0")))] #[serde(skip_serializing_if = "Option::is_none")] @@ -218,6 +223,8 @@ mod tests { auto_watch: Some(true), inject_featured_note: Some(true), always_mark_nsfw: Some(true), + #[cfg(feature = "12-112-0")] + auto_sensitive: Some(true), #[cfg(feature = "12-96-0")] ff_visibility: Some(FfVisibility::Public), pinned_page_id: None, @@ -280,6 +287,8 @@ mod tests { auto_watch: None, inject_featured_note: None, always_mark_nsfw: None, + #[cfg(feature = "12-112-0")] + auto_sensitive: None, #[cfg(feature = "12-96-0")] ff_visibility: None, #[cfg(not(feature = "12-108-0"))] diff --git a/misskey-api/src/endpoint/users.rs b/misskey-api/src/endpoint/users.rs index 8aaccf3e..0dc55b7c 100644 --- a/misskey-api/src/endpoint/users.rs +++ b/misskey-api/src/endpoint/users.rs @@ -105,6 +105,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub origin: Option, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub hostname: Option, } #[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] @@ -138,6 +143,8 @@ mod tests { sort: None, state: None, origin: None, + #[cfg(feature = "12-112-0")] + hostname: None, }) .await; } @@ -152,6 +159,8 @@ mod tests { sort: None, state: None, origin: None, + #[cfg(feature = "12-112-0")] + hostname: None, }) .await; } @@ -169,6 +178,8 @@ mod tests { sort: Some(SortOrder::Ascending(UserSortKey::Follower)), state: None, origin: None, + #[cfg(feature = "12-112-0")] + hostname: None, }) .await; client @@ -178,6 +189,8 @@ mod tests { sort: Some(SortOrder::Ascending(UserSortKey::CreatedAt)), state: None, origin: None, + #[cfg(feature = "12-112-0")] + hostname: None, }) .await; client @@ -187,6 +200,8 @@ mod tests { sort: Some(SortOrder::Descending(UserSortKey::UpdatedAt)), state: None, origin: None, + #[cfg(feature = "12-112-0")] + hostname: None, }) .await; } @@ -202,6 +217,8 @@ mod tests { sort: None, state: Some(UserState::All), origin: None, + #[cfg(feature = "12-112-0")] + hostname: None, }) .await; client @@ -211,6 +228,8 @@ mod tests { sort: None, state: Some(UserState::Admin), origin: None, + #[cfg(feature = "12-112-0")] + hostname: None, }) .await; client @@ -220,6 +239,8 @@ mod tests { sort: None, state: Some(UserState::Alive), origin: None, + #[cfg(feature = "12-112-0")] + hostname: None, }) .await; client @@ -229,6 +250,8 @@ mod tests { sort: None, state: Some(UserState::Moderator), origin: None, + #[cfg(feature = "12-112-0")] + hostname: None, }) .await; // TODO: Uncomment with cfg when `adminOrModerator` value is fixed in Misskey @@ -256,6 +279,8 @@ mod tests { sort: None, state: None, origin: Some(UserOrigin::Local), + #[cfg(feature = "12-112-0")] + hostname: None, }) .await; client @@ -265,6 +290,8 @@ mod tests { sort: None, state: None, origin: Some(UserOrigin::Remote), + #[cfg(feature = "12-112-0")] + hostname: None, }) .await; client @@ -274,6 +301,25 @@ mod tests { sort: None, state: None, origin: Some(UserOrigin::Combined), + #[cfg(feature = "12-112-0")] + hostname: None, + }) + .await; + } + + #[cfg(feature = "12-112-0")] + #[tokio::test] + async fn request_with_hostname() { + let client = TestClient::new(); + + client + .test(Request { + limit: None, + offset: None, + sort: None, + state: None, + origin: None, + hostname: Some("host".to_string()), }) .await; } diff --git a/misskey-api/src/model/meta.rs b/misskey-api/src/model/meta.rs index ff309f89..2eb7749f 100644 --- a/misskey-api/src/model/meta.rs +++ b/misskey-api/src/model/meta.rs @@ -1,3 +1,6 @@ +#[cfg(feature = "12-112-0")] +use std::fmt::{self, Display}; + #[cfg(feature = "12-81-0")] use crate::model::ad::{Ad, Place}; #[cfg(feature = "12-62-0")] @@ -5,6 +8,8 @@ use crate::model::clip::Clip; use crate::model::{emoji::Emoji, id::Id, user::User}; use serde::{Deserialize, Serialize}; +#[cfg(feature = "12-112-0")] +use thiserror::Error; use url::Url; #[derive(Deserialize, Serialize, Debug, Clone)] @@ -230,6 +235,18 @@ pub struct AdminMeta { pub blocked_hosts: Vec, pub hcaptcha_secret_key: Option, pub recaptcha_secret_key: Option, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub sensitive_media_detection: Option, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub sensitive_media_detection_sensitivity: Option, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub set_sensitive_flag_automatically: Option, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub enable_sensitive_media_detection_for_videos: Option, pub proxy_account_id: Option>, pub twitter_consumer_key: Option, pub twitter_consumer_secret: Option, @@ -261,6 +278,9 @@ pub struct AdminMeta { pub object_storage_s3_force_path_style: bool, pub deepl_auth_key: Option, pub deepl_is_pro: bool, + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub enable_ip_logging: bool, } #[derive(Deserialize, Serialize, Debug, Clone)] @@ -286,3 +306,98 @@ pub struct FeaturesMeta { #[cfg_attr(docsrs, doc(cfg(feature = "12-28-0")))] pub miauth: bool, } + +#[cfg(feature = "12-112-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] +#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, Copy)] +#[serde(rename_all = "camelCase")] +pub enum SensitiveMediaDetection { + None, + All, + Local, + Remote, +} + +#[cfg(feature = "12-112-0")] +impl Display for SensitiveMediaDetection { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + SensitiveMediaDetection::None => f.write_str("none"), + SensitiveMediaDetection::All => f.write_str("all"), + SensitiveMediaDetection::Local => f.write_str("local"), + SensitiveMediaDetection::Remote => f.write_str("remote"), + } + } +} + +#[cfg(feature = "12-112-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] +#[derive(Debug, Error, Clone)] +#[error("invalid sensitive media detection")] +pub struct ParseSensitiveMediaDetectionError { + _priv: (), +} + +#[cfg(feature = "12-112-0")] +impl std::str::FromStr for SensitiveMediaDetection { + type Err = ParseSensitiveMediaDetectionError; + + fn from_str(s: &str) -> Result { + match s { + "none" | "None" => Ok(SensitiveMediaDetection::None), + "all" | "All" => Ok(SensitiveMediaDetection::All), + "local" | "Local" => Ok(SensitiveMediaDetection::Local), + "remote" | "Remote" => Ok(SensitiveMediaDetection::Remote), + _ => Err(ParseSensitiveMediaDetectionError { _priv: () }), + } + } +} + +#[cfg(feature = "12-112-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] +#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, Copy)] +#[serde(rename_all = "camelCase")] +pub enum SensitiveMediaDetectionSensitivity { + Medium, + Low, + High, + VeryLow, + VeryHigh, +} + +#[cfg(feature = "12-112-0")] +impl Display for SensitiveMediaDetectionSensitivity { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + SensitiveMediaDetectionSensitivity::Medium => f.write_str("medium"), + SensitiveMediaDetectionSensitivity::Low => f.write_str("low"), + SensitiveMediaDetectionSensitivity::High => f.write_str("high"), + SensitiveMediaDetectionSensitivity::VeryLow => f.write_str("veryLow"), + SensitiveMediaDetectionSensitivity::VeryHigh => f.write_str("veryHigh"), + } + } +} + +#[cfg(feature = "12-112-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] +#[derive(Debug, Error, Clone)] +#[error("invalid sensitive media detection")] +pub struct ParseSensitiveMediaDetectionSensitivityError { + _priv: (), +} + +#[cfg(feature = "12-112-0")] +impl std::str::FromStr for SensitiveMediaDetectionSensitivity { + type Err = ParseSensitiveMediaDetectionSensitivityError; + + fn from_str(s: &str) -> Result { + match s { + "medium" | "Medium" => Ok(SensitiveMediaDetectionSensitivity::Medium), + "low" | "Low" => Ok(SensitiveMediaDetectionSensitivity::Low), + "high" | "High" => Ok(SensitiveMediaDetectionSensitivity::High), + "veryLow" | "VeryLow" => Ok(SensitiveMediaDetectionSensitivity::VeryLow), + "veryHigh" | "VeryHigh" => Ok(SensitiveMediaDetectionSensitivity::VeryHigh), + _ => Err(ParseSensitiveMediaDetectionSensitivityError { _priv: () }), + } + } +} diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index 01ff361f..fdff1be2 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-112-0 = ["misskey-api/12-112-0", "12-111-0"] 12-111-0 = ["misskey-api/12-111-0", "12-109-0"] 12-109-0 = ["misskey-api/12-109-0", "12-108-0"] 12-108-0 = ["misskey-api/12-108-0", "12-107-0"] diff --git a/misskey-util/src/builder/admin.rs b/misskey-util/src/builder/admin.rs index 9293a8ca..60002c52 100644 --- a/misskey-util/src/builder/admin.rs +++ b/misskey-util/src/builder/admin.rs @@ -10,6 +10,8 @@ use misskey_api::model::clip::Clip; use misskey_api::model::emoji::Emoji; #[cfg(not(feature = "12-93-0"))] use misskey_api::model::log::{Log, LogLevel}; +#[cfg(feature = "12-112-0")] +use misskey_api::model::meta::{SensitiveMediaDetection, SensitiveMediaDetectionSensitivity}; use misskey_api::model::{announcement::Announcement, user::User}; use misskey_api::{endpoint, EntityRef}; use misskey_core::Client; @@ -264,6 +266,124 @@ impl MetaUpdateBuilder { pub recaptcha_secret_key; } + /// Sets sensitive media detection target. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub fn detect_sensitive_media(&mut self, detection: SensitiveMediaDetection) -> &mut Self { + self.request.sensitive_media_detection.replace(detection); + self + } + + /// Sets sensitive media detection target to none. + /// + /// This is equivalent to `.detect_sensitive_media(SensitiveMediaDetection::None)`. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub fn disable_sensitive_media_detection(&mut self) -> &mut Self { + self.detect_sensitive_media(SensitiveMediaDetection::None) + } + + /// Sets sensitive media detection target to all. + /// + /// This is equivalent to `.detect_sensitive_media(SensitiveMediaDetection::All)`. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub fn detect_sensitive_media_for_all_posts(&mut self) -> &mut Self { + self.detect_sensitive_media(SensitiveMediaDetection::All) + } + + /// Sets sensitive media detection target to local. + /// + /// This is equivalent to `.detect_sensitive_media(SensitiveMediaDetection::Local)`. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub fn detect_sensitive_media_for_local_posts(&mut self) -> &mut Self { + self.detect_sensitive_media(SensitiveMediaDetection::Local) + } + + /// Sets sensitive media detection target to remote. + /// + /// This is equivalent to `.detect_sensitive_media(SensitiveMediaDetection::Remote)`. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub fn detect_sensitive_media_for_remote_posts(&mut self) -> &mut Self { + self.detect_sensitive_media(SensitiveMediaDetection::Remote) + } + + /// Sets sensitivity of sensitive media detection. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub fn sensitive_media_detection_sensitivity( + &mut self, + sensitivity: SensitiveMediaDetectionSensitivity, + ) -> &mut Self { + self.request + .sensitive_media_detection_sensitivity + .replace(sensitivity); + self + } + + /// Sets sensitivity of sensitive media detection to medium. + /// + /// This is equivalent to + /// `.sensitive_media_detection_sensitivity(SensitiveMediaDetectionSensitivity::Medium)`. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub fn sensitive_media_detection_medium_sensitivity(&mut self) -> &mut Self { + self.sensitive_media_detection_sensitivity(SensitiveMediaDetectionSensitivity::Medium) + } + + /// Sets sensitivity of sensitive media detection to low. + /// + /// This is equivalent to + /// `.sensitive_media_detection_sensitivity(SensitiveMediaDetectionSensitivity::Low)`. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub fn sensitive_media_detection_low_sensitivity(&mut self) -> &mut Self { + self.sensitive_media_detection_sensitivity(SensitiveMediaDetectionSensitivity::Low) + } + + /// Sets sensitivity of sensitive media detection to high. + /// + /// This is equivalent to + /// `.sensitive_media_detection_sensitivity(SensitiveMediaDetectionSensitivity::High)`. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub fn sensitive_media_detection_high_sensitivity(&mut self) -> &mut Self { + self.sensitive_media_detection_sensitivity(SensitiveMediaDetectionSensitivity::High) + } + + /// Sets sensitivity of sensitive media detection to very low. + /// + /// This is equivalent to + /// `.sensitive_media_detection_sensitivity(SensitiveMediaDetectionSensitivity::VeryLow)`. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub fn sensitive_media_detection_very_low_sensitivity(&mut self) -> &mut Self { + self.sensitive_media_detection_sensitivity(SensitiveMediaDetectionSensitivity::VeryLow) + } + + /// Sets sensitivity of sensitive media detection to very high. + /// + /// This is equivalent to + /// `.sensitive_media_detection_sensitivity(SensitiveMediaDetectionSensitivity::VeryHigh)`. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub fn sensitive_media_detection_very_high_sensitivity(&mut self) -> &mut Self { + self.sensitive_media_detection_sensitivity(SensitiveMediaDetectionSensitivity::VeryHigh) + } + + update_builder_bool_field! { + /// Sets whether to set sensitive flag automatically on detected media. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub set_sensitive_flag_automatically; + /// Sets whether to enable sensitive media detection for videos. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub enable_sensitive_media_detection_for_videos; + } + update_builder_option_field! { #[doc_name = "proxy account for the instance"] pub proxy_account: impl EntityRef { proxy_account_id = proxy_account.entity_ref() }; @@ -398,6 +518,10 @@ impl MetaUpdateBuilder { #[cfg(feature = "12-69-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-69-0")))] pub object_storage_s3_force_path_style; + /// Sets whether or not to log ip address of the users. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub enable_ip_logging; } update_builder_option_field! { #[doc_name = "base URL of the extenal object storage"] diff --git a/misskey-util/src/builder/me.rs b/misskey-util/src/builder/me.rs index f17ea6b2..fff10e8e 100644 --- a/misskey-util/src/builder/me.rs +++ b/misskey-util/src/builder/me.rs @@ -261,6 +261,11 @@ impl MeUpdateBuilder { /// Sets whether to mark uploaded media as NSFW by default. pub always_mark_nsfw; + /// Sets whether to mark uploaded media as NSFW according to automatic detection. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub auto_sensitive; + /// Sets whether to receive notifications about other users' notes that this user has /// reacted to or replied to. #[cfg(any(docsrs, not(feature = "12-55-0")))] diff --git a/misskey-util/src/builder/user.rs b/misskey-util/src/builder/user.rs index 772d6c30..1f8c95a8 100644 --- a/misskey-util/src/builder/user.rs +++ b/misskey-util/src/builder/user.rs @@ -108,6 +108,16 @@ impl UserListBuilder { .replace(endpoint::users::UserState::AdminOrModerator); self } + + /// Limits the host from which users are listed. + /// + /// To list users in the local host, use [`local`][`UserListBuilder::local`] method instead. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + pub fn hostname(&mut self, hostname: impl Into) -> &mut Self { + self.request.hostname.replace(hostname.into()); + self + } } impl UserListBuilder { diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index 963400ee..94e28f40 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -2397,6 +2397,25 @@ pub trait ClientExt: Client + Sync { }) } + /// Removes the specified note from the clip. + #[cfg(feature = "12-112-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + fn unclip_note( + &self, + clip: impl EntityRef, + note: impl EntityRef, + ) -> BoxFuture>> { + let clip_id = clip.entity_ref(); + let note_id = note.entity_ref(); + Box::pin(async move { + self.request(endpoint::clips::remove_note::Request { clip_id, note_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + /// Lists the notes that are clipped to the specified clip. fn clip_notes(&self, clip: impl EntityRef) -> PagerStream> { let pager = BackwardPager::new( diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index dda293dd..23f743ec 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-112-0 = ["misskey-api/12-112-0", "misskey-util/12-112-0", "12-111-0"] 12-111-0 = ["misskey-api/12-111-0", "misskey-util/12-111-0", "misskey-websocket?/12-111-0"] 12-109-0 = ["misskey-api/12-109-0", "misskey-util/12-109-0"] 12-108-0 = ["misskey-api/12-108-0", "misskey-util/12-108-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index df7c11c8..53e80542 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -106,6 +106,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-112-0` | v12.112.0 ~ v12.112.2 | v12.112.2 | //! | `12-111-0` | v12.111.0 ~ v12.111.1 | v12.111.0 | //! | `12-109-0` | v12.109.0 ~ v12.110.1 | v12.109.2 | //! | `12-108-0` | v12.108.0 ~ v12.108.1 | v12.108.1 | From b76002ef6191c99ab148af17a6af192c9766a1f8 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Mon, 17 Apr 2023 23:53:51 +0900 Subject: [PATCH 33/44] Add: Support v12.112.3 --- .github/workflows/ci.yml | 4 ++-- .github/workflows/flaky.yml | 2 ++ .github/workflows/unstable.yml | 4 ++-- misskey-api/CHANGELOG.md | 1 + misskey-api/Cargo.toml | 1 + misskey-api/src/endpoint/admin/update_meta.rs | 7 +++++++ misskey-api/src/model/meta.rs | 3 +++ misskey-util/Cargo.toml | 1 + misskey-util/src/builder/admin.rs | 4 ++++ misskey/Cargo.toml | 1 + misskey/src/lib.rs | 1 + 11 files changed, 25 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c835a380..6b18c3b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.112.2' + MISSKEY_IMAGE: 'misskey/misskey:12.112.3' MISSKEY_ID: aid - - run: cargo test --features 12-112-0 + - run: cargo test --features 12-112-3 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 42aee55d..74953f98 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:12.112.3' + flags: --features 12-112-3 - image: 'misskey/misskey:12.112.2' flags: --features 12-112-0 - image: 'misskey/misskey:12.111.0' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index 763c193c..cf9b6aa4 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.112.2' + MISSKEY_IMAGE: 'misskey/misskey:12.112.3' MISSKEY_ID: aid - - run: cargo test --features 12-112-0 + - run: cargo test --features 12-112-3 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 5f493c7d..74905710 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -75,6 +75,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint `admin/update-user-note` - endpoint `admin/drive-capacity-override` - endpoint `clips/remove-note` +- Support for Misskey v12.112.3 ~ v12.119.2 ### Changed ### Deprecated diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index d0b0ea67..b74c6d31 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +12-112-3 = ["12-112-0"] 12-112-0 = ["12-111-0"] 12-111-0 = ["12-109-0"] 12-109-0 = ["12-108-0"] diff --git a/misskey-api/src/endpoint/admin/update_meta.rs b/misskey-api/src/endpoint/admin/update_meta.rs index 5197c7e6..a65ae9a0 100644 --- a/misskey-api/src/endpoint/admin/update_meta.rs +++ b/misskey-api/src/endpoint/admin/update_meta.rs @@ -291,6 +291,11 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub enable_ip_logging: Option, + #[cfg(feature = "12-112-3")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-3")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub enable_active_email_validation: Option, } impl misskey_core::Request for Request { @@ -432,6 +437,8 @@ mod tests { object_storage_s3_force_path_style: Some(false), #[cfg(feature = "12-112-0")] enable_ip_logging: Some(false), + #[cfg(feature = "12-112-3")] + enable_active_email_validation: Some(false), }) .await; } diff --git a/misskey-api/src/model/meta.rs b/misskey-api/src/model/meta.rs index 2eb7749f..a0360fcb 100644 --- a/misskey-api/src/model/meta.rs +++ b/misskey-api/src/model/meta.rs @@ -281,6 +281,9 @@ pub struct AdminMeta { #[cfg(feature = "12-112-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] pub enable_ip_logging: bool, + #[cfg(feature = "12-112-3")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-3")))] + pub enable_active_email_validation: bool, } #[derive(Deserialize, Serialize, Debug, Clone)] diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index fdff1be2..a9905c04 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +12-112-3 = ["misskey-api/12-112-3", "12-112-0"] 12-112-0 = ["misskey-api/12-112-0", "12-111-0"] 12-111-0 = ["misskey-api/12-111-0", "12-109-0"] 12-109-0 = ["misskey-api/12-109-0", "12-108-0"] diff --git a/misskey-util/src/builder/admin.rs b/misskey-util/src/builder/admin.rs index 60002c52..1c5c16c1 100644 --- a/misskey-util/src/builder/admin.rs +++ b/misskey-util/src/builder/admin.rs @@ -522,6 +522,10 @@ impl MetaUpdateBuilder { #[cfg(feature = "12-112-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] pub enable_ip_logging; + /// Sets whether or not to validate email address strictly. + #[cfg(feature = "12-112-3")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-112-3")))] + pub enable_active_email_validation; } update_builder_option_field! { #[doc_name = "base URL of the extenal object storage"] diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 23f743ec..335a524b 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +12-112-3 = ["misskey-api/12-112-3", "misskey-util/12-112-3", "12-112-0"] 12-112-0 = ["misskey-api/12-112-0", "misskey-util/12-112-0", "12-111-0"] 12-111-0 = ["misskey-api/12-111-0", "misskey-util/12-111-0", "misskey-websocket?/12-111-0"] 12-109-0 = ["misskey-api/12-109-0", "misskey-util/12-109-0"] diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index 53e80542..bc31fb59 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -106,6 +106,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `12-112-3` | v12.112.3 ~ v12.119.2 | v12.112.3 | //! | `12-112-0` | v12.112.0 ~ v12.112.2 | v12.112.2 | //! | `12-111-0` | v12.111.0 ~ v12.111.1 | v12.111.0 | //! | `12-109-0` | v12.109.0 ~ v12.110.1 | v12.109.2 | From 24a6f685905678b4512a0a756218982832a60247 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 3 May 2023 08:17:57 +0900 Subject: [PATCH 34/44] Add: Add missing fields for Meta --- misskey-api/src/model/meta.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/misskey-api/src/model/meta.rs b/misskey-api/src/model/meta.rs index a0360fcb..11a3e765 100644 --- a/misskey-api/src/model/meta.rs +++ b/misskey-api/src/model/meta.rs @@ -72,6 +72,12 @@ pub struct Meta { pub bannar_url: Option, pub error_image_url: Option, pub icon_url: Option, + #[cfg(feature = "12-60-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-60-0")))] + pub background_image_url: Option, + #[cfg(feature = "12-60-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-60-0")))] + pub logo_image_url: Option, pub max_note_text_length: u64, #[serde(default)] pub emojis: Vec, From 4f9238f4814c893d5ab86007743bcbada22fd5d2 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Fri, 5 May 2023 04:52:59 +0900 Subject: [PATCH 35/44] Fix: Fix typo --- misskey-api/src/endpoint/admin/update_meta.rs | 4 ++-- misskey-api/src/model/meta.rs | 2 +- misskey-util/src/builder/admin.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/misskey-api/src/endpoint/admin/update_meta.rs b/misskey-api/src/endpoint/admin/update_meta.rs index a65ae9a0..efbecf5e 100644 --- a/misskey-api/src/endpoint/admin/update_meta.rs +++ b/misskey-api/src/endpoint/admin/update_meta.rs @@ -46,7 +46,7 @@ pub struct Request { pub mascot_image_url: Option>, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] - pub bannar_url: Option>, + pub banner_url: Option>, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub icon_url: Option>, @@ -347,7 +347,7 @@ mod tests { #[cfg(feature = "12-105-0")] theme_color: Some(Some("#31748f".to_string())), mascot_image_url: Some(Some(image_url.to_string())), - bannar_url: Some(Some(image_url.to_string())), + banner_url: Some(Some(image_url.to_string())), icon_url: Some(Some(image_url.to_string())), #[cfg(feature = "12-60-0")] background_image_url: Some(Some(image_url.to_string())), diff --git a/misskey-api/src/model/meta.rs b/misskey-api/src/model/meta.rs index 11a3e765..a441df77 100644 --- a/misskey-api/src/model/meta.rs +++ b/misskey-api/src/model/meta.rs @@ -69,7 +69,7 @@ pub struct Meta { #[cfg_attr(docsrs, doc(cfg(feature = "12-105-0")))] pub theme_color: Option, pub mascot_image_url: Option, - pub bannar_url: Option, + pub banner_url: Option, pub error_image_url: Option, pub icon_url: Option, #[cfg(feature = "12-60-0")] diff --git a/misskey-util/src/builder/admin.rs b/misskey-util/src/builder/admin.rs index 1c5c16c1..23806ffe 100644 --- a/misskey-util/src/builder/admin.rs +++ b/misskey-util/src/builder/admin.rs @@ -183,7 +183,7 @@ impl MetaUpdateBuilder { #[doc_name = "URL of the mascot image for the instance"] pub mascot_image_url; #[doc_name = "URL of the banner image for the instance"] - pub bannar_url; + pub banner_url; #[doc_name = "URL of the error image for the instance"] pub error_image_url; #[doc_name = "URL of the icon for the instance"] From 735b15075ddd14d38f0985bb1f0110a9b01380c0 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Sun, 7 May 2023 03:36:16 +0900 Subject: [PATCH 36/44] Fix: Rename field banner_id to banner_url for Channel model --- misskey-api/src/model/channel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misskey-api/src/model/channel.rs b/misskey-api/src/model/channel.rs index 00e5fcff..5c6a08c4 100644 --- a/misskey-api/src/model/channel.rs +++ b/misskey-api/src/model/channel.rs @@ -12,7 +12,7 @@ pub struct Channel { pub last_noted_at: Option>, pub name: String, pub description: Option, - pub banner_id: Option, + pub banner_url: Option, pub notes_count: u64, pub users_count: u64, pub user_id: Id, From 06d545264b28fbaefda151254e759452e3aa7ab8 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 3 May 2023 04:44:40 +0900 Subject: [PATCH 37/44] CI: Bump postgres to 15 --- ci/testenv/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/testenv/docker-compose.yml b/ci/testenv/docker-compose.yml index 7cba4146..06462a58 100644 --- a/ci/testenv/docker-compose.yml +++ b/ci/testenv/docker-compose.yml @@ -24,7 +24,7 @@ services: db: restart: always - image: postgres:11.2-alpine + image: postgres:15-alpine environment: - POSTGRES_PASSWORD=misskey-test - POSTGRES_USER=misskey-test From 8def72a5535437b479c588664492db4755cd932b Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 3 May 2023 04:46:01 +0900 Subject: [PATCH 38/44] CI: Set NODE_ENV to development --- ci/testenv/web/Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci/testenv/web/Dockerfile b/ci/testenv/web/Dockerfile index 332ec578..71e9b0bf 100644 --- a/ci/testenv/web/Dockerfile +++ b/ci/testenv/web/Dockerfile @@ -2,4 +2,7 @@ ARG MISSKEY_IMAGE FROM ${MISSKEY_IMAGE} ARG MISSKEY_ID COPY default.yml /misskey/.config/default.yml +USER root RUN echo "id: '${MISSKEY_ID}'" >> /misskey/.config/default.yml +# Disable rate limit +ENV NODE_ENV=development From 064f8807005c36f712f06d2f49cbdd198da77071 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 3 May 2023 04:47:25 +0900 Subject: [PATCH 39/44] CI: Update scripts to be compatible with Misskey v13.0.0 --- ci/testenv/get-token/get-token.sh | 48 ++++++++++++++++++++++++++++++- ci/testenv/setup.sh | 2 +- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/ci/testenv/get-token/get-token.sh b/ci/testenv/get-token/get-token.sh index 3275e05b..c4589c80 100755 --- a/ci/testenv/get-token/get-token.sh +++ b/ci/testenv/get-token/get-token.sh @@ -19,9 +19,55 @@ USER_DATA=$( USER_TOKEN=$(echo "$USER_DATA" | jq -r .token) USER_ID=$(echo "$USER_DATA" | jq -r .id) +# endpoint `admin/moderators/add` is removed in Misskey v13.0.0 curl -fsS -XPOST -H 'Content-Type: application/json' \ --data '{"i":"'"${ADMIN_TOKEN}"'","userId":"'"${USER_ID}"'"}' \ - http://web:3000/api/admin/moderators/add || exit 1 + http://web:3000/api/admin/moderators/add || +( + # create and assign moderator role + ROLE_ID=$( + curl -fsS -XPOST -H 'Content-Type: application/json' \ + --data '{ + "i": "'"${ADMIN_TOKEN}"'", + "name": "Moderator", + "description": "", + "color": "", + "target": "manual", + "condFormula": {}, + "isPublic": false, + "isModerator": true, + "isAdministrator": false, + "canEditMembersByModerator": false, + "policies": { + "pinLimit": { + "value": 1000, + "priority": 0, + "useDefault": false + }, + "clipLimit": { + "value": 1000, + "priority": 0, + "useDefault": false + }, + "antennaLimit": { + "value": 1000, + "priority": 0, + "useDefault": false + }, + "userListLimit": { + "value": 1000, + "priority": 0, + "useDefault": false + } + } + }' \ + http://web:3000/api/admin/roles/create | jq -r .id \ + ) && + curl -fsS -XPOST -H 'Content-Type: application/json' \ + --data '{"i":"'"${ADMIN_TOKEN}"'", "roleId": "'"${ROLE_ID}"'", "userId":"'"${USER_ID}"'"}' \ + http://web:3000/api/admin/roles/assign +) || +exit 1 echo "::set-output name=admin_token::$ADMIN_TOKEN" echo "::set-output name=user_token::$USER_TOKEN" diff --git a/ci/testenv/setup.sh b/ci/testenv/setup.sh index 823888a6..d4aac60f 100755 --- a/ci/testenv/setup.sh +++ b/ci/testenv/setup.sh @@ -10,7 +10,7 @@ readonly MAX_RETRY=5 count=0 while :; do docker-compose build - docker-compose run --rm web yarn run init + docker-compose run --rm web yarn run init || docker-compose run --rm web pnpm run init docker-compose up -d web if docker-compose run --rm get-token; then break From ffaeb2ec589b8e3a15df9cd4b5b5d4e5becbdb77 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 3 May 2023 05:12:15 +0900 Subject: [PATCH 40/44] CI: Assign moderator role to the root user From Misskey v13.0.0, NewAbuseUserReport will not be published to the root user by default. See: https://github.com/misskey-dev/misskey/blob/13.0.0/packages/backend/src/core/RoleService.ts#L261 --- ci/testenv/get-token/get-token.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ci/testenv/get-token/get-token.sh b/ci/testenv/get-token/get-token.sh index c4589c80..2efd25b0 100755 --- a/ci/testenv/get-token/get-token.sh +++ b/ci/testenv/get-token/get-token.sh @@ -4,12 +4,15 @@ until nc -z web 3000; do sleep 1 done -ADMIN_TOKEN=$( +ADMIN_DATA=$( curl -fsS -XPOST -H 'Content-Type: application/json' \ --data '{"username":"admin","password":"admin"}' \ - http://web:3000/api/admin/accounts/create | jq -r .token + http://web:3000/api/admin/accounts/create ) +ADMIN_TOKEN=$(echo "$ADMIN_DATA" | jq -r .token) +ADMIN_ID=$(echo "$ADMIN_DATA" | jq -r .id) + USER_DATA=$( curl -fsS -XPOST -H 'Content-Type: application/json' \ --data '{"username":"testuser","password":"testuser"}' \ @@ -63,6 +66,9 @@ curl -fsS -XPOST -H 'Content-Type: application/json' \ }' \ http://web:3000/api/admin/roles/create | jq -r .id \ ) && + curl -fsS -XPOST -H 'Content-Type: application/json' \ + --data '{"i":"'"${ADMIN_TOKEN}"'", "roleId": "'"${ROLE_ID}"'", "userId":"'"${ADMIN_ID}"'"}' \ + http://web:3000/api/admin/roles/assign && curl -fsS -XPOST -H 'Content-Type: application/json' \ --data '{"i":"'"${ADMIN_TOKEN}"'", "roleId": "'"${ROLE_ID}"'", "userId":"'"${USER_ID}"'"}' \ http://web:3000/api/admin/roles/assign From c75736a935dc825e019245a9365dad07b9f07926 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 3 May 2023 05:42:33 +0900 Subject: [PATCH 41/44] Add: Update Cargo.toml for v13.0.0 --- misskey-api/Cargo.toml | 1 + misskey-util/Cargo.toml | 1 + misskey/Cargo.toml | 1 + 3 files changed, 3 insertions(+) diff --git a/misskey-api/Cargo.toml b/misskey-api/Cargo.toml index b74c6d31..5d14e4c7 100644 --- a/misskey-api/Cargo.toml +++ b/misskey-api/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings"] [features] default = ["aid"] +13-0-0 = ["12-112-3"] 12-112-3 = ["12-112-0"] 12-112-0 = ["12-111-0"] 12-111-0 = ["12-109-0"] diff --git a/misskey-util/Cargo.toml b/misskey-util/Cargo.toml index a9905c04..b349c5a3 100644 --- a/misskey-util/Cargo.toml +++ b/misskey-util/Cargo.toml @@ -14,6 +14,7 @@ keywords = ["async", "client", "misskey"] [features] default = ["aid"] +13-0-0 = ["misskey-api/13-0-0", "12-112-3"] 12-112-3 = ["misskey-api/12-112-3", "12-112-0"] 12-112-0 = ["misskey-api/12-112-0", "12-111-0"] 12-111-0 = ["misskey-api/12-111-0", "12-109-0"] diff --git a/misskey/Cargo.toml b/misskey/Cargo.toml index 335a524b..8aff4bb9 100644 --- a/misskey/Cargo.toml +++ b/misskey/Cargo.toml @@ -15,6 +15,7 @@ categories = ["api-bindings", "web-programming::http-client", "web-programming:: [features] default = ["http-client", "websocket-client", "tokio-runtime", "aid"] +13-0-0 = ["misskey-api/13-0-0", "misskey-util/13-0-0", "12-112-3"] 12-112-3 = ["misskey-api/12-112-3", "misskey-util/12-112-3", "12-112-0"] 12-112-0 = ["misskey-api/12-112-0", "misskey-util/12-112-0", "12-111-0"] 12-111-0 = ["misskey-api/12-111-0", "misskey-util/12-111-0", "misskey-websocket?/12-111-0"] From ae13fc32a0440952a30ee6b9e70280d0f25e247f Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 3 May 2023 06:34:32 +0900 Subject: [PATCH 42/44] Add: Add roles related APIs --- misskey-api/CHANGELOG.md | 4 + misskey-api/src/endpoint/admin.rs | 28 +- misskey-api/src/endpoint/admin/roles.rs | 8 + .../src/endpoint/admin/roles/assign.rs | 41 + .../src/endpoint/admin/roles/create.rs | 177 ++++ .../src/endpoint/admin/roles/delete.rs | 31 + misskey-api/src/endpoint/admin/roles/list.rs | 29 + misskey-api/src/endpoint/admin/roles/show.rs | 31 + .../src/endpoint/admin/roles/unassign.rs | 48 + .../src/endpoint/admin/roles/update.rs | 202 ++++ .../admin/roles/update_default_policies.rs | 57 ++ misskey-api/src/endpoint/admin/show_user.rs | 51 + misskey-api/src/endpoint/admin/show_users.rs | 4 + misskey-api/src/endpoint/admin/update_meta.rs | 12 + misskey-api/src/endpoint/users.rs | 11 + misskey-api/src/model.rs | 1 + misskey-api/src/model/meta.rs | 17 + misskey-api/src/model/role.rs | 349 +++++++ misskey-util/CHANGELOG.md | 2 + misskey-util/src/builder.rs | 4 + misskey-util/src/builder/admin.rs | 882 ++++++++++++++++++ misskey-util/src/builder/user.rs | 6 + misskey-util/src/client.rs | 347 ++++++- 23 files changed, 2323 insertions(+), 19 deletions(-) create mode 100644 misskey-api/src/endpoint/admin/roles.rs create mode 100644 misskey-api/src/endpoint/admin/roles/assign.rs create mode 100644 misskey-api/src/endpoint/admin/roles/create.rs create mode 100644 misskey-api/src/endpoint/admin/roles/delete.rs create mode 100644 misskey-api/src/endpoint/admin/roles/list.rs create mode 100644 misskey-api/src/endpoint/admin/roles/show.rs create mode 100644 misskey-api/src/endpoint/admin/roles/unassign.rs create mode 100644 misskey-api/src/endpoint/admin/roles/update.rs create mode 100644 misskey-api/src/endpoint/admin/roles/update_default_policies.rs create mode 100644 misskey-api/src/model/role.rs diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 74905710..b8b9fca3 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -76,6 +76,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - endpoint `admin/drive-capacity-override` - endpoint `clips/remove-note` - Support for Misskey v12.112.3 ~ v12.119.2 +- Support for Misskey v13.0.0 + - endpoint `admin/roles/*` ### Changed ### Deprecated @@ -98,6 +100,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - For Misskey v12.106.0 ~ v12.106.3 - endpoint `email-address/available` - For Misskey v12.108.0 ~ v12.108.1 +- endpoint `admin/invite`, `admin/moderators/*`, `admin/silence_user`, `admin/unsilence_user` + - For Misskey v13.0.0 ~ ### Fixed diff --git a/misskey-api/src/endpoint/admin.rs b/misskey-api/src/endpoint/admin.rs index 9c4fbc87..de4ffcb0 100644 --- a/misskey-api/src/endpoint/admin.rs +++ b/misskey-api/src/endpoint/admin.rs @@ -3,16 +3,12 @@ pub mod accounts; pub mod announcements; pub mod emoji; pub mod get_table_stats; -pub mod invite; -pub mod moderators; pub mod reset_password; pub mod server_info; pub mod show_moderation_logs; pub mod show_user; pub mod show_users; -pub mod silence_user; pub mod suspend_user; -pub mod unsilence_user; pub mod unsuspend_user; pub mod update_meta; pub mod vacuum; @@ -65,6 +61,26 @@ pub mod get_user_ips; #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] pub mod update_user_note; -#[cfg(feature = "12-112-0")] -#[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] +#[cfg(all(feature = "12-112-0", not(feature = "13-0-0")))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "12-112-0", not(feature = "13-0-0")))))] pub mod drive_capacity_override; + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +pub mod roles; + +#[cfg(not(feature = "13-0-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] +pub mod invite; + +#[cfg(not(feature = "13-0-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] +pub mod moderators; + +#[cfg(not(feature = "13-0-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] +pub mod silence_user; + +#[cfg(not(feature = "13-0-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] +pub mod unsilence_user; diff --git a/misskey-api/src/endpoint/admin/roles.rs b/misskey-api/src/endpoint/admin/roles.rs new file mode 100644 index 00000000..71058b06 --- /dev/null +++ b/misskey-api/src/endpoint/admin/roles.rs @@ -0,0 +1,8 @@ +pub mod assign; +pub mod create; +pub mod delete; +pub mod list; +pub mod show; +pub mod unassign; +pub mod update; +pub mod update_default_policies; diff --git a/misskey-api/src/endpoint/admin/roles/assign.rs b/misskey-api/src/endpoint/admin/roles/assign.rs new file mode 100644 index 00000000..ea0dc551 --- /dev/null +++ b/misskey-api/src/endpoint/admin/roles/assign.rs @@ -0,0 +1,41 @@ +use crate::model::{id::Id, role::Role, user::User}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + pub role_id: Id, + pub user_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/roles/assign"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let (user, _) = client.admin.create_user().await; + let role = client + .admin + .test(crate::endpoint::admin::roles::create::Request::default()) + .await; + + client + .admin + .test(Request { + role_id: role.id, + user_id: user.id, + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/admin/roles/create.rs b/misskey-api/src/endpoint/admin/roles/create.rs new file mode 100644 index 00000000..dfa873ed --- /dev/null +++ b/misskey-api/src/endpoint/admin/roles/create.rs @@ -0,0 +1,177 @@ +use crate::model::role::{cond_formula_option, Policies, Role, RoleCondFormulaValue, Target}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Debug, Default, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + #[builder(default, setter(into))] + pub name: String, + #[builder(default, setter(into))] + pub description: String, + #[builder(default, setter(strip_option, into))] + pub color: Option, + #[builder(default, setter(into))] + pub target: Target, + #[serde(with = "cond_formula_option")] + #[builder(default, setter(strip_option, into))] + pub cond_formula: Option, + #[builder(default, setter(into))] + pub is_public: bool, + #[builder(default, setter(into))] + pub is_moderator: bool, + #[builder(default, setter(into))] + pub is_administrator: bool, + #[builder(default, setter(into))] + pub can_edit_members_by_moderator: bool, + #[builder(default, setter(into))] + pub policies: Policies, +} + +impl misskey_core::Request for Request { + type Response = Role; + const ENDPOINT: &'static str = "admin/roles/create"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::{ + model::role::Priority, + test::{ClientExt, TestClient}, + }; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.admin.test(Request::default()).await; + } + + #[tokio::test] + async fn request_with_options() { + use chrono::Duration; + + use crate::model::role::{Policies, PolicyValue, RoleCondFormulaValue, Target}; + + let client = TestClient::new(); + client + .admin + .test(Request { + name: "role".to_string(), + description: "description".to_string(), + color: Some("#ff0000".to_string()), + target: Target::Conditional, + cond_formula: Some(RoleCondFormulaValue::And { + values: vec![ + RoleCondFormulaValue::Or { + values: vec![ + RoleCondFormulaValue::Not { + value: Box::new(RoleCondFormulaValue::IsLocal), + }, + RoleCondFormulaValue::IsRemote, + ], + }, + RoleCondFormulaValue::CreatedLessThan { + duration: Duration::days(2), + }, + RoleCondFormulaValue::CreatedMoreThan { + duration: Duration::minutes(3), + }, + RoleCondFormulaValue::FollowersLessThanOrEq { value: 100 }, + RoleCondFormulaValue::FollowersMoreThanOrEq { value: 10 }, + RoleCondFormulaValue::FollowingLessThanOrEq { value: 100 }, + RoleCondFormulaValue::FollowingMoreThanOrEq { value: 10 }, + ], + }), + is_public: true, + is_moderator: true, + is_administrator: true, + can_edit_members_by_moderator: true, + policies: Policies { + gtl_available: Some(PolicyValue { + use_default: true, + priority: Priority::Low, + value: false, + }), + ltl_available: Some(PolicyValue { + use_default: false, + priority: Priority::Middle, + value: true, + }), + can_public_note: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: true, + }), + can_invite: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: true, + }), + can_manage_custom_emojis: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: true, + }), + can_hide_ads: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: true, + }), + drive_capacity_mb: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 1000, + }), + pin_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 100, + }), + antenna_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 10, + }), + word_mute_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 10000, + }), + webhook_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 10, + }), + clip_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 1000, + }), + note_each_clips_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 10000, + }), + user_list_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 100, + }), + user_each_user_lists_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 1000, + }), + rate_limit_factor: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 0.5, + }), + }, + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/admin/roles/delete.rs b/misskey-api/src/endpoint/admin/roles/delete.rs new file mode 100644 index 00000000..8cf65243 --- /dev/null +++ b/misskey-api/src/endpoint/admin/roles/delete.rs @@ -0,0 +1,31 @@ +use crate::model::{id::Id, role::Role}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub role_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/roles/delete"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let role = client + .admin + .test(crate::endpoint::admin::roles::create::Request::default()) + .await; + + client.admin.test(Request { role_id: role.id }).await; + } +} diff --git a/misskey-api/src/endpoint/admin/roles/list.rs b/misskey-api/src/endpoint/admin/roles/list.rs new file mode 100644 index 00000000..df82c2a4 --- /dev/null +++ b/misskey-api/src/endpoint/admin/roles/list.rs @@ -0,0 +1,29 @@ +use crate::model::role::Role; + +use serde::Serialize; + +#[derive(Serialize, Default, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request {} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "admin/roles/list"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client + .admin + .test(crate::endpoint::admin::roles::create::Request::default()) + .await; + + client.admin.test(Request::default()).await; + } +} diff --git a/misskey-api/src/endpoint/admin/roles/show.rs b/misskey-api/src/endpoint/admin/roles/show.rs new file mode 100644 index 00000000..22af04f6 --- /dev/null +++ b/misskey-api/src/endpoint/admin/roles/show.rs @@ -0,0 +1,31 @@ +use crate::model::{id::Id, role::Role}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub role_id: Id, +} + +impl misskey_core::Request for Request { + type Response = Role; + const ENDPOINT: &'static str = "admin/roles/show"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let role = client + .admin + .test(crate::endpoint::admin::roles::create::Request::default()) + .await; + + client.admin.test(Request { role_id: role.id }).await; + } +} diff --git a/misskey-api/src/endpoint/admin/roles/unassign.rs b/misskey-api/src/endpoint/admin/roles/unassign.rs new file mode 100644 index 00000000..5946856e --- /dev/null +++ b/misskey-api/src/endpoint/admin/roles/unassign.rs @@ -0,0 +1,48 @@ +use crate::model::{id::Id, role::Role, user::User}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub role_id: Id, + pub user_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/roles/unassign"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let (user, _) = client.admin.create_user().await; + let role = client + .admin + .test(crate::endpoint::admin::roles::create::Request::default()) + .await; + client + .admin + .test( + crate::endpoint::admin::roles::assign::Request::builder() + .role_id(role.id) + .user_id(user.id) + .build(), + ) + .await; + + client + .admin + .test(Request { + role_id: role.id, + user_id: user.id, + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/admin/roles/update.rs b/misskey-api/src/endpoint/admin/roles/update.rs new file mode 100644 index 00000000..ed441c6c --- /dev/null +++ b/misskey-api/src/endpoint/admin/roles/update.rs @@ -0,0 +1,202 @@ +use crate::model::{ + id::Id, + role::{cond_formula_option, Policies, Role, RoleCondFormulaValue, Target}, +}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + pub role_id: Id, + #[builder(default, setter(into))] + pub name: String, + #[builder(default, setter(into))] + pub description: String, + #[builder(default, setter(strip_option, into))] + pub color: Option, + #[builder(default, setter(into))] + pub target: Target, + #[serde(with = "cond_formula_option")] + #[builder(default, setter(strip_option, into))] + pub cond_formula: Option, + #[builder(default, setter(into))] + pub is_public: bool, + #[builder(default, setter(into))] + pub is_moderator: bool, + #[builder(default, setter(into))] + pub is_administrator: bool, + #[builder(default, setter(into))] + pub can_edit_members_by_moderator: bool, + #[builder(default, setter(into))] + pub policies: Policies, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/roles/update"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::model::role::{Policies, PolicyValue, Priority, RoleCondFormulaValue, Target}; + use crate::test::{ClientExt, TestClient}; + use chrono::Duration; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let role = client + .admin + .test(crate::endpoint::admin::roles::create::Request::default()) + .await; + + client + .admin + .test(Request { + role_id: role.id, + name: String::new(), + description: String::new(), + color: None, + target: Target::Manual, + cond_formula: None, + is_public: false, + is_moderator: false, + is_administrator: false, + can_edit_members_by_moderator: false, + policies: Policies::default(), + }) + .await; + } + + #[tokio::test] + async fn request_with_options() { + let client = TestClient::new(); + let role = client + .admin + .test(crate::endpoint::admin::roles::create::Request::default()) + .await; + + client + .admin + .test(Request { + role_id: role.id, + name: "role".to_string(), + description: "description".to_string(), + color: Some("#ff0000".to_string()), + target: Target::Conditional, + cond_formula: Some(RoleCondFormulaValue::And { + values: vec![ + RoleCondFormulaValue::Or { + values: vec![ + RoleCondFormulaValue::Not { + value: Box::new(RoleCondFormulaValue::IsLocal), + }, + RoleCondFormulaValue::IsRemote, + ], + }, + RoleCondFormulaValue::CreatedLessThan { + duration: Duration::days(2), + }, + RoleCondFormulaValue::CreatedMoreThan { + duration: Duration::minutes(3), + }, + RoleCondFormulaValue::FollowersLessThanOrEq { value: 100 }, + RoleCondFormulaValue::FollowersMoreThanOrEq { value: 10 }, + RoleCondFormulaValue::FollowingLessThanOrEq { value: 100 }, + RoleCondFormulaValue::FollowingMoreThanOrEq { value: 10 }, + ], + }), + is_public: true, + is_moderator: true, + is_administrator: true, + can_edit_members_by_moderator: true, + policies: Policies { + gtl_available: Some(PolicyValue { + use_default: true, + priority: Priority::Low, + value: false, + }), + ltl_available: Some(PolicyValue { + use_default: false, + priority: Priority::Middle, + value: true, + }), + can_public_note: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: true, + }), + can_invite: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: true, + }), + can_manage_custom_emojis: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: true, + }), + can_hide_ads: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: true, + }), + drive_capacity_mb: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 1000, + }), + pin_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 100, + }), + antenna_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 10, + }), + word_mute_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 10000, + }), + webhook_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 10, + }), + clip_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 1000, + }), + note_each_clips_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 10000, + }), + user_list_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 100, + }), + user_each_user_lists_limit: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 1000, + }), + rate_limit_factor: Some(PolicyValue { + use_default: false, + priority: Priority::High, + value: 0.5, + }), + }, + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/admin/roles/update_default_policies.rs b/misskey-api/src/endpoint/admin/roles/update_default_policies.rs new file mode 100644 index 00000000..8dd19883 --- /dev/null +++ b/misskey-api/src/endpoint/admin/roles/update_default_policies.rs @@ -0,0 +1,57 @@ +use crate::model::role::PoliciesSimple; + +use serde::Serialize; + +#[derive(Serialize, Default, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub policies: PoliciesSimple, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "admin/roles/update-default-policies"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::{ + model::role::PoliciesSimple, + test::{ClientExt, TestClient}, + }; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.admin.test(Request::default()).await; + } + + #[tokio::test] + async fn request_with_options() { + let client = TestClient::new(); + client + .admin + .test(Request { + policies: PoliciesSimple { + gtl_available: Some(true), + ltl_available: Some(true), + can_public_note: Some(true), + can_invite: Some(true), + can_manage_custom_emojis: Some(true), + can_hide_ads: Some(false), + drive_capacity_mb: Some(1000), + pin_limit: Some(100), + antenna_limit: Some(10), + word_mute_limit: Some(10000), + webhook_limit: Some(10), + clip_limit: Some(1000), + note_each_clips_limit: Some(10000), + user_list_limit: Some(100), + user_each_user_lists_limit: Some(1000), + rate_limit_factor: Some(0.5), + }, + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/admin/show_user.rs b/misskey-api/src/endpoint/admin/show_user.rs index b90ad7de..2a365ccd 100644 --- a/misskey-api/src/endpoint/admin/show_user.rs +++ b/misskey-api/src/endpoint/admin/show_user.rs @@ -3,6 +3,8 @@ use std::collections::HashMap; #[cfg(not(feature = "12-111-0"))] use crate::model::drive::DriveFile; +#[cfg(feature = "13-0-0")] +use crate::model::role::{PoliciesSimple, Role}; use crate::model::{id::Id, user::User}; #[cfg(feature = "12-111-0")] use crate::model::{notification::NotificationType, signin::Signin, user::IntegrationValue}; @@ -99,17 +101,39 @@ pub struct Response { pub muted_instances: Option>, #[serde(default)] pub muting_notification_types: Option>, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub is_moderator: bool, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + #[serde(default)] + pub is_moderator: Option, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub is_silenced: bool, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + #[serde(default)] + pub is_silenced: Option, pub is_suspended: bool, #[cfg(feature = "12-112-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + #[serde(default)] pub last_active_date: Option>, #[cfg(feature = "12-112-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] + #[serde(default)] pub moderation_note: Option, #[serde(default)] pub signins: Option>, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + #[serde(default)] + pub policies: Option, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + #[serde(default)] + pub roles: Option>, } impl misskey_core::Request for Request { @@ -130,6 +154,7 @@ mod tests { client.admin.test(Request { user_id: user.id }).await; } + #[cfg(not(feature = "13-0-0"))] #[tokio::test] async fn request_moderator() { let client = TestClient::new(); @@ -141,4 +166,30 @@ mod tests { client.user.test(Request { user_id }).await; } + + #[cfg(feature = "13-0-0")] + #[tokio::test] + async fn request_moderator() { + let client = TestClient::new(); + let user_id = client.user.me().await.id; + let role = client + .admin + .test( + crate::endpoint::admin::roles::create::Request::builder() + .is_moderator(true) + .build(), + ) + .await; + client + .admin + .test( + crate::endpoint::admin::roles::assign::Request::builder() + .role_id(role.id) + .user_id(user_id) + .build(), + ) + .await; + + client.user.test(Request { user_id }).await; + } } diff --git a/misskey-api/src/endpoint/admin/show_users.rs b/misskey-api/src/endpoint/admin/show_users.rs index c925ec85..14fd5bf5 100644 --- a/misskey-api/src/endpoint/admin/show_users.rs +++ b/misskey-api/src/endpoint/admin/show_users.rs @@ -16,6 +16,8 @@ pub enum UserState { Admin, Moderator, AdminOrModerator, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] Silenced, Suspended, } @@ -37,6 +39,7 @@ impl std::str::FromStr for UserState { "admin" | "Admin" => Ok(UserState::Admin), "moderator" | "Moderator" => Ok(UserState::Moderator), "adminOrModerator" | "AdminOrModerator" => Ok(UserState::AdminOrModerator), + #[cfg(not(feature = "13-0-0"))] "silenced" | "Silenced" => Ok(UserState::Silenced), "suspended" | "Suspended" => Ok(UserState::Suspended), _ => Err(ParseUserStateError { _priv: () }), @@ -309,6 +312,7 @@ mod tests { // origin: None, // }) // .await; + #[cfg(not(feature = "13-0-0"))] client .admin .test(Request { diff --git a/misskey-api/src/endpoint/admin/update_meta.rs b/misskey-api/src/endpoint/admin/update_meta.rs index efbecf5e..6d701b3a 100644 --- a/misskey-api/src/endpoint/admin/update_meta.rs +++ b/misskey-api/src/endpoint/admin/update_meta.rs @@ -14,8 +14,12 @@ use url::Url; pub struct Request { #[builder(default, setter(strip_option))] pub disable_registration: Option, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] #[builder(default, setter(strip_option))] pub disable_local_timeline: Option, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] #[builder(default, setter(strip_option))] pub disable_global_timeline: Option, #[builder(default, setter(strip_option))] @@ -81,9 +85,13 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub max_note_text_length: Option, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub local_drive_capacity_mb: Option, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub remote_drive_capacity_mb: Option, @@ -334,7 +342,9 @@ mod tests { .admin .test(Request { disable_registration: Some(false), + #[cfg(not(feature = "13-0-0"))] disable_local_timeline: Some(false), + #[cfg(not(feature = "13-0-0"))] disable_global_timeline: Some(false), use_star_for_reaction_fallback: Some(false), #[cfg(feature = "12-58-0")] @@ -361,7 +371,9 @@ mod tests { default_dark_theme: Some(Some("{}".to_string())), #[cfg(not(feature = "12-108-0"))] max_note_text_length: Some(1000), + #[cfg(not(feature = "13-0-0"))] local_drive_capacity_mb: Some(1000), + #[cfg(not(feature = "13-0-0"))] remote_drive_capacity_mb: Some(1000), cache_remote_files: Some(true), #[cfg(not(feature = "12-108-0"))] diff --git a/misskey-api/src/endpoint/users.rs b/misskey-api/src/endpoint/users.rs index 0dc55b7c..b6c096a3 100644 --- a/misskey-api/src/endpoint/users.rs +++ b/misskey-api/src/endpoint/users.rs @@ -54,8 +54,14 @@ pub mod reactions; pub enum UserState { All, Alive, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] Admin, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] Moderator, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] AdminOrModerator, } @@ -74,8 +80,11 @@ impl std::str::FromStr for UserState { match s { "all" | "All" => Ok(UserState::All), "alive" | "Alive" => Ok(UserState::Alive), + #[cfg(not(feature = "13-0-0"))] "admin" | "Admin" => Ok(UserState::Admin), + #[cfg(not(feature = "13-0-0"))] "moderator" | "Moderator" => Ok(UserState::Moderator), + #[cfg(not(feature = "13-0-0"))] "adminOrModerator" | "AdminOrModerator" => Ok(UserState::AdminOrModerator), _ => Err(ParseUserStateError { _priv: () }), } @@ -221,6 +230,7 @@ mod tests { hostname: None, }) .await; + #[cfg(not(feature = "13-0-0"))] client .test(Request { limit: None, @@ -243,6 +253,7 @@ mod tests { hostname: None, }) .await; + #[cfg(not(feature = "13-0-0"))] client .test(Request { limit: None, diff --git a/misskey-api/src/model.rs b/misskey-api/src/model.rs index 90eca0fd..c104c900 100644 --- a/misskey-api/src/model.rs +++ b/misskey-api/src/model.rs @@ -40,6 +40,7 @@ pub mod notification; pub mod page; pub mod query; pub mod registry; +pub mod role; pub mod signin; pub mod sort; pub mod user; diff --git a/misskey-api/src/model/meta.rs b/misskey-api/src/model/meta.rs index a441df77..f83307da 100644 --- a/misskey-api/src/model/meta.rs +++ b/misskey-api/src/model/meta.rs @@ -5,6 +5,8 @@ use std::fmt::{self, Display}; use crate::model::ad::{Ad, Place}; #[cfg(feature = "12-62-0")] use crate::model::clip::Clip; +#[cfg(feature = "13-0-0")] +use crate::model::role::PoliciesSimple; use crate::model::{emoji::Emoji, id::Id, user::User}; use serde::{Deserialize, Serialize}; @@ -38,9 +40,17 @@ pub struct Meta { #[cfg(feature = "12-108-0")] pub default_light_theme: Option, pub disable_registration: bool, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub disable_local_timeline: bool, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub disable_global_timeline: bool, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub drive_capacity_per_local_user_mb: u64, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub drive_capacity_per_remote_user_mb: u64, /// This field is [`bool`] (i.e. not [`Option`]) on non-feature="12-58-0". #[cfg(feature = "12-58-0")] @@ -97,6 +107,9 @@ pub struct Meta { pub enable_service_worker: bool, #[cfg(feature = "12-88-0")] pub translator_available: bool, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + pub policies: PoliciesSimple, /// This field is [`Option`][`Option`] on non-feature="12-58-0". #[cfg(feature = "12-58-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-48-0")))] @@ -296,7 +309,11 @@ pub struct AdminMeta { #[serde(rename_all = "camelCase")] pub struct FeaturesMeta { pub registration: bool, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub local_time_line: bool, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub global_time_line: bool, #[cfg(feature = "12-92-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-92-0")))] diff --git a/misskey-api/src/model/role.rs b/misskey-api/src/model/role.rs new file mode 100644 index 00000000..b75c6012 --- /dev/null +++ b/misskey-api/src/model/role.rs @@ -0,0 +1,349 @@ +use crate::model::{id::Id, user::User}; + +use chrono::{DateTime, Duration, Utc}; +use serde::{Deserialize, Serialize}; +use thiserror::Error; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Role { + pub id: Id, + pub created_at: DateTime, + pub updated_at: DateTime, + pub name: String, + pub description: String, + pub color: Option, + pub target: Target, + #[serde(with = "cond_formula_option")] + pub cond_formula: Option, + pub is_public: bool, + pub is_moderator: bool, + pub is_administrator: bool, + pub can_edit_members_by_moderator: bool, + pub policies: Policies, + pub users_count: u64, + #[serde(default)] + pub users: Option>, +} + +impl_entity!(Role); + +#[derive(Serialize, Deserialize, Default, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub enum Target { + #[default] + Manual, + Conditional, +} + +pub(crate) mod cond_formula_option { + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + + use super::RoleCondFormulaValue; + + #[derive(Serialize, Deserialize, Debug, Clone)] + #[serde(deny_unknown_fields)] + struct Empty {} + + #[derive(Serialize, Deserialize, Debug, Clone)] + #[serde(untagged)] + enum ValueOrEmpty { + Value(RoleCondFormulaValue), + Empty(Empty), + } + + pub fn serialize( + opt: &Option, + serializer: S, + ) -> Result + where + S: Serializer, + { + match opt { + Some(cond_formula) => { + serializer.serialize_some(&ValueOrEmpty::Value(cond_formula.clone())) + } + None => serializer.serialize_some(&ValueOrEmpty::Empty(Empty {})), + } + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + match Deserialize::deserialize(deserializer)? { + ValueOrEmpty::Value(cond_formula) => Ok(Some(cond_formula)), + ValueOrEmpty::Empty(_) => Ok(None), + } + } +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase", tag = "type")] +pub enum RoleCondFormulaValue { + And { + values: Vec, + }, + Or { + values: Vec, + }, + Not { + value: Box, + }, + IsLocal, + IsRemote, + CreatedLessThan { + #[serde(rename = "sec", with = "duration_seconds")] + duration: Duration, + }, + CreatedMoreThan { + #[serde(rename = "sec", with = "duration_seconds")] + duration: Duration, + }, + FollowersLessThanOrEq { + value: u64, + }, + FollowersMoreThanOrEq { + value: u64, + }, + FollowingLessThanOrEq { + value: u64, + }, + FollowingMoreThanOrEq { + value: u64, + }, +} + +mod duration_seconds { + use chrono::Duration; + use serde::{Deserialize, Deserializer, Serializer}; + + pub fn serialize(duration: &Duration, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_i64(duration.num_seconds()) + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let seconds = i64::deserialize(deserializer)?; + Ok(Duration::seconds(seconds)) + } +} + +impl RoleCondFormulaValue { + pub fn and(self, rhs: impl Into) -> Self { + let rhs = rhs.into(); + match self { + Self::And { values: mut v } => { + v.push(rhs); + Self::And { values: v } + } + lhs => Self::And { + values: vec![lhs, rhs], + }, + } + } + + pub fn or(self, rhs: impl Into) -> Self { + let rhs = rhs.into(); + match self { + Self::Or { values: mut v } => { + v.push(rhs); + Self::Or { values: v } + } + lhs => Self::Or { + values: vec![lhs, rhs], + }, + } + } +} + +impl std::ops::Not for RoleCondFormulaValue { + type Output = Self; + + fn not(self) -> Self::Output { + Self::Not { + value: Box::new(self), + } + } +} + +#[derive(Serialize, Deserialize, Default, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Policies { + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub gtl_available: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub ltl_available: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub can_public_note: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub can_invite: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub can_manage_custom_emojis: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub can_hide_ads: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub drive_capacity_mb: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub pin_limit: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub antenna_limit: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub word_mute_limit: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub webhook_limit: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub clip_limit: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub note_each_clips_limit: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub user_list_limit: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub user_each_user_lists_limit: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub rate_limit_factor: Option>, +} + +#[derive(Serialize, Deserialize, Default, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct PolicyValue { + pub use_default: bool, + #[serde(with = "priority_u8")] + pub priority: Priority, + pub value: T, +} + +#[derive(Serialize, Deserialize, Default, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub enum Priority { + #[default] + Low, + Middle, + High, +} + +#[derive(Debug, Error, Clone)] +#[error("invalid priority")] +pub struct ParsePriorityError { + _priv: (), +} + +impl std::str::FromStr for Priority { + type Err = ParsePriorityError; + + fn from_str(s: &str) -> Result { + match s { + "low" | "Low" => Ok(Priority::Low), + "middle" | "Middle" => Ok(Priority::Middle), + "high" | "High" => Ok(Priority::High), + _ => Err(ParsePriorityError { _priv: () }), + } + } +} + +mod priority_u8 { + use super::Priority; + use serde::{de, Deserialize, Deserializer, Serializer}; + + pub fn serialize(priority: &Priority, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_u8(match priority { + Priority::Low => 0, + Priority::Middle => 1, + Priority::High => 2, + }) + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let value = u8::deserialize(deserializer)?; + match value { + 0 => Ok(Priority::Low), + 1 => Ok(Priority::Middle), + 2 => Ok(Priority::High), + _ => Err(de::Error::custom("invalid priority")), + } + } +} + +#[derive(Serialize, Deserialize, Default, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct PoliciesSimple { + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub gtl_available: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub ltl_available: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub can_public_note: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub can_invite: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub can_manage_custom_emojis: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub can_hide_ads: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub drive_capacity_mb: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub pin_limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub antenna_limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub word_mute_limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub webhook_limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub clip_limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub note_each_clips_limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub user_list_limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub user_each_user_lists_limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub rate_limit_factor: Option, +} diff --git a/misskey-util/CHANGELOG.md b/misskey-util/CHANGELOG.md index 534a8d72..6a0823d2 100644 --- a/misskey-util/CHANGELOG.md +++ b/misskey-util/CHANGELOG.md @@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - For Misskey v12.88.0 ~ - `ClientExt::server_logs` - For Misskey v12.93.0 ~ +- `ClientExt::add_moderator`, `ClientExt::remove_moderator`, `ClientExt::silence`, `ClientExt::unsilence` + - For Misskey v13.0.0 ~ ### Fixed ### Security diff --git a/misskey-util/src/builder.rs b/misskey-util/src/builder.rs index 41fec762..256d77e8 100644 --- a/misskey-util/src/builder.rs +++ b/misskey-util/src/builder.rs @@ -71,3 +71,7 @@ pub use admin::ServerLogListBuilder; #[cfg(not(feature = "12-108-0"))] #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] pub use me::IntoUserFields; + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +pub use admin::{DefaultPoliciesUpdateBuilder, RoleBuilder, RoleUpdateBuilder}; diff --git a/misskey-util/src/builder/admin.rs b/misskey-util/src/builder/admin.rs index 23806ffe..a905aa40 100644 --- a/misskey-util/src/builder/admin.rs +++ b/misskey-util/src/builder/admin.rs @@ -12,6 +12,10 @@ use misskey_api::model::emoji::Emoji; use misskey_api::model::log::{Log, LogLevel}; #[cfg(feature = "12-112-0")] use misskey_api::model::meta::{SensitiveMediaDetection, SensitiveMediaDetectionSensitivity}; +#[cfg(feature = "13-0-0")] +use misskey_api::model::role::{ + self, Policies, PoliciesSimple, PolicyValue, Role, RoleCondFormulaValue, Target, +}; use misskey_api::model::{announcement::Announcement, user::User}; use misskey_api::{endpoint, EntityRef}; use misskey_core::Client; @@ -148,8 +152,12 @@ impl MetaUpdateBuilder { /// Sets whether the instance has registration enabled. pub disable_registration; /// Sets whether the instance has local timeline enabled. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub disable_local_timeline; /// Sets whether the instance has global timeline enabled. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub disable_global_timeline; /// Sets whether the instance uses ★ as fallback if the reaction emoji is unknown. pub use_star_for_reaction_fallback; @@ -213,12 +221,16 @@ impl MetaUpdateBuilder { } /// Sets the drive capacity per local user in megabytes. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub fn local_drive_capacity(&mut self, mb: u64) -> &mut Self { self.request.local_drive_capacity_mb.replace(mb); self } /// Sets the drive capacity per remote user in megabytes. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub fn remote_drive_capacity(&mut self, mb: u64) -> &mut Self { self.request.remote_drive_capacity_mb.replace(mb); self @@ -970,3 +982,873 @@ impl AdUpdateBuilder { Ok(()) } } + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +/// Builder for building [`PolicyValue`]. +pub struct PolicyValueBuilder { + use_default: bool, + priority: role::Priority, + value: T, +} + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +impl PolicyValueBuilder { + /// Creates a builder. + pub fn new(value: T) -> Self { + PolicyValueBuilder { + use_default: false, + priority: role::Priority::Low, + value, + } + } + + /// Sets whether to use default policy. + pub fn use_default(&mut self, use_default: bool) -> &mut Self { + self.use_default = use_default; + self + } + + /// Sets the priority of the value. + pub fn priority(&mut self, priority: role::Priority) -> &mut Self { + self.priority = priority; + self + } + + /// Sets the priority of the value to high. + pub fn priority_high(&mut self) -> &mut Self { + self.priority(role::Priority::High) + } + + /// Sets the priority of the value to middle. + pub fn priority_middle(&mut self) -> &mut Self { + self.priority(role::Priority::Middle) + } + + /// Sets the priority of the value to low. + pub fn priority_low(&mut self) -> &mut Self { + self.priority(role::Priority::Low) + } + + /// Sets the policy value. + pub fn value(&mut self, value: T) -> &mut Self { + self.value = value; + self + } +} + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +impl PolicyValueBuilder { + pub fn build(&self) -> PolicyValue { + PolicyValue { + use_default: self.use_default, + priority: self.priority.to_owned(), + value: self.value.to_owned(), + } + } +} + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +/// Builder for the [`build_role`][`crate::ClientExt::build_role`] method. +pub struct RoleBuilder { + client: C, + request: endpoint::admin::roles::create::Request, +} + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +impl RoleBuilder { + /// Creates a builder with the client. + pub fn new(client: C) -> Self { + let request = endpoint::admin::roles::create::Request::default(); + RoleBuilder { client, request } + } + + /// Gets the request object for reuse. + pub fn as_request(&self) -> &endpoint::admin::roles::create::Request { + &self.request + } + + /// Sets the name of the role. + pub fn name(&mut self, name: impl Into) -> &mut Self { + self.request.name = name.into(); + self + } + + /// Sets the description of the role. + pub fn description(&mut self, description: impl Into) -> &mut Self { + self.request.description = description.into(); + self + } + + /// Sets the color of the role. + pub fn color(&mut self, color: impl Into) -> &mut Self { + self.request.color.replace(color.into()); + self + } + + /// Sets the assignment type of the role. + pub fn target(&mut self, target: impl Into) -> &mut Self { + self.request.target = target.into(); + self + } + + /// Sets the role to be assigned manually. + /// + /// This is equivalent to `.target(Target::Manual)`. + pub fn manual(&mut self) -> &mut Self { + self.target(Target::Manual) + } + + /// Sets the role to be assigned automatically based on the condition. + /// + /// This is equivalent to `.target(Target::Conditional)`. + pub fn conditional(&mut self) -> &mut Self { + self.target(Target::Conditional) + } + + /// Sets the condition of the role. + pub fn condition(&mut self, condition: impl Into) -> &mut Self { + self.conditional(); + self.request.cond_formula.replace(condition.into()); + self + } + + /// Sets whether the role is public or not. + pub fn public(&mut self, public: bool) -> &mut Self { + self.request.is_public = public; + self + } + + /// Sets whether to give the moderator permission to the members of the role. + pub fn moderator(&mut self, moderator: bool) -> &mut Self { + self.request.is_moderator = moderator; + self + } + + /// Sets whether to give the administrator permission to the members of the role. + pub fn administrator(&mut self, administrator: bool) -> &mut Self { + self.request.is_administrator = administrator; + self + } + + /// Sets whether to allow moderators to edit members of the role. + pub fn allow_moderator_to_edit_members( + &mut self, + can_edit_members_by_moderator: bool, + ) -> &mut Self { + self.request.can_edit_members_by_moderator = can_edit_members_by_moderator; + self + } + + /// Sets the policies of the role. + pub fn policies(&mut self, policies: impl Into) -> &mut Self { + self.request.policies = policies.into(); + self + } + + /// Sets whether to allow the members of the role to view the global timeline. + pub fn allow_global_timeline( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .gtl_available + .replace(build_policy_value(PolicyValueBuilder::new(false))); + self + } + + /// Sets whether to allow the members of the role to view the local timeline. + pub fn allow_local_timeline( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .ltl_available + .replace(build_policy_value(PolicyValueBuilder::new(false))); + self + } + + /// Sets whether to allow the members of the role to post public note. + pub fn allow_public_note( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .can_public_note + .replace(build_policy_value(PolicyValueBuilder::new(false))); + self + } + + /// Sets whether to allow the members of the role to create invitation code of the instance. + pub fn allow_invitation( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .can_invite + .replace(build_policy_value(PolicyValueBuilder::new(false))); + self + } + + /// Sets whether to allow the members of the role to manage custom emojis. + pub fn allow_custom_emojis_management( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .can_manage_custom_emojis + .replace(build_policy_value(PolicyValueBuilder::new(false))); + self + } + + /// Sets whether to allow the members of the role to hide ads. + pub fn allow_hiding_ads( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .can_hide_ads + .replace(build_policy_value(PolicyValueBuilder::new(false))); + self + } + + /// Sets the drive capacity of the members of the role in megabytes. + pub fn drive_capacity( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .drive_capacity_mb + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of pinned notes for the members of the role. + pub fn pin_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .pin_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of antennas for the members of the role. + pub fn antenna_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .antenna_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of characters in word mutes for the members of the role. + pub fn word_mute_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .word_mute_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of webhooks for the members of the role. + pub fn webhook_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .webhook_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of clips for the members of the role. + pub fn clip_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .clip_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of notes per clip for the members of the role. + pub fn note_each_clips_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .note_each_clips_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of user lists for the members of the role. + pub fn user_list_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .user_list_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of users per user list for the members of the role. + pub fn user_each_user_lists_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .user_each_user_lists_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the rate limit factor of the members of the role. + pub fn rate_limit_factor( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .rate_limit_factor + .replace(build_policy_value(PolicyValueBuilder::new(0.0))); + self + } +} + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +impl RoleBuilder { + /// Creates the role. + pub async fn create(&self) -> Result> { + let role = self + .client + .request(&self.request) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(role) + } +} + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +/// Builder for the [`update_role`][`crate::ClientExt::update_role`] method. +pub struct RoleUpdateBuilder { + client: C, + request: endpoint::admin::roles::update::Request, +} + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +impl RoleUpdateBuilder { + /// Creates a builder with the client. + pub fn new(client: C, role: Role) -> Self { + let Role { + id, + name, + description, + color, + target, + cond_formula, + is_public, + is_moderator, + is_administrator, + can_edit_members_by_moderator, + policies, + .. + } = role; + let request = endpoint::admin::roles::update::Request { + role_id: id, + name, + description, + color, + target, + cond_formula, + is_public, + is_moderator, + is_administrator, + can_edit_members_by_moderator, + policies, + }; + RoleUpdateBuilder { client, request } + } + + /// Gets the request object for reuse. + pub fn as_request(&self) -> &endpoint::admin::roles::update::Request { + &self.request + } + + /// Sets the name of the role. + pub fn name(&mut self, name: impl Into) -> &mut Self { + self.request.name = name.into(); + self + } + + /// Sets the description of the role. + pub fn description(&mut self, description: impl Into) -> &mut Self { + self.request.description = description.into(); + self + } + + /// Sets the color of the role. + pub fn color(&mut self, color: impl Into) -> &mut Self { + self.request.color.replace(color.into()); + self + } + + /// Sets the assignment type of the role. + pub fn target(&mut self, target: impl Into) -> &mut Self { + self.request.target = target.into(); + self + } + + /// Sets the role to be assigned manually. + /// + /// This is equivalent to `.target(Target::Manual)`. + pub fn manual(&mut self) -> &mut Self { + self.target(Target::Manual) + } + + /// Sets the role to be assigned automatically based on conditions. + /// + /// This is equivalent to `.target(Target::Conditional)`. + pub fn conditional(&mut self) -> &mut Self { + self.target(Target::Conditional) + } + + /// Sets the conditions of the role. + pub fn cond_formula(&mut self, cond_formula: impl Into) -> &mut Self { + self.request.cond_formula.replace(cond_formula.into()); + self + } + + /// Sets whether the role is public or not. + pub fn public(&mut self, public: bool) -> &mut Self { + self.request.is_public = public; + self + } + + /// Sets whether to give the moderator permission to the members of the role. + pub fn moderator(&mut self, moderator: bool) -> &mut Self { + self.request.is_moderator = moderator; + self + } + + /// Sets whether to give the administrator permission to the members of the role. + pub fn administrator(&mut self, administrator: bool) -> &mut Self { + self.request.is_administrator = administrator; + self + } + + /// Sets whether to allow moderators to edit members of the role. + pub fn allow_moderator_to_edit_members( + &mut self, + can_edit_members_by_moderator: bool, + ) -> &mut Self { + self.request.can_edit_members_by_moderator = can_edit_members_by_moderator; + self + } + + /// Sets the policies of the role. + pub fn policies(&mut self, policies: impl Into) -> &mut Self { + self.request.policies = policies.into(); + self + } + + /// Sets whether to allow the members of the role to view the global timeline. + pub fn allow_global_timeline( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .gtl_available + .replace(build_policy_value(PolicyValueBuilder::new(false))); + self + } + + /// Sets whether to allow the members of the role to view the local timeline. + pub fn allow_local_timeline( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .ltl_available + .replace(build_policy_value(PolicyValueBuilder::new(false))); + self + } + + /// Sets whether to allow the members of the role to post public note. + pub fn allow_public_note( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .can_public_note + .replace(build_policy_value(PolicyValueBuilder::new(false))); + self + } + + /// Sets whether to allow the members of the role to create invitation code of the instance. + pub fn allow_invitation( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .can_invite + .replace(build_policy_value(PolicyValueBuilder::new(false))); + self + } + + /// Sets whether to allow the members of the role to manage custom emojis. + pub fn allow_custom_emojis_management( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .can_manage_custom_emojis + .replace(build_policy_value(PolicyValueBuilder::new(false))); + self + } + + /// Sets whether to allow the members of the role to hide ads. + pub fn allow_hiding_ads( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .can_hide_ads + .replace(build_policy_value(PolicyValueBuilder::new(false))); + self + } + + /// Sets the drive capacity of the members of the role in megabytes. + pub fn drive_capacity( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .drive_capacity_mb + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of pinned notes for the members of the role. + pub fn pin_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .pin_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of antennas for the members of the role. + pub fn antenna_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .antenna_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of characters in word mutes for the members of the role. + pub fn word_mute_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .word_mute_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of webhooks for the members of the role. + pub fn webhook_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .webhook_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of clips for the members of the role. + pub fn clip_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .clip_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of notes per clip for the members of the role. + pub fn note_each_clips_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .note_each_clips_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of user lists for the members of the role. + pub fn user_list_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .user_list_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the maximum number of users per user list for the members of the role. + pub fn user_each_user_lists_limit( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .user_each_user_lists_limit + .replace(build_policy_value(PolicyValueBuilder::new(0))); + self + } + + /// Sets the rate limit factor of the members of the role. + pub fn rate_limit_factor( + &mut self, + build_policy_value: impl FnOnce(PolicyValueBuilder) -> PolicyValue, + ) -> &mut Self { + self.request + .policies + .rate_limit_factor + .replace(build_policy_value(PolicyValueBuilder::new(0.0))); + self + } +} + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +impl RoleUpdateBuilder { + /// Updates the role. + pub async fn update(&self) -> Result<(), Error> { + self.client + .request(&self.request) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + } +} + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +/// Builder for the [`update_role`][`crate::ClientExt::update_role`] method. +pub struct DefaultPoliciesUpdateBuilder { + client: C, + request: endpoint::admin::roles::update_default_policies::Request, +} + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +impl DefaultPoliciesUpdateBuilder { + /// Creates a builder with the client. + pub fn new(client: C, policies: PoliciesSimple) -> Self { + let request = endpoint::admin::roles::update_default_policies::Request { policies }; + DefaultPoliciesUpdateBuilder { client, request } + } + + /// Gets the request object for reuse. + pub fn as_request(&self) -> &endpoint::admin::roles::update_default_policies::Request { + &self.request + } + + /// Sets whether to allow users to view the global timeline. + pub fn allow_global_timeline(&mut self, allow_global_timeline: bool) -> &mut Self { + self.request + .policies + .gtl_available + .replace(allow_global_timeline); + self + } + + /// Sets whether to allow users to view the local timeline. + pub fn allow_local_timeline(&mut self, allow_local_timeline: bool) -> &mut Self { + self.request + .policies + .ltl_available + .replace(allow_local_timeline); + self + } + + /// Sets whether to allow users to post public note. + pub fn allow_public_note(&mut self, allow_public_note: bool) -> &mut Self { + self.request + .policies + .can_public_note + .replace(allow_public_note); + self + } + + /// Sets whether to allow users to create invitation code of the instance. + pub fn allow_invitation(&mut self, allow_invitation: bool) -> &mut Self { + self.request.policies.can_invite.replace(allow_invitation); + self + } + + /// Sets whether to allow users to manage custom emojis. + pub fn allow_custom_emojis_management( + &mut self, + allow_custom_emojis_management: bool, + ) -> &mut Self { + self.request + .policies + .can_manage_custom_emojis + .replace(allow_custom_emojis_management); + self + } + + /// Sets whether to allow users to hide ads. + pub fn allow_hiding_ads(&mut self, allow_hiding_ads: bool) -> &mut Self { + self.request.policies.can_hide_ads.replace(allow_hiding_ads); + self + } + + /// Sets the drive capacity per user in megabytes. + pub fn drive_capacity(&mut self, mb: u64) -> &mut Self { + self.request.policies.drive_capacity_mb.replace(mb); + self + } + + /// Sets the maximum number of pinned notes for the users. + pub fn pin_limit(&mut self, pin_limit: u64) -> &mut Self { + self.request.policies.pin_limit.replace(pin_limit); + self + } + + /// Sets the maximum number of antennas for the users. + pub fn antenna_limit(&mut self, antenna_limit: u64) -> &mut Self { + self.request.policies.antenna_limit.replace(antenna_limit); + self + } + + /// Sets the maximum number of characters in word mutes for the users. + pub fn word_mute_limit(&mut self, word_mute_limit: u64) -> &mut Self { + self.request + .policies + .word_mute_limit + .replace(word_mute_limit); + self + } + + /// Sets the maximum number of webhooks for the users. + pub fn webhook_limit(&mut self, webhook_limit: u64) -> &mut Self { + self.request.policies.webhook_limit.replace(webhook_limit); + self + } + + /// Sets the maximum number of clips for the users. + pub fn clip_limit(&mut self, clip_limit: u64) -> &mut Self { + self.request.policies.clip_limit.replace(clip_limit); + self + } + + /// Sets the maximum number of notes per clip for the users. + pub fn note_each_clips_limit(&mut self, note_each_clips_limit: u64) -> &mut Self { + self.request + .policies + .note_each_clips_limit + .replace(note_each_clips_limit); + self + } + + /// Sets the maximum number of user lists for the users. + pub fn user_list_limit(&mut self, user_list_limit: u64) -> &mut Self { + self.request + .policies + .user_list_limit + .replace(user_list_limit); + self + } + + /// Sets the maximum number of users per user list for the users. + pub fn user_each_user_lists_limit(&mut self, user_each_user_lists_limit: u64) -> &mut Self { + self.request + .policies + .user_each_user_lists_limit + .replace(user_each_user_lists_limit); + self + } + + /// Sets the rate limit factor of users. + pub fn rate_limit_factor(&mut self, rate_limit_factor: f64) -> &mut Self { + self.request + .policies + .rate_limit_factor + .replace(rate_limit_factor); + self + } +} + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +impl DefaultPoliciesUpdateBuilder { + /// Updates the default policies. + pub async fn update(&self) -> Result<(), Error> { + self.client + .request(&self.request) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + } +} diff --git a/misskey-util/src/builder/user.rs b/misskey-util/src/builder/user.rs index 1f8c95a8..a1203cde 100644 --- a/misskey-util/src/builder/user.rs +++ b/misskey-util/src/builder/user.rs @@ -78,6 +78,8 @@ impl UserListBuilder { } /// Limits the listed users to moderators. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub fn moderator(&mut self) -> &mut Self { self.request .state @@ -94,6 +96,8 @@ impl UserListBuilder { } /// Limits the listed users to admins. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub fn admin(&mut self) -> &mut Self { self.request .state @@ -102,6 +106,8 @@ impl UserListBuilder { } /// Limits the listed users to admins or moderators. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub fn admin_or_moderator(&mut self) -> &mut Self { self.request .state diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index 94e28f40..d19dd957 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -26,6 +26,8 @@ use crate::builder::{ use crate::builder::{ChannelBuilder, ChannelUpdateBuilder}; #[cfg(feature = "12-57-0")] use crate::builder::{ClipBuilder, ClipUpdateBuilder}; +#[cfg(feature = "13-0-0")] +use crate::builder::{DefaultPoliciesUpdateBuilder, RoleBuilder, RoleUpdateBuilder}; use crate::pager::{BackwardPager, BoxPager, ForwardPager, OffsetPager, PagerStream}; use crate::Error; use crate::{TimelineCursor, TimelineRange}; @@ -45,6 +47,8 @@ use misskey_api::model::gallery::GalleryPost; use misskey_api::model::meta::AdminMeta; #[cfg(feature = "12-67-0")] use misskey_api::model::registry::{RegistryKey, RegistryScope, RegistryValue}; +#[cfg(feature = "13-0-0")] +use misskey_api::model::role::{PoliciesSimple, Role}; #[cfg(feature = "12-93-0")] use misskey_api::model::user::UserOrigin; use misskey_api::model::{ @@ -981,11 +985,10 @@ pub trait ClientExt: Client + Sync { /// use futures::stream::TryStreamExt; /// use misskey::model::user::{User, UserSortKey}; /// - /// // Get a list of local moderator users sorted by number of followers. + /// // Get a list of local users sorted by number of followers. /// let users: Vec = client /// .users() /// .local() - /// .moderator() /// .sort_by_followers() /// .list() /// .try_collect() @@ -3783,6 +3786,8 @@ pub trait ClientExt: Client + Sync { /// Sets moderator privileges for the specified user. /// /// This operation may require this client to be logged in with an admin account. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] fn add_moderator( &self, user: impl EntityRef, @@ -3800,6 +3805,8 @@ pub trait ClientExt: Client + Sync { /// Removes moderator privileges for the specified user. /// /// This operation may require this client to be logged in with an admin account. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] fn remove_moderator( &self, user: impl EntityRef, @@ -3939,6 +3946,8 @@ pub trait ClientExt: Client + Sync { /// Silences the specified user. /// /// This operation may require moderator privileges. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] fn silence(&self, user: impl EntityRef) -> BoxFuture>> { let user_id = user.entity_ref(); Box::pin(async move { @@ -3967,6 +3976,8 @@ pub trait ClientExt: Client + Sync { /// Unsilences the specified user. /// /// This operation may require moderator privileges. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] fn unsilence(&self, user: impl EntityRef) -> BoxFuture>> { let user_id = user.entity_ref(); Box::pin(async move { @@ -3999,7 +4010,14 @@ pub trait ClientExt: Client + Sync { /// Finally, calling [`update`][builder_update] method will actually perform the update. /// See [`MetaUpdateBuilder`] for the fields that can be updated. /// - /// This operation may require this client to be logged in with an admin account. + #[cfg_attr( + not(feature = "13-0-0"), + doc = "This operation may require this client to be logged in with an admin account." + )] + #[cfg_attr( + feature = "13-0-0", + doc = "This operation may require administrator privileges." + )] /// /// [builder_update]: MetaUpdateBuilder::update /// @@ -4013,7 +4031,6 @@ pub trait ClientExt: Client + Sync { /// client /// .update_meta() /// .set_name("The Instance of Saturn") - /// .local_drive_capacity(5000) /// .update() /// .await?; /// # Ok(()) @@ -4107,7 +4124,14 @@ pub trait ClientExt: Client + Sync { /// Creates a custom emoji from the given file. /// - /// This operation may require moderator privileges. + #[cfg_attr( + not(feature = "13-0-0"), + doc = "This operation may require moderator privileges." + )] + #[cfg_attr( + feature = "13-0-0", + doc = "This operation may require `canManageCustomEmojis` policy." + )] #[cfg(feature = "12-9-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-9-0")))] fn create_emoji( @@ -4128,7 +4152,14 @@ pub trait ClientExt: Client + Sync { /// Deletes the specified emoji. /// - /// This operation may require moderator privileges. + #[cfg_attr( + not(feature = "13-0-0"), + doc = "This operation may require moderator privileges." + )] + #[cfg_attr( + feature = "13-0-0", + doc = "This operation may require `canManageCustomEmojis` policy." + )] fn delete_emoji( &self, emoji: impl EntityRef, @@ -4154,7 +4185,14 @@ pub trait ClientExt: Client + Sync { /// Finally, calling [`update`][builder_update] method will actually perform the update. /// See [`EmojiUpdateBuilder`] for the fields that can be updated. /// - /// This operation may require moderator privileges. + #[cfg_attr( + not(feature = "13-0-0"), + doc = "This operation may require moderator privileges." + )] + #[cfg_attr( + feature = "13-0-0", + doc = "This operation may require `canManageCustomEmojis` policy." + )] /// /// [builder_update]: EmojiUpdateBuilder::update #[cfg(feature = "12-9-0")] @@ -4165,7 +4203,14 @@ pub trait ClientExt: Client + Sync { /// Copies the specified emoji. /// - /// This operation may require moderator privileges. + #[cfg_attr( + not(feature = "13-0-0"), + doc = "This operation may require moderator privileges." + )] + #[cfg_attr( + feature = "13-0-0", + doc = "This operation may require `canManageCustomEmojis` policy." + )] fn copy_emoji( &self, emoji: impl EntityRef, @@ -4184,16 +4229,50 @@ pub trait ClientExt: Client + Sync { /// Lists the emojis in the instance. /// - /// This operation may require moderator privileges. - /// Use [`meta`][`ClientExt::meta`] method if you want to get a list of custom emojis from normal users, + #[cfg_attr( + not(feature = "13-0-0"), + doc = "This operation may require moderator privileges." + )] + #[cfg_attr( + feature = "13-0-0", + doc = "This operation may require `canManageCustomEmojis` policy." + )] + /// Use [`meta`][`ClientExt::meta`] method if you want to get a list of custom emojis from normal users. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] fn emojis(&self) -> PagerStream> { let pager = BackwardPager::new(self, endpoint::admin::emoji::list::Request::default()); PagerStream::new(Box::pin(pager)) } + /// Lists the emojis in the instance. + /// + #[cfg_attr( + not(feature = "13-0-0"), + doc = "This operation may require moderator privileges." + )] + #[cfg_attr( + feature = "13-0-0", + doc = "This operation may require `canManageCustomEmojis` policy." + )] + /// Use [`emojis`][`ClientExt::emojis`] method if you want to get a list of custom emojis from normal users. + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn admin_emojis(&self) -> PagerStream> { + let pager = BackwardPager::new(self, endpoint::admin::emoji::list::Request::default()); + PagerStream::new(Box::pin(pager)) + } + /// Searches the emojis using the given query string. /// - /// This operation may require moderator privileges. + #[cfg_attr( + not(feature = "13-0-0"), + doc = "This operation may require moderator privileges." + )] + #[cfg_attr( + feature = "13-0-0", + doc = "This operation may require `canManageCustomEmojis` policy." + )] #[cfg(feature = "12-48-0")] fn search_emojis(&self, query: impl Into) -> PagerStream> { let pager = BackwardPager::new( @@ -4272,7 +4351,7 @@ pub trait ClientExt: Client + Sync { /// Lists the ads in the instance. /// /// This operation may require moderator privileges. - /// Use [`meta`][`ClientExt::meta`] method if you want to get a list of ads from normal users, + /// Use [`meta`][`ClientExt::meta`] method if you want to get a list of ads from normal users. #[cfg(feature = "12-80-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-80-0")))] fn ads(&self) -> PagerStream> { @@ -4282,7 +4361,7 @@ pub trait ClientExt: Client + Sync { /// Gets detailed information about the instance. /// - /// This operation may require moderator privileges. + /// This operation may require administrator privileges. #[cfg(feature = "12-109-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-109-0")))] fn admin_meta(&self) -> BoxFuture>> { @@ -4295,6 +4374,248 @@ pub trait ClientExt: Client + Sync { Ok(meta) }) } + + /// Creates a role with the given name. + /// + /// This operation may require administrator privileges. + /// + /// # Examples + /// + /// ``` + /// # use misskey_util::ClientExt; + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let client = misskey_test::test_admin_client().await?; + /// let role = client.create_role("name").await?; + /// assert_eq!(role.name, "name"); + /// # Ok(()) + /// # } + /// ``` + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn create_role(&self, name: impl Into) -> BoxFuture>> { + let name = name.into(); + Box::pin(async move { self.build_role().name(name).create().await }) + } + + /// Returns a builder for creating a role. + /// + /// The returned builder provides methods to customize details of the role, + /// and you can chain them to create a role incrementally. + /// Finally, calling [`create`][builder_create] method will actually create a role. + /// See [`RoleBuilder`] for the provided methods. + /// + /// This operation may require administrator privileges. + /// + /// [builder_create]: RoleBuilder::create + /// + /// # Examples + /// + /// ``` + /// # use misskey_util::ClientExt; + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let client = misskey_test::test_admin_client().await?; + /// // Create a role whose members cannot post public notes. + /// let role = client + /// .build_role() + /// .name("Silence") + /// .allow_public_note(|mut builder| builder.value(false).use_default(false).build()) + /// .create() + /// .await?; + /// + /// assert_eq!(role.name, "Silence"); + /// # Ok(()) + /// # } + /// ``` + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn build_role(&self) -> RoleBuilder<&Self> { + RoleBuilder::new(self) + } + + /// Deletes the specified role. + /// + /// This operation may require administrator privileges. + /// + /// # Examples + /// + /// ``` + /// # use misskey_util::ClientExt; + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let client = misskey_test::test_admin_client().await?; + /// let role = client.create_role("role").await?; + /// client.delete_role(&role).await?; + /// # Ok(()) + /// # } + /// ``` + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn delete_role(&self, role: impl EntityRef) -> BoxFuture>> { + let role_id = role.entity_ref(); + Box::pin(async move { + self.request(endpoint::admin::roles::delete::Request { role_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + + /// Gets the corresponding role from the ID. + /// + /// This operation may require moderator privileges. + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn get_role(&self, id: Id) -> BoxFuture>> { + Box::pin(async move { + let role = self + .request(endpoint::admin::roles::show::Request { role_id: id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(role) + }) + } + + /// Updates the role. + /// + /// This method actually returns a builder, namely [`RoleUpdateBuilder`]. + /// You can chain the method calls to it corresponding to the fields you want to update. + /// Finally, calling [`update`][builder_update] method will actually perform the update. + /// See [`RoleUpdateBuilder`] for the fields that can be updated. + /// + /// This operation may require administrator privileges. + /// + /// [builder_update]: RoleUpdateBuilder::update + /// + /// # Examples + /// + /// ``` + /// # use misskey_util::ClientExt; + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let client = misskey_test::test_admin_client().await?; + /// let role = client + /// .create_role("role") + /// .await?; + /// + /// // Change description and rate limit factor of the role + /// client + /// .update_role(role) + /// .description("description") + /// .rate_limit_factor(|mut builder| builder.value(0.3).use_default(false).build()) + /// .update() + /// .await?; + /// # Ok(()) + /// # } + /// ``` + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn update_role(&self, role: Role) -> RoleUpdateBuilder<&Self> { + RoleUpdateBuilder::new(self, role) + } + + /// Assigns a user to the role. + /// + /// This operation may require moderator privileges. + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn assign_role( + &self, + role: impl EntityRef, + user: impl EntityRef, + ) -> BoxFuture>> { + let role_id = role.entity_ref(); + let user_id = user.entity_ref(); + Box::pin(async move { + self.request( + endpoint::admin::roles::assign::Request::builder() + .role_id(role_id) + .user_id(user_id) + .build(), + ) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + + /// Removes a user from the role. + /// + /// This operation may require moderator privileges. + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn unassign_role( + &self, + role: impl EntityRef, + user: impl EntityRef, + ) -> BoxFuture>> { + let role_id = role.entity_ref(); + let user_id = user.entity_ref(); + Box::pin(async move { + self.request(endpoint::admin::roles::unassign::Request { role_id, user_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + + /// Lists the roles of the instance. + /// + /// This operation may require moderator privileges. + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn roles(&self) -> BoxFuture, Error>> { + Box::pin(async move { + let roles = self + .request(endpoint::admin::roles::list::Request::default()) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(roles) + }) + } + + /// Updates the default policies of the instance. + /// + /// This method actually returns a builder, namely [`DefaultPoliciesUpdateBuilder`]. + /// You can chain the method calls to it corresponding to the fields you want to update. + /// Finally, calling [`update`][builder_update] method will actually perform the update. + /// See [`DefaultPoliciesUpdateBuilder`] for the fields that can be updated. + /// + /// This operation may require administrator privileges. + /// + /// [builder_update]: DefaultPoliciesUpdateBuilder::update + /// + /// # Examples + /// + /// ``` + /// # use misskey_util::ClientExt; + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let client = misskey_test::test_admin_client().await?; + /// let policies = client.admin_meta().await?.policies; + /// client + /// .update_default_policies(policies) + /// .allow_hiding_ads(true) + /// .drive_capacity(5000) + /// .update() + /// .await?; + /// # Ok(()) + /// # } + /// ``` + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn update_default_policies( + &self, + policies: PoliciesSimple, + ) -> DefaultPoliciesUpdateBuilder<&Self> { + DefaultPoliciesUpdateBuilder::new(self, policies) + } // }}} // {{{ Miscellaneous From deb431f72955989e9c8d512c7a10e0454795708d Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 3 May 2023 06:58:53 +0900 Subject: [PATCH 43/44] Add: Add flash related APIs --- misskey-api/CHANGELOG.md | 1 + misskey-api/src/endpoint.rs | 4 + misskey-api/src/endpoint/flash.rs | 9 + misskey-api/src/endpoint/flash/create.rs | 65 ++++++ misskey-api/src/endpoint/flash/delete.rs | 30 +++ misskey-api/src/endpoint/flash/featured.rs | 24 +++ misskey-api/src/endpoint/flash/like.rs | 31 +++ misskey-api/src/endpoint/flash/my.rs | 75 +++++++ misskey-api/src/endpoint/flash/my_likes.rs | 91 ++++++++ misskey-api/src/endpoint/flash/show.rs | 30 +++ misskey-api/src/endpoint/flash/unlike.rs | 35 ++++ misskey-api/src/endpoint/flash/update.rs | 83 ++++++++ misskey-api/src/model.rs | 1 + misskey-api/src/model/flash.rs | 31 +++ misskey-util/CHANGELOG.md | 1 + misskey-util/src/builder.rs | 7 + misskey-util/src/builder/flash.rs | 135 ++++++++++++ misskey-util/src/client.rs | 232 ++++++++++++++++++++- 18 files changed, 882 insertions(+), 3 deletions(-) create mode 100644 misskey-api/src/endpoint/flash.rs create mode 100644 misskey-api/src/endpoint/flash/create.rs create mode 100644 misskey-api/src/endpoint/flash/delete.rs create mode 100644 misskey-api/src/endpoint/flash/featured.rs create mode 100644 misskey-api/src/endpoint/flash/like.rs create mode 100644 misskey-api/src/endpoint/flash/my.rs create mode 100644 misskey-api/src/endpoint/flash/my_likes.rs create mode 100644 misskey-api/src/endpoint/flash/show.rs create mode 100644 misskey-api/src/endpoint/flash/unlike.rs create mode 100644 misskey-api/src/endpoint/flash/update.rs create mode 100644 misskey-api/src/model/flash.rs create mode 100644 misskey-util/src/builder/flash.rs diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index b8b9fca3..5080c6f5 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -78,6 +78,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v12.112.3 ~ v12.119.2 - Support for Misskey v13.0.0 - endpoint `admin/roles/*` + - endpoint `flash/*` ### Changed ### Deprecated diff --git a/misskey-api/src/endpoint.rs b/misskey-api/src/endpoint.rs index bf6fcf22..786cbfc8 100644 --- a/misskey-api/src/endpoint.rs +++ b/misskey-api/src/endpoint.rs @@ -90,3 +90,7 @@ pub mod email_address; #[cfg(any(not(feature = "12-106-0"), feature = "12-107-0"))] #[cfg_attr(docsrs, doc(cfg(any(not(feature = "12-106-0"), feature = "12-107-0"))))] pub mod stats; + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +pub mod flash; diff --git a/misskey-api/src/endpoint/flash.rs b/misskey-api/src/endpoint/flash.rs new file mode 100644 index 00000000..eb2d32f3 --- /dev/null +++ b/misskey-api/src/endpoint/flash.rs @@ -0,0 +1,9 @@ +pub mod create; +pub mod delete; +pub mod featured; +pub mod like; +pub mod my; +pub mod my_likes; +pub mod show; +pub mod unlike; +pub mod update; diff --git a/misskey-api/src/endpoint/flash/create.rs b/misskey-api/src/endpoint/flash/create.rs new file mode 100644 index 00000000..ffd15c97 --- /dev/null +++ b/misskey-api/src/endpoint/flash/create.rs @@ -0,0 +1,65 @@ +use crate::model::flash::Flash; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Default, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + #[builder(default, setter(into))] + pub title: String, + #[builder(default, setter(into))] + pub summary: String, + #[builder(default, setter(into))] + pub script: String, + #[builder(default, setter(into))] + pub permissions: Vec, +} + +impl misskey_core::Request for Request { + type Response = Flash; + const ENDPOINT: &'static str = "flash/create"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.test(Request::default()).await; + } + + #[tokio::test] + async fn request_with_options() { + let client = TestClient::new(); + client + .test(Request { + title: "play".to_string(), + summary: "summary".to_string(), + script: r#"/// @ 0.12.2 + + var name = "" + + Ui:render([ + Ui:C:textInput({ + label: "Your name" + onInput: @(v) { name = v } + }) + Ui:C:button({ + text: "Hello" + onClick: @() { + Mk:dialog(null `Hello, {name}!`) + } + }) + ]) + "# + .to_string(), + permissions: vec!["read:account".to_string()], + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/flash/delete.rs b/misskey-api/src/endpoint/flash/delete.rs new file mode 100644 index 00000000..1a0f6491 --- /dev/null +++ b/misskey-api/src/endpoint/flash/delete.rs @@ -0,0 +1,30 @@ +use crate::model::{flash::Flash, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub flash_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "flash/delete"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let flash = client + .test(crate::endpoint::flash::create::Request::default()) + .await; + + client.test(Request { flash_id: flash.id }).await; + } +} diff --git a/misskey-api/src/endpoint/flash/featured.rs b/misskey-api/src/endpoint/flash/featured.rs new file mode 100644 index 00000000..6ea31b00 --- /dev/null +++ b/misskey-api/src/endpoint/flash/featured.rs @@ -0,0 +1,24 @@ +use crate::model::flash::Flash; + +use serde::Serialize; + +#[derive(Serialize, Default, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request {} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "flash/featured"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.test(Request::default()).await; + } +} diff --git a/misskey-api/src/endpoint/flash/like.rs b/misskey-api/src/endpoint/flash/like.rs new file mode 100644 index 00000000..5e3eda1f --- /dev/null +++ b/misskey-api/src/endpoint/flash/like.rs @@ -0,0 +1,31 @@ +use crate::model::{flash::Flash, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub flash_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "flash/like"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let flash = client + .admin + .test(crate::endpoint::flash::create::Request::default()) + .await; + + client.user.test(Request { flash_id: flash.id }).await; + } +} diff --git a/misskey-api/src/endpoint/flash/my.rs b/misskey-api/src/endpoint/flash/my.rs new file mode 100644 index 00000000..b349a8d7 --- /dev/null +++ b/misskey-api/src/endpoint/flash/my.rs @@ -0,0 +1,75 @@ +use crate::model::{flash::Flash, id::Id}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Default, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + /// 1 .. 100 + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub since_id: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub until_id: Option>, +} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "flash/my"; +} + +impl_pagination!(Request, Flash); + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client + .test(crate::endpoint::flash::create::Request::default()) + .await; + + client.test(Request::default()).await; + } + + #[tokio::test] + async fn request_with_limit() { + let client = TestClient::new(); + client + .test(crate::endpoint::flash::create::Request::default()) + .await; + + client + .test(Request { + limit: Some(100), + since_id: None, + until_id: None, + }) + .await; + } + + #[tokio::test] + async fn request_paginate() { + let client = TestClient::new(); + let flash = client + .test(crate::endpoint::flash::create::Request::default()) + .await; + + client + .test(Request { + limit: None, + since_id: Some(flash.id), + until_id: Some(flash.id), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/flash/my_likes.rs b/misskey-api/src/endpoint/flash/my_likes.rs new file mode 100644 index 00000000..9269c5f2 --- /dev/null +++ b/misskey-api/src/endpoint/flash/my_likes.rs @@ -0,0 +1,91 @@ +use crate::model::{flash::FlashLike, id::Id}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Default, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + /// 1 .. 100 + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub limit: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub since_id: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub until_id: Option>, +} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "flash/my-likes"; +} + +impl_pagination!(Request, FlashLike); + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let flash = client + .admin + .test(crate::endpoint::flash::create::Request::default()) + .await; + client + .user + .test(crate::endpoint::flash::like::Request { flash_id: flash.id }) + .await; + + client.test(Request::default()).await; + } + + #[tokio::test] + async fn request_with_limit() { + let client = TestClient::new(); + let flash = client + .admin + .test(crate::endpoint::flash::create::Request::default()) + .await; + client + .user + .test(crate::endpoint::flash::like::Request { flash_id: flash.id }) + .await; + + client + .test(Request { + limit: Some(100), + since_id: None, + until_id: None, + }) + .await; + } + + #[tokio::test] + async fn request_paginate() { + let client = TestClient::new(); + let flash = client + .admin + .test(crate::endpoint::flash::create::Request::default()) + .await; + client + .user + .test(crate::endpoint::flash::like::Request { flash_id: flash.id }) + .await; + let likes = client.test(Request::default()).await; + + client + .test(Request { + limit: None, + since_id: Some(likes[0].id), + until_id: Some(likes[0].id), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/flash/show.rs b/misskey-api/src/endpoint/flash/show.rs new file mode 100644 index 00000000..c94b595b --- /dev/null +++ b/misskey-api/src/endpoint/flash/show.rs @@ -0,0 +1,30 @@ +use crate::model::{flash::Flash, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub flash_id: Id, +} + +impl misskey_core::Request for Request { + type Response = Flash; + const ENDPOINT: &'static str = "flash/show"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let flash = client + .test(crate::endpoint::flash::create::Request::default()) + .await; + + client.test(Request { flash_id: flash.id }).await; + } +} diff --git a/misskey-api/src/endpoint/flash/unlike.rs b/misskey-api/src/endpoint/flash/unlike.rs new file mode 100644 index 00000000..06b2c1ba --- /dev/null +++ b/misskey-api/src/endpoint/flash/unlike.rs @@ -0,0 +1,35 @@ +use crate::model::{flash::Flash, id::Id}; + +use serde::Serialize; + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request { + pub flash_id: Id, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "flash/unlike"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let flash = client + .admin + .test(crate::endpoint::flash::create::Request::default()) + .await; + client + .user + .test(crate::endpoint::flash::like::Request { flash_id: flash.id }) + .await; + + client.user.test(Request { flash_id: flash.id }).await; + } +} diff --git a/misskey-api/src/endpoint/flash/update.rs b/misskey-api/src/endpoint/flash/update.rs new file mode 100644 index 00000000..c42a2508 --- /dev/null +++ b/misskey-api/src/endpoint/flash/update.rs @@ -0,0 +1,83 @@ +use crate::model::{flash::Flash, id::Id}; + +use serde::Serialize; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + pub flash_id: Id, + #[builder(default, setter(into))] + pub title: String, + #[builder(default, setter(into))] + pub summary: String, + #[builder(default, setter(into))] + pub script: String, + #[builder(default, setter(into))] + pub permissions: Vec, +} + +impl misskey_core::Request for Request { + type Response = (); + const ENDPOINT: &'static str = "flash/update"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + let flash = client + .test(crate::endpoint::flash::create::Request::default()) + .await; + + client + .test(Request { + flash_id: flash.id, + title: String::new(), + summary: String::new(), + script: String::new(), + permissions: Vec::new(), + }) + .await; + } + + #[tokio::test] + async fn request_with_options() { + let client = TestClient::new(); + let flash = client + .test(crate::endpoint::flash::create::Request::default()) + .await; + + client + .test(Request { + flash_id: flash.id, + title: "play".to_string(), + summary: "summary".to_string(), + script: r#"/// @ 0.12.2 + + var name = "" + + Ui:render([ + Ui:C:textInput({ + label: "Your name" + onInput: @(v) { name = v } + }) + Ui:C:button({ + text: "Hello" + onClick: @() { + Mk:dialog(null `Hello, {name}!`) + } + }) + ]) + "# + .to_string(), + permissions: vec!["read:account".to_string()], + }) + .await; + } +} diff --git a/misskey-api/src/model.rs b/misskey-api/src/model.rs index c104c900..75b08f5c 100644 --- a/misskey-api/src/model.rs +++ b/misskey-api/src/model.rs @@ -26,6 +26,7 @@ pub mod chart; pub mod clip; pub mod drive; pub mod emoji; +pub mod flash; pub mod following; pub mod gallery; pub mod id; diff --git a/misskey-api/src/model/flash.rs b/misskey-api/src/model/flash.rs new file mode 100644 index 00000000..825f0a3e --- /dev/null +++ b/misskey-api/src/model/flash.rs @@ -0,0 +1,31 @@ +use crate::model::id::Id; +use crate::model::user::User; + +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Flash { + pub id: Id, + pub created_at: DateTime, + pub updated_at: DateTime, + pub user_id: Id, + pub user: User, + pub title: String, + pub summary: String, + pub script: String, + pub liked_count: u64, + pub is_liked: Option, +} + +impl_entity!(Flash); + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct FlashLike { + pub id: Id, + pub flash: Flash, +} + +impl_entity!(FlashLike); diff --git a/misskey-util/CHANGELOG.md b/misskey-util/CHANGELOG.md index 6a0823d2..4042d31a 100644 --- a/misskey-util/CHANGELOG.md +++ b/misskey-util/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Page APIs - Gallery APIs - Reactions APIs +- Play (Flash) APIs ### Changed ### Deprecated diff --git a/misskey-util/src/builder.rs b/misskey-util/src/builder.rs index 256d77e8..8fb2bc14 100644 --- a/misskey-util/src/builder.rs +++ b/misskey-util/src/builder.rs @@ -27,6 +27,9 @@ mod gallery; #[cfg(any(not(feature = "12-88-0"), feature = "12-89-0"))] mod user; +#[cfg(feature = "13-0-0")] +mod flash; + pub use admin::{AnnouncementUpdateBuilder, EmojiUpdateBuilder, MetaUpdateBuilder}; pub use antenna::{AntennaBuilder, AntennaUpdateBuilder}; pub use clip::{ClipBuilder, ClipUpdateBuilder}; @@ -75,3 +78,7 @@ pub use me::IntoUserFields; #[cfg(feature = "13-0-0")] #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] pub use admin::{DefaultPoliciesUpdateBuilder, RoleBuilder, RoleUpdateBuilder}; + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +pub use flash::{FlashBuilder, FlashUpdateBuilder}; diff --git a/misskey-util/src/builder/flash.rs b/misskey-util/src/builder/flash.rs new file mode 100644 index 00000000..205b5b92 --- /dev/null +++ b/misskey-util/src/builder/flash.rs @@ -0,0 +1,135 @@ +use crate::Error; + +use misskey_api::endpoint; +use misskey_api::model::flash::Flash; +use misskey_core::Client; + +/// Builder for the [`build_play`][`crate::ClientExt::build_play`] method. +pub struct FlashBuilder { + client: C, + request: endpoint::flash::create::Request, +} + +impl FlashBuilder { + /// Creates a builder with the client. + pub fn new(client: C) -> Self { + let request = endpoint::flash::create::Request::default(); + FlashBuilder { client, request } + } + + /// Gets the request object for reuse. + pub fn as_request(&self) -> &endpoint::flash::create::Request { + &self.request + } + + /// Sets the title of the Play. + pub fn title(&mut self, title: impl Into) -> &mut Self { + self.request.title = title.into(); + self + } + + /// Sets the summary of the Play. + pub fn summary(&mut self, summary: impl Into) -> &mut Self { + self.request.summary = summary.into(); + self + } + + /// Sets the script of the Play. + pub fn script(&mut self, script: impl Into) -> &mut Self { + self.request.script = script.into(); + self + } + + /// Sets the permissions of the Play. + pub fn permissions( + &mut self, + permissions: impl IntoIterator>, + ) -> &mut Self { + self.request.permissions = permissions.into_iter().map(Into::into).collect(); + self + } +} + +impl FlashBuilder { + /// Creates the Play. + pub async fn create(&self) -> Result> { + let flash = self + .client + .request(&self.request) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(flash) + } +} + +/// Builder for the [`update_play`][`crate::ClientExt::update_play`] method. +pub struct FlashUpdateBuilder { + client: C, + request: endpoint::flash::update::Request, +} + +impl FlashUpdateBuilder { + /// Creates a builder with the client and the Play you are going to update. + pub fn new(client: C, flash: Flash) -> Self { + let Flash { + id, + title, + summary, + script, + .. + } = flash; + let request = endpoint::flash::update::Request { + flash_id: id, + title, + summary, + script, + permissions: Vec::default(), + }; + FlashUpdateBuilder { client, request } + } + + /// Gets the request object for reuse. + pub fn as_request(&self) -> &endpoint::flash::update::Request { + &self.request + } + + /// Sets the title of the Play. + pub fn title(&mut self, title: impl Into) -> &mut Self { + self.request.title = title.into(); + self + } + + /// Sets the summary of the Play. + pub fn summary(&mut self, summary: impl Into) -> &mut Self { + self.request.summary = summary.into(); + self + } + + /// Sets the script of the Play. + pub fn script(&mut self, script: impl Into) -> &mut Self { + self.request.script = script.into(); + self + } + + /// Sets the permissions of the Play. + pub fn permissions( + &mut self, + permissions: impl IntoIterator>, + ) -> &mut Self { + self.request.permissions = permissions.into_iter().map(Into::into).collect(); + self + } +} + +impl FlashUpdateBuilder { + /// Updates the Play. + pub async fn update(&self) -> Result<(), Error> { + self.client + .request(&self.request) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + } +} diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index d19dd957..82c94c53 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -27,7 +27,9 @@ use crate::builder::{ChannelBuilder, ChannelUpdateBuilder}; #[cfg(feature = "12-57-0")] use crate::builder::{ClipBuilder, ClipUpdateBuilder}; #[cfg(feature = "13-0-0")] -use crate::builder::{DefaultPoliciesUpdateBuilder, RoleBuilder, RoleUpdateBuilder}; +use crate::builder::{ + DefaultPoliciesUpdateBuilder, FlashBuilder, FlashUpdateBuilder, RoleBuilder, RoleUpdateBuilder, +}; use crate::pager::{BackwardPager, BoxPager, ForwardPager, OffsetPager, PagerStream}; use crate::Error; use crate::{TimelineCursor, TimelineRange}; @@ -47,8 +49,6 @@ use misskey_api::model::gallery::GalleryPost; use misskey_api::model::meta::AdminMeta; #[cfg(feature = "12-67-0")] use misskey_api::model::registry::{RegistryKey, RegistryScope, RegistryValue}; -#[cfg(feature = "13-0-0")] -use misskey_api::model::role::{PoliciesSimple, Role}; #[cfg(feature = "12-93-0")] use misskey_api::model::user::UserOrigin; use misskey_api::model::{ @@ -72,6 +72,11 @@ use misskey_api::model::{ user_group::{UserGroup, UserGroupInvitation}, user_list::UserList, }; +#[cfg(feature = "13-0-0")] +use misskey_api::model::{ + flash::Flash, + role::{PoliciesSimple, Role}, +}; use misskey_api::{endpoint, EntityRef}; use misskey_core::{Client, UploadFileClient}; use url::Url; @@ -3782,6 +3787,227 @@ pub trait ClientExt: Client + Sync { } // }}} + // {{{ Play + /// Creates a Play with the given title and files. + /// + /// # Examples + /// + /// ``` + /// # use misskey_util::ClientExt; + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let client = misskey_test::test_client().await?; + /// // Create a Play that says "Hello World!" + /// let script = r#"/// @ 0.12.2 + /// Ui:render([ + /// Ui:C:text({ text: "Hello, World!" }) + /// ])"#; + /// let play = client.create_play("My Play", script).await?; + /// + /// assert_eq!(play.title, "My Play"); + /// # Ok(()) + /// # } + /// ``` + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn create_play( + &self, + title: impl Into, + script: impl Into, + ) -> BoxFuture>> { + let title = title.into(); + let script = script.into(); + Box::pin(async move { + let flash = self + .request(endpoint::flash::create::Request { + title, + summary: String::new(), + script, + permissions: Vec::new(), + }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(flash) + }) + } + + /// Returns a builder for creating a Play. + /// + /// The returned builder provides methods to customize details of the Play, + /// and you can chain them to create a Play incrementally. + /// Finally, calling [`create`][builder_create] method will actually create a post. + /// See [`FlashBuilder`] for the provided methods. + /// + /// [builder_create]: FlashBuilder::create + /// + /// # Examples + /// + /// ``` + /// # use misskey_util::ClientExt; + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let client = misskey_test::test_client().await?; + /// let script = r#"/// @ 0.12.2 + /// Ui:render([ + /// Ui:C:text({ text: "Hello, World!" }) + /// ])"#; + /// let play = client + /// .build_play() + /// .title("title") + /// .summary("summary") + /// .script(script) + /// .create() + /// .await?; + /// + /// assert_eq!(play.title, "title"); + /// # Ok(()) + /// # } + /// ``` + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn build_play(&self) -> FlashBuilder<&Self> { + FlashBuilder::new(self) + } + + /// Deletes the specified Play. + /// + /// # Examples + /// + /// ``` + /// # use misskey_util::ClientExt; + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let client = misskey_test::test_client().await?; + /// let play = client.create_play("My Play", "").await?; + /// client.delete_play(&play).await?; + /// # Ok(()) + /// # } + /// ``` + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn delete_play( + &self, + play: impl EntityRef, + ) -> BoxFuture>> { + let flash_id = play.entity_ref(); + Box::pin(async move { + self.request(endpoint::flash::delete::Request { flash_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + + /// Gets the corresponding Play from the ID. + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn get_play(&self, id: Id) -> BoxFuture>> { + Box::pin(async move { + let flash = self + .request(endpoint::flash::show::Request { flash_id: id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(flash) + }) + } + + /// Updates the Play. + /// + /// This method actually returns a builder, namely [`FlashUpdateBuilder`]. + /// You can chain the method calls to it corresponding to the fields you want to update. + /// Finally, calling [`update`][builder_update] method will actually perform the update. + /// See [`FlashUpdateBuilder`] for the fields that can be updated. + /// + /// [builder_update]: FlashUpdateBuilder::update + /// + /// # Examples + /// + /// ``` + /// # use misskey_util::ClientExt; + /// # #[tokio::main] + /// # async fn main() -> anyhow::Result<()> { + /// # let client = misskey_test::test_client().await?; + /// let play = client.create_play("My Play", "").await?; + /// client + /// .update_play(play) + /// .summary("summary") + /// .update() + /// .await?; + /// # Ok(()) + /// # } + /// ``` + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn update_play(&self, play: Flash) -> FlashUpdateBuilder<&Self> { + FlashUpdateBuilder::new(self, play) + } + + /// Gives a like to the specified Play. + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn like_play(&self, play: impl EntityRef) -> BoxFuture>> { + let flash_id = play.entity_ref(); + Box::pin(async move { + self.request(endpoint::flash::like::Request { flash_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + + /// Removes a like from the specified Play. + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn unlike_play( + &self, + play: impl EntityRef, + ) -> BoxFuture>> { + let flash_id = play.entity_ref(); + Box::pin(async move { + self.request(endpoint::flash::unlike::Request { flash_id }) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(()) + }) + } + + /// Lists the Plays created by the user logged in with this client. + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn plays(&self) -> PagerStream> { + let pager = BackwardPager::new(self, endpoint::flash::my::Request::default()); + PagerStream::new(Box::pin(pager)) + } + + /// Lists the Plays liked by the user logged in with this client. + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn liked_plays(&self) -> PagerStream> { + let pager = BackwardPager::new(self, endpoint::flash::my_likes::Request::default()) + .map_ok(|v| v.into_iter().map(|l| l.flash).collect()); + PagerStream::new(Box::pin(pager)) + } + + /// Lists the featured Plays. + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn featured_plays(&self) -> BoxFuture, Error>> { + Box::pin(async move { + let flashes = self + .request(endpoint::flash::featured::Request::default()) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(flashes) + }) + } + // }}} + // {{{ Admin /// Sets moderator privileges for the specified user. /// From 2d2306749eb04b82e81c661beb3326f4e109f247 Mon Sep 17 00:00:00 2001 From: poppingmoon <63451158+poppingmoon@users.noreply.github.com> Date: Wed, 3 May 2023 07:22:54 +0900 Subject: [PATCH 44/44] Add: Support v13.0.0 --- .github/workflows/ci.yml | 4 +- .github/workflows/flaky.yml | 2 + .github/workflows/unstable.yml | 4 +- misskey-api/CHANGELOG.md | 6 +- misskey-api/src/endpoint.rs | 12 +++ misskey-api/src/endpoint/admin.rs | 5 +- .../src/endpoint/admin/get_table_stats.rs | 2 +- misskey-api/src/endpoint/admin/show_users.rs | 41 +++++++- misskey-api/src/endpoint/admin/update_meta.rs | 21 ++++ misskey-api/src/endpoint/charts/user.rs | 4 + misskey-api/src/endpoint/charts/user/pv.rs | 99 +++++++++++++++++++ misskey-api/src/endpoint/emojis.rs | 29 ++++++ .../src/endpoint/following/requests/list.rs | 83 +++++++++++++++- misskey-api/src/endpoint/i/update.rs | 8 +- misskey-api/src/endpoint/invite.rs | 28 ++++++ misskey-api/src/endpoint/notes.rs | 5 +- misskey-api/src/endpoint/notes/state.rs | 2 + misskey-api/src/endpoint/retention.rs | 24 +++++ misskey-api/src/endpoint/users/stats.rs | 6 ++ misskey-api/src/model.rs | 1 + misskey-api/src/model/antenna.rs | 3 + misskey-api/src/model/chart.rs | 9 ++ misskey-api/src/model/emoji.rs | 13 +++ misskey-api/src/model/meta.rs | 45 ++++++++- misskey-api/src/model/note.rs | 5 + misskey-api/src/model/retention.rs | 12 +++ misskey-api/src/model/user.rs | 43 ++++++++ misskey-util/src/builder/me.rs | 8 +- misskey-util/src/client.rs | 31 +++++- misskey/src/lib.rs | 1 + 30 files changed, 527 insertions(+), 29 deletions(-) create mode 100644 misskey-api/src/endpoint/charts/user/pv.rs create mode 100644 misskey-api/src/endpoint/emojis.rs create mode 100644 misskey-api/src/endpoint/invite.rs create mode 100644 misskey-api/src/endpoint/retention.rs create mode 100644 misskey-api/src/model/retention.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b18c3b7..5eaca482 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.112.3' + MISSKEY_IMAGE: 'misskey/misskey:13.0.0' MISSKEY_ID: aid - - run: cargo test --features 12-112-3 + - run: cargo test --features 13-0-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/.github/workflows/flaky.yml b/.github/workflows/flaky.yml index 74953f98..a9395e90 100644 --- a/.github/workflows/flaky.yml +++ b/.github/workflows/flaky.yml @@ -12,6 +12,8 @@ jobs: strategy: matrix: include: + - image: 'misskey/misskey:13.0.0' + flags: --features 13-0-0 - image: 'misskey/misskey:12.112.3' flags: --features 12-112-3 - image: 'misskey/misskey:12.112.2' diff --git a/.github/workflows/unstable.yml b/.github/workflows/unstable.yml index cf9b6aa4..85267a1c 100644 --- a/.github/workflows/unstable.yml +++ b/.github/workflows/unstable.yml @@ -28,9 +28,9 @@ jobs: - id: setup_env run: ./ci/testenv/setup.sh env: - MISSKEY_IMAGE: 'misskey/misskey:12.112.3' + MISSKEY_IMAGE: 'misskey/misskey:13.0.0' MISSKEY_ID: aid - - run: cargo test --features 12-112-3 + - run: cargo test --features 13-0-0 timeout-minutes: 15 env: TEST_API_URL: http://localhost:3000/api/ diff --git a/misskey-api/CHANGELOG.md b/misskey-api/CHANGELOG.md index 5080c6f5..5044d640 100644 --- a/misskey-api/CHANGELOG.md +++ b/misskey-api/CHANGELOG.md @@ -79,6 +79,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for Misskey v13.0.0 - endpoint `admin/roles/*` - endpoint `flash/*` + - endpoint `emojis` + - endpoint `invite` + - endpoint `retention` + - endpoint `charts/user/pv` ### Changed ### Deprecated @@ -101,7 +105,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - For Misskey v12.106.0 ~ v12.106.3 - endpoint `email-address/available` - For Misskey v12.108.0 ~ v12.108.1 -- endpoint `admin/invite`, `admin/moderators/*`, `admin/silence_user`, `admin/unsilence_user` +- endpoint `admin/invite`, `admin/moderators/*`, `admin/silence_user`, `admin/unsilence_user`, `admin/vaccum`, `notes/watching/*` - For Misskey v13.0.0 ~ ### Fixed diff --git a/misskey-api/src/endpoint.rs b/misskey-api/src/endpoint.rs index 786cbfc8..a686f7b0 100644 --- a/misskey-api/src/endpoint.rs +++ b/misskey-api/src/endpoint.rs @@ -91,6 +91,18 @@ pub mod email_address; #[cfg_attr(docsrs, doc(cfg(any(not(feature = "12-106-0"), feature = "12-107-0"))))] pub mod stats; +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +pub mod emojis; + #[cfg(feature = "13-0-0")] #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] pub mod flash; + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +pub mod invite; + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +pub mod retention; diff --git a/misskey-api/src/endpoint/admin.rs b/misskey-api/src/endpoint/admin.rs index de4ffcb0..0003fa27 100644 --- a/misskey-api/src/endpoint/admin.rs +++ b/misskey-api/src/endpoint/admin.rs @@ -11,7 +11,6 @@ pub mod show_users; pub mod suspend_user; pub mod unsuspend_user; pub mod update_meta; -pub mod vacuum; #[cfg(feature = "12-13-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-13-0")))] @@ -84,3 +83,7 @@ pub mod silence_user; #[cfg(not(feature = "13-0-0"))] #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub mod unsilence_user; + +#[cfg(not(feature = "13-0-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] +pub mod vacuum; diff --git a/misskey-api/src/endpoint/admin/get_table_stats.rs b/misskey-api/src/endpoint/admin/get_table_stats.rs index 97bfac35..dc6b5583 100644 --- a/misskey-api/src/endpoint/admin/get_table_stats.rs +++ b/misskey-api/src/endpoint/admin/get_table_stats.rs @@ -9,7 +9,7 @@ pub struct Request {} #[derive(Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct Stat { - pub count: u64, + pub count: i64, pub size: u64, } diff --git a/misskey-api/src/endpoint/admin/show_users.rs b/misskey-api/src/endpoint/admin/show_users.rs index 14fd5bf5..e206d8da 100644 --- a/misskey-api/src/endpoint/admin/show_users.rs +++ b/misskey-api/src/endpoint/admin/show_users.rs @@ -1,6 +1,10 @@ +#[cfg(feature = "13-0-0")] +use crate::model::user::AdminUserSortKey; +#[cfg(not(feature = "13-0-0"))] +use crate::model::user::UserSortKey; use crate::model::{ sort::SortOrder, - user::{User, UserOrigin, UserSortKey}, + user::{User, UserOrigin}, }; use serde::Serialize; @@ -58,9 +62,16 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub offset: Option, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub sort: Option>, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub sort: Option>, #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub state: Option, @@ -153,7 +164,11 @@ mod tests { #[tokio::test] async fn request_with_sort() { - use crate::model::{sort::SortOrder, user::UserSortKey}; + use crate::model::sort::SortOrder; + #[cfg(feature = "13-0-0")] + use crate::model::user::AdminUserSortKey; + #[cfg(not(feature = "13-0-0"))] + use crate::model::user::UserSortKey; let client = TestClient::new(); @@ -162,7 +177,10 @@ mod tests { .test(Request { limit: None, offset: None, + #[cfg(not(feature = "13-0-0"))] sort: Some(SortOrder::Ascending(UserSortKey::Follower)), + #[cfg(feature = "13-0-0")] + sort: Some(SortOrder::Ascending(AdminUserSortKey::Follower)), state: None, origin: None, #[cfg(not(feature = "12-108-0"))] @@ -180,7 +198,10 @@ mod tests { .test(Request { limit: None, offset: None, + #[cfg(not(feature = "13-0-0"))] sort: Some(SortOrder::Ascending(UserSortKey::CreatedAt)), + #[cfg(feature = "13-0-0")] + sort: Some(SortOrder::Ascending(AdminUserSortKey::CreatedAt)), state: None, origin: None, #[cfg(not(feature = "12-108-0"))] @@ -198,7 +219,10 @@ mod tests { .test(Request { limit: None, offset: None, + #[cfg(not(feature = "13-0-0"))] sort: Some(SortOrder::Descending(UserSortKey::UpdatedAt)), + #[cfg(feature = "13-0-0")] + sort: Some(SortOrder::Descending(AdminUserSortKey::UpdatedAt)), state: None, origin: None, #[cfg(not(feature = "12-108-0"))] @@ -211,6 +235,19 @@ mod tests { hostname: String::new(), }) .await; + #[cfg(feature = "13-0-0")] + client + .admin + .test(Request { + limit: None, + offset: None, + sort: Some(SortOrder::Descending(AdminUserSortKey::LastActiveDate)), + state: None, + origin: None, + username: String::new(), + hostname: String::new(), + }) + .await; } #[tokio::test] diff --git a/misskey-api/src/endpoint/admin/update_meta.rs b/misskey-api/src/endpoint/admin/update_meta.rs index 6d701b3a..1fca1dc6 100644 --- a/misskey-api/src/endpoint/admin/update_meta.rs +++ b/misskey-api/src/endpoint/admin/update_meta.rs @@ -132,6 +132,21 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub recaptcha_secret_key: Option>, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub enable_turnstile: Option, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub turnstile_site_key: Option>, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub turnstile_secret_key: Option>, #[cfg(feature = "12-112-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] #[serde(skip_serializing_if = "Option::is_none")] @@ -389,6 +404,12 @@ mod tests { enable_recaptcha: Some(false), recaptcha_site_key: Some(None), recaptcha_secret_key: Some(None), + #[cfg(feature = "13-0-0")] + enable_turnstile: Some(false), + #[cfg(feature = "13-0-0")] + turnstile_site_key: Some(None), + #[cfg(feature = "13-0-0")] + turnstile_secret_key: Some(None), #[cfg(feature = "12-112-0")] sensitive_media_detection: Some(SensitiveMediaDetection::None), #[cfg(feature = "12-112-0")] diff --git a/misskey-api/src/endpoint/charts/user.rs b/misskey-api/src/endpoint/charts/user.rs index 641ec14d..d7b9c082 100644 --- a/misskey-api/src/endpoint/charts/user.rs +++ b/misskey-api/src/endpoint/charts/user.rs @@ -2,3 +2,7 @@ pub mod drive; pub mod following; pub mod notes; pub mod reactions; + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +pub mod pv; diff --git a/misskey-api/src/endpoint/charts/user/pv.rs b/misskey-api/src/endpoint/charts/user/pv.rs new file mode 100644 index 00000000..23980ea2 --- /dev/null +++ b/misskey-api/src/endpoint/charts/user/pv.rs @@ -0,0 +1,99 @@ +use crate::model::{ + chart::{ChartSpan, PerUserPvChart}, + id::Id, + user::User, +}; + +use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; + +#[derive(Serialize, Debug, Clone, TypedBuilder)] +#[serde(rename_all = "camelCase")] +#[builder(doc)] +pub struct Request { + pub span: ChartSpan, + pub user_id: Id, + /// 1 .. 500 + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub limit: Option, + #[builder(default, setter(strip_option))] + pub offset: Option, +} + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Response { + pub upv: PerUserPvChart, + pub pv: PerUserPvChart, +} + +impl misskey_core::Request for Request { + type Response = Response; + const ENDPOINT: &'static str = "charts/user/pv"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + use crate::model::chart::ChartSpan; + + let client = TestClient::new(); + let user = client.user.me().await; + + client + .test(Request { + span: ChartSpan::Day, + user_id: user.id.clone(), + limit: None, + offset: None, + }) + .await; + client + .test(Request { + span: ChartSpan::Hour, + user_id: user.id.clone(), + limit: None, + offset: None, + }) + .await; + } + + #[tokio::test] + async fn request_with_limit() { + use crate::model::chart::ChartSpan; + + let client = TestClient::new(); + let user = client.user.me().await; + + client + .test(Request { + span: ChartSpan::Day, + user_id: user.id, + limit: Some(500), + offset: None, + }) + .await; + } + + #[tokio::test] + async fn request_with_offset() { + use crate::model::chart::ChartSpan; + + let client = TestClient::new(); + let user = client.user.me().await; + + client + .test(Request { + span: ChartSpan::Day, + user_id: user.id, + limit: None, + offset: Some(5), + }) + .await; + } +} diff --git a/misskey-api/src/endpoint/emojis.rs b/misskey-api/src/endpoint/emojis.rs new file mode 100644 index 00000000..22df2c3f --- /dev/null +++ b/misskey-api/src/endpoint/emojis.rs @@ -0,0 +1,29 @@ +use serde::{Deserialize, Serialize}; + +use crate::model::emoji::EmojiSimple; + +#[derive(Serialize, Default, Debug, Clone)] +pub struct Request {} + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Response { + pub emojis: Vec, +} + +impl misskey_core::Request for Request { + type Response = Response; + const ENDPOINT: &'static str = "emojis"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.test(Request::default()).await; + } +} diff --git a/misskey-api/src/endpoint/following/requests/list.rs b/misskey-api/src/endpoint/following/requests/list.rs index bcc19886..7d71eef9 100644 --- a/misskey-api/src/endpoint/following/requests/list.rs +++ b/misskey-api/src/endpoint/following/requests/list.rs @@ -1,10 +1,30 @@ use crate::model::following::FollowRequest; +#[cfg(feature = "13-0-0")] +use crate::model::id::Id; use serde::Serialize; +use typed_builder::TypedBuilder; -#[derive(Serialize, Default, Debug, Clone)] +#[derive(Serialize, Default, Debug, Clone, TypedBuilder)] #[serde(rename_all = "camelCase")] -pub struct Request {} +pub struct Request { + /// 1 .. 100 + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub limit: Option, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub since_id: Option>, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + #[serde(skip_serializing_if = "Option::is_none")] + #[builder(default, setter(strip_option))] + pub until_id: Option>, +} impl misskey_core::Request for Request { type Response = Vec; @@ -37,4 +57,63 @@ mod tests { new_client.test(Request::default()).await; } + + #[cfg(feature = "13-0-0")] + #[tokio::test] + async fn request_with_limit() { + let client = TestClient::new(); + let (new_user, new_client) = client.admin.create_user().await; + + new_client + .test( + crate::endpoint::i::update::Request::builder() + .is_locked(true) + .build(), + ) + .await; + client + .user + .test(crate::endpoint::following::create::Request { + user_id: new_user.id, + }) + .await; + + client + .test(Request { + limit: Some(100), + since_id: None, + until_id: None, + }) + .await; + } + + #[cfg(feature = "13-0-0")] + #[tokio::test] + async fn request_paginate() { + let client = TestClient::new(); + let (new_user, new_client) = client.admin.create_user().await; + + new_client + .test( + crate::endpoint::i::update::Request::builder() + .is_locked(true) + .build(), + ) + .await; + client + .user + .test(crate::endpoint::following::create::Request { + user_id: new_user.id, + }) + .await; + let requests = new_client.test(Request::default()).await; + + new_client + .test(Request { + limit: None, + since_id: Some(requests[0].id.clone()), + until_id: Some(requests[0].id.clone()), + }) + .await; + } } diff --git a/misskey-api/src/endpoint/i/update.rs b/misskey-api/src/endpoint/i/update.rs index 083771d8..3b7e9d75 100644 --- a/misskey-api/src/endpoint/i/update.rs +++ b/misskey-api/src/endpoint/i/update.rs @@ -108,13 +108,13 @@ pub struct Request { #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub ff_visibility: Option, - #[cfg(not(feature = "12-108-0"))] - #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] + #[cfg(any(not(feature = "12-108-0"), feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(any(not(feature = "12-108-0"), feature = "13-0-0"))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub pinned_page_id: Option>>, - #[cfg(feature = "12-108-0")] - #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + #[cfg(all(feature = "12-108-0", not(feature = "13-0-0")))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "12-108-0", not(feature = "13-0-0")))))] #[serde(skip_serializing_if = "Option::is_none")] #[builder(default, setter(strip_option))] pub pinned_page_id: Option>>, diff --git a/misskey-api/src/endpoint/invite.rs b/misskey-api/src/endpoint/invite.rs new file mode 100644 index 00000000..e018f731 --- /dev/null +++ b/misskey-api/src/endpoint/invite.rs @@ -0,0 +1,28 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Default, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request {} + +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Response { + pub code: String, +} + +impl misskey_core::Request for Request { + type Response = Response; + const ENDPOINT: &'static str = "invite"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.admin.test(Request::default()).await; + } +} diff --git a/misskey-api/src/endpoint/notes.rs b/misskey-api/src/endpoint/notes.rs index f5de3790..1ee151f2 100644 --- a/misskey-api/src/endpoint/notes.rs +++ b/misskey-api/src/endpoint/notes.rs @@ -24,7 +24,6 @@ pub mod state; pub mod timeline; pub mod unrenote; pub mod user_list_timeline; -pub mod watching; #[cfg(feature = "12-58-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-58-0")))] @@ -34,6 +33,10 @@ pub mod clips; #[cfg_attr(docsrs, doc(cfg(feature = "12-95-0")))] pub mod thread_muting; +#[cfg(not(feature = "13-0-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] +pub mod watching; + #[derive(Serialize, Default, Debug, Clone, TypedBuilder)] #[serde(rename_all = "camelCase")] #[builder(doc)] diff --git a/misskey-api/src/endpoint/notes/state.rs b/misskey-api/src/endpoint/notes/state.rs index 21923bea..eb7552c2 100644 --- a/misskey-api/src/endpoint/notes/state.rs +++ b/misskey-api/src/endpoint/notes/state.rs @@ -12,6 +12,8 @@ pub struct Request { #[serde(rename_all = "camelCase")] pub struct Response { pub is_favorited: bool, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub is_watching: bool, #[cfg(feature = "12-95-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-95-0")))] diff --git a/misskey-api/src/endpoint/retention.rs b/misskey-api/src/endpoint/retention.rs new file mode 100644 index 00000000..7379698f --- /dev/null +++ b/misskey-api/src/endpoint/retention.rs @@ -0,0 +1,24 @@ +use serde::Serialize; + +use crate::model::retention::Retention; + +#[derive(Serialize, Default, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Request {} + +impl misskey_core::Request for Request { + type Response = Vec; + const ENDPOINT: &'static str = "retention"; +} + +#[cfg(test)] +mod tests { + use super::Request; + use crate::test::{ClientExt, TestClient}; + + #[tokio::test] + async fn request() { + let client = TestClient::new(); + client.admin.test(Request::default()).await; + } +} diff --git a/misskey-api/src/endpoint/users/stats.rs b/misskey-api/src/endpoint/users/stats.rs index 8fce15ce..5103f2c1 100644 --- a/misskey-api/src/endpoint/users/stats.rs +++ b/misskey-api/src/endpoint/users/stats.rs @@ -24,7 +24,13 @@ pub struct UserStats { pub page_likes_count: u64, pub page_liked_count: u64, pub drive_files_count: u64, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub drive_usage: u64, + // https://github.com/misskey-dev/misskey/blob/13.0.0/packages/backend/src/core/entities/DriveFileEntityService.ts#L108 + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + pub drive_usage: Option, #[cfg(not(feature = "12-102-0"))] #[cfg_attr(docsrs, doc(cfg(not(feature = "12-102-0"))))] pub reversi_count: u64, diff --git a/misskey-api/src/model.rs b/misskey-api/src/model.rs index 75b08f5c..2a4c887e 100644 --- a/misskey-api/src/model.rs +++ b/misskey-api/src/model.rs @@ -41,6 +41,7 @@ pub mod notification; pub mod page; pub mod query; pub mod registry; +pub mod retention; pub mod role; pub mod signin; pub mod sort; diff --git a/misskey-api/src/model/antenna.rs b/misskey-api/src/model/antenna.rs index bdcb37bf..379ba6b3 100644 --- a/misskey-api/src/model/antenna.rs +++ b/misskey-api/src/model/antenna.rs @@ -26,6 +26,9 @@ pub struct Antenna { pub notify: bool, pub with_file: bool, pub with_replies: bool, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + pub has_unread_note: bool, } impl_entity!(Antenna); diff --git a/misskey-api/src/model/chart.rs b/misskey-api/src/model/chart.rs index 94e77bfe..6da51434 100644 --- a/misskey-api/src/model/chart.rs +++ b/misskey-api/src/model/chart.rs @@ -226,3 +226,12 @@ pub struct ApRequestChart { pub deliver_succeeded: Vec, pub inbox_received: Vec, } + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct PerUserPvChart { + pub user: Vec, + pub visitor: Vec, +} diff --git a/misskey-api/src/model/emoji.rs b/misskey-api/src/model/emoji.rs index 907deae7..195f5e2f 100644 --- a/misskey-api/src/model/emoji.rs +++ b/misskey-api/src/model/emoji.rs @@ -1,6 +1,7 @@ use crate::model::id::Id; use serde::{Deserialize, Serialize}; +#[cfg(not(feature = "13-0-0"))] use url::Url; #[derive(Serialize, Deserialize, Debug, Clone)] @@ -8,6 +9,8 @@ use url::Url; pub struct Emoji { pub id: Id, pub name: String, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub url: Url, pub host: Option, pub category: Option, @@ -15,3 +18,13 @@ pub struct Emoji { } impl_entity!(Emoji); + +#[cfg(feature = "13-0-0")] +#[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] +#[derive(Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct EmojiSimple { + pub name: String, + pub aliases: Vec, + pub category: Option, +} diff --git a/misskey-api/src/model/meta.rs b/misskey-api/src/model/meta.rs index f83307da..571838a2 100644 --- a/misskey-api/src/model/meta.rs +++ b/misskey-api/src/model/meta.rs @@ -5,9 +5,11 @@ use std::fmt::{self, Display}; use crate::model::ad::{Ad, Place}; #[cfg(feature = "12-62-0")] use crate::model::clip::Clip; +#[cfg(not(feature = "13-0-0"))] +use crate::model::emoji::Emoji; #[cfg(feature = "13-0-0")] use crate::model::role::PoliciesSimple; -use crate::model::{emoji::Emoji, id::Id, user::User}; +use crate::model::{id::Id, user::User}; use serde::{Deserialize, Serialize}; #[cfg(feature = "12-112-0")] @@ -35,10 +37,6 @@ pub struct Meta { pub feedback_url: Option, #[cfg(not(feature = "12-108-0"))] pub secure: bool, - #[cfg(feature = "12-108-0")] - pub default_dark_theme: Option, - #[cfg(feature = "12-108-0")] - pub default_light_theme: Option, pub disable_registration: bool, #[cfg(not(feature = "13-0-0"))] #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] @@ -73,6 +71,12 @@ pub struct Meta { pub hcaptcha_site_key: Option, pub enable_recaptcha: bool, pub recaptcha_site_key: Option, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + pub enable_turnstile: bool, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + pub turnstile_site_key: Option, #[serde(rename = "swPublickey")] pub sw_public_key: Option, #[cfg(feature = "12-105-0")] @@ -89,8 +93,16 @@ pub struct Meta { #[cfg_attr(docsrs, doc(cfg(feature = "12-60-0")))] pub logo_image_url: Option, pub max_note_text_length: u64, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] #[serde(default)] pub emojis: Vec, + #[cfg(feature = "12-108-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + pub default_dark_theme: Option, + #[cfg(feature = "12-108-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + pub default_light_theme: Option, #[cfg(feature = "12-81-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-81-0")))] #[serde(default)] @@ -218,15 +230,29 @@ pub struct AdminMeta { pub repository_url: Url, pub feedback_url: Option, pub disable_registration: bool, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub disable_local_timeline: bool, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub disable_global_timeline: bool, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub drive_capacity_per_local_user_mb: u64, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub drive_capacity_per_remote_user_mb: u64, pub email_required_for_signup: bool, pub enable_hcaptcha: bool, pub hcaptcha_site_key: Option, pub enable_recaptcha: bool, pub recaptcha_site_key: Option, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + pub enable_turnstile: bool, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + pub turnstile_site_key: Option, #[serde(rename = "swPublickey")] pub sw_public_key: Option, pub theme_color: Option, @@ -254,6 +280,9 @@ pub struct AdminMeta { pub blocked_hosts: Vec, pub hcaptcha_secret_key: Option, pub recaptcha_secret_key: Option, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + pub turnstile_secret_key: Option, #[cfg(feature = "12-112-0")] #[cfg_attr(docsrs, doc(cfg(feature = "12-112-0")))] pub sensitive_media_detection: Option, @@ -303,6 +332,9 @@ pub struct AdminMeta { #[cfg(feature = "12-112-3")] #[cfg_attr(docsrs, doc(cfg(feature = "12-112-3")))] pub enable_active_email_validation: bool, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + pub policies: PoliciesSimple, } #[derive(Deserialize, Serialize, Debug, Clone)] @@ -323,6 +355,9 @@ pub struct FeaturesMeta { #[cfg_attr(docsrs, doc(cfg(feature = "12-37-0")))] pub hcaptcha: bool, pub recaptcha: bool, + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + pub turnstile: bool, pub object_storage: bool, pub twitter: bool, pub github: bool, diff --git a/misskey-api/src/model/note.rs b/misskey-api/src/model/note.rs index 35d791d8..9a078156 100644 --- a/misskey-api/src/model/note.rs +++ b/misskey-api/src/model/note.rs @@ -7,6 +7,7 @@ use crate::model::{channel::Channel, drive::DriveFile, id::Id, user::User}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use thiserror::Error; +#[cfg(not(feature = "13-0-0"))] use url::Url; #[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Hash, Debug)] @@ -105,6 +106,8 @@ pub struct Poll { } // packed `Emoji` for `Note` +#[cfg(not(feature = "13-0-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] #[derive(Serialize, Deserialize, Debug, Clone)] pub struct NoteEmoji { pub name: String, @@ -156,6 +159,8 @@ pub struct Note { #[serde(default)] pub poll: Option, pub reactions: HashMap, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub emojis: Vec, pub renote_count: u64, pub replies_count: u64, diff --git a/misskey-api/src/model/retention.rs b/misskey-api/src/model/retention.rs new file mode 100644 index 00000000..47051089 --- /dev/null +++ b/misskey-api/src/model/retention.rs @@ -0,0 +1,12 @@ +use std::collections::HashMap; + +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize, Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub struct Retention { + pub created_at: DateTime, + pub users: u64, + pub data: HashMap, +} diff --git a/misskey-api/src/model/user.rs b/misskey-api/src/model/user.rs index 39d730f8..1c308334 100644 --- a/misskey-api/src/model/user.rs +++ b/misskey-api/src/model/user.rs @@ -18,6 +18,8 @@ pub struct UserField { pub value: String, } +#[cfg(not(feature = "13-0-0"))] +#[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] // packed `Emoji` for `User` #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] @@ -173,6 +175,8 @@ pub struct User { #[cfg(not(feature = "12-42-0"))] #[cfg_attr(docsrs, doc(cfg(not(feature = "12-42-0"))))] pub banner_color: Option, + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] pub emojis: Option>, pub host: Option, #[serde(default)] @@ -314,6 +318,45 @@ impl std::str::FromStr for UserSortKey { } } +#[derive(PartialEq, Eq, Clone, Debug, Copy)] +pub enum AdminUserSortKey { + Follower, + CreatedAt, + UpdatedAt, + LastActiveDate, +} + +impl Display for AdminUserSortKey { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + AdminUserSortKey::Follower => f.write_str("follower"), + AdminUserSortKey::CreatedAt => f.write_str("createdAt"), + AdminUserSortKey::UpdatedAt => f.write_str("updatedAt"), + AdminUserSortKey::LastActiveDate => f.write_str("lastActiveDate"), + } + } +} + +#[derive(Debug, Error, Clone)] +#[error("invalid sort key")] +pub struct ParseAdminUserSortKeyError { + _priv: (), +} + +impl std::str::FromStr for AdminUserSortKey { + type Err = ParseAdminUserSortKeyError; + + fn from_str(s: &str) -> Result { + match s { + "follower" | "Follower" => Ok(AdminUserSortKey::Follower), + "createdAt" | "CreatedAt" => Ok(AdminUserSortKey::CreatedAt), + "updatedAt" | "UpdatedAt" => Ok(AdminUserSortKey::UpdatedAt), + "lastActiveDate" | "LastActiveDate" => Ok(AdminUserSortKey::LastActiveDate), + _ => Err(ParseAdminUserSortKeyError { _priv: () }), + } + } +} + #[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, Copy)] #[serde(rename_all = "camelCase")] pub enum UserOrigin { diff --git a/misskey-util/src/builder/me.rs b/misskey-util/src/builder/me.rs index fff10e8e..9f37ed95 100644 --- a/misskey-util/src/builder/me.rs +++ b/misskey-util/src/builder/me.rs @@ -103,14 +103,14 @@ impl MeUpdateBuilder { pub avatar: impl EntityRef { avatar_id = avatar.entity_ref() }; pub banner: impl EntityRef { banner_id = banner.entity_ref() }; #[doc_name = "pinned page"] - #[cfg(not(feature = "12-108-0"))] - #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] + #[cfg(any(not(feature = "12-108-0"), feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(any(not(feature = "12-108-0"), feature = "13-0-0"))))] pub pinned_page: impl EntityRef { pinned_page_id = pinned_page.entity_ref() }; } /// Sets the pinned page. - #[cfg(feature = "12-108-0")] - #[cfg_attr(docsrs, doc(cfg(feature = "12-108-0")))] + #[cfg(all(feature = "12-108-0", not(feature = "13-0-0")))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "12-108-0", not(feature = "13-0-0")))))] pub fn pinned_page( &mut self, pinned_page: impl IntoIterator>, diff --git a/misskey-util/src/client.rs b/misskey-util/src/client.rs index 82c94c53..f653e648 100644 --- a/misskey-util/src/client.rs +++ b/misskey-util/src/client.rs @@ -74,6 +74,7 @@ use misskey_api::model::{ }; #[cfg(feature = "13-0-0")] use misskey_api::model::{ + emoji::EmojiSimple, flash::Flash, role::{PoliciesSimple, Role}, }; @@ -1263,6 +1264,8 @@ pub trait ClientExt: Client + Sync { } /// Watches the specified note. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] fn watch(&self, note: impl EntityRef) -> BoxFuture>> { let note_id = note.entity_ref(); Box::pin(async move { @@ -1275,6 +1278,8 @@ pub trait ClientExt: Client + Sync { } /// Unwatches the specified note. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] fn unwatch(&self, note: impl EntityRef) -> BoxFuture>> { let note_id = note.entity_ref(); Box::pin(async move { @@ -1334,6 +1339,8 @@ pub trait ClientExt: Client + Sync { } /// Checks if the specified note is watched by the user logged in with this client. + #[cfg(not(feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(not(feature = "13-0-0"))))] fn is_watched( &self, note: impl EntityRef, @@ -3369,16 +3376,16 @@ pub trait ClientExt: Client + Sync { } /// Pins the specified page to the profile. - #[cfg(not(feature = "12-108-0"))] - #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] + #[cfg(any(not(feature = "12-108-0"), feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(any(not(feature = "12-108-0"), feature = "13-0-0"))))] fn pin_page(&self, page: impl EntityRef) -> BoxFuture>> { let page_id = page.entity_ref(); Box::pin(async move { self.update_me().set_pinned_page(page_id).update().await }) } /// Unpins the page from the profile. - #[cfg(not(feature = "12-108-0"))] - #[cfg_attr(docsrs, doc(cfg(not(feature = "12-108-0"))))] + #[cfg(any(not(feature = "12-108-0"), feature = "13-0-0"))] + #[cfg_attr(docsrs, doc(cfg(any(not(feature = "12-108-0"), feature = "13-0-0"))))] fn unpin_page(&self) -> BoxFuture>> { Box::pin(async move { self.update_me().delete_pinned_page().update().await }) } @@ -4916,6 +4923,22 @@ pub trait ClientExt: Client + Sync { fn build_notification(&self) -> NotificationBuilder<&Self> { NotificationBuilder::new(self) } + + /// Lists the emojis in the instance. + /// + /// Use [`admin_emojis`][`ClientExt::admin_emojis`] method if you want to get a list of custom emojis with details. + #[cfg(feature = "13-0-0")] + #[cfg_attr(docsrs, doc(cfg(feature = "13-0-0")))] + fn emojis(&self) -> BoxFuture, Error>> { + Box::pin(async move { + let response = self + .request(endpoint::emojis::Request::default()) + .await + .map_err(Error::Client)? + .into_result()?; + Ok(response.emojis) + }) + } // }}} } diff --git a/misskey/src/lib.rs b/misskey/src/lib.rs index bc31fb59..9e4a621d 100644 --- a/misskey/src/lib.rs +++ b/misskey/src/lib.rs @@ -106,6 +106,7 @@ //! //! | Feature | Supported Misskey versions (inclusive) | Tested Misskey version | //! | -------------------------- | -------------------------------------- | ---------------------- | +//! | `13-0-0` | v13.0.0 | v13.0.0 | //! | `12-112-3` | v12.112.3 ~ v12.119.2 | v12.112.3 | //! | `12-112-0` | v12.112.0 ~ v12.112.2 | v12.112.2 | //! | `12-111-0` | v12.111.0 ~ v12.111.1 | v12.111.0 |