1use crate::{BilibiliRequest, BpiClient, BpiError, BpiResponse};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Deserialize, Serialize)]
6pub struct NoteListArchiveData {
7 #[serde(rename = "noteIds")]
9 pub note_ids: Option<Vec<String>>,
10}
11
12#[derive(Debug, Clone, Deserialize, Serialize)]
16pub struct PrivateNoteArc {
17 pub oid: u64,
18 pub status: u8,
19 pub oid_type: u8,
20 pub aid: u64,
21
22 pub bvid: Option<String>,
24 pub pic: Option<String>,
25 pub desc: Option<String>,
26}
27
28#[derive(Debug, Clone, Deserialize, Serialize)]
30pub struct PrivateNoteItem {
31 pub title: String,
32 pub summary: String,
33 pub mtime: String,
34 pub arc: PrivateNoteArc,
35 pub note_id: u64,
36 pub audit_status: u8,
37 pub web_url: String,
38 pub note_id_str: String,
39 pub message: String,
40 pub forbid_note_entrance: Option<bool>,
41 pub likes: u64,
42 pub has_like: bool,
43}
44
45#[derive(Debug, Clone, Deserialize, Serialize)]
47pub struct PrivateNoteListData {
48 pub list: Option<Vec<PrivateNoteItem>>,
49 pub page: Option<NotePage>,
50}
51
52#[derive(Debug, Clone, Deserialize, Serialize)]
56pub struct PublicNoteAuthor {
57 pub mid: u64,
58 pub name: String,
59 pub face: String,
60 pub level: u8,
61 pub vip_info: serde_json::Value,
62 pub pendant: serde_json::Value,
63}
64
65#[derive(Debug, Clone, Deserialize, Serialize)]
67pub struct PublicNoteItem {
68 pub cvid: u64,
69 pub title: String,
70 pub summary: String,
71 pub pubtime: String,
72 pub web_url: String,
73 pub message: String,
74 pub author: PublicNoteAuthor,
75 pub likes: u64,
76 pub has_like: bool,
77}
78
79#[derive(Debug, Clone, Deserialize, Serialize)]
81pub struct NotePage {
82 pub total: u32,
83 pub size: u32,
84 pub num: u32,
85}
86
87#[derive(Debug, Clone, Deserialize, Serialize)]
89pub struct PublicNoteListArchiveData {
90 pub list: Option<Vec<PublicNoteItem>>,
91 pub page: Option<NotePage>,
92 pub show_public_note: bool,
93 pub message: String,
94}
95
96#[derive(Debug, Clone, Deserialize, Serialize)]
100pub struct PublicNoteListUserData {
101 pub list: Option<Vec<PublicNoteItem>>,
102 pub page: Option<NotePage>,
103}
104
105impl BpiClient {
106 pub async fn note_list_archive(
113 &self,
114 oid: u64,
115 ) -> Result<BpiResponse<NoteListArchiveData>, BpiError> {
116 self.get("https://api.bilibili.com/x/note/list/archive")
117 .query(&[("oid", oid), ("oid_type", 0)])
118 .send_bpi("查询稿件私有笔记")
119 .await
120 }
121
122 pub async fn note_list_user_private(
133 &self,
134 pn: u32,
135 ps: u32,
136 ) -> Result<BpiResponse<PrivateNoteListData>, BpiError> {
137 self.get("https://api.bilibili.com/x/note/list")
138 .query(&[("pn", pn), ("ps", ps)])
139 .send_bpi("查询用户私有笔记")
140 .await
141 }
142
143 pub async fn note_list_public_archive(
155 &self,
156 oid: u64,
157 pn: u32,
158 ps: u32,
159 ) -> Result<BpiResponse<PublicNoteListArchiveData>, BpiError> {
160 self.get("https://api.bilibili.com/x/note/publish/list/archive")
161 .query(&[
162 ("oid", oid.to_string()),
163 ("oid_type", 0.to_string()),
164 ("pn", pn.to_string()),
165 ("ps", ps.to_string()),
166 ])
167 .send_bpi("查询稿件公开笔记")
168 .await
169 }
170
171 pub async fn note_list_public_user(
182 &self,
183 pn: u32,
184 ps: u32,
185 ) -> Result<BpiResponse<PublicNoteListUserData>, BpiError> {
186 self.get("https://api.bilibili.com/x/note/publish/list/user")
187 .query(&[("pn", pn), ("ps", ps)])
188 .send_bpi("查询用户公开笔记")
189 .await
190 }
191}
192
193#[cfg(test)]
194mod tests {
195 use super::*;
196 use tracing::info;
197
198 #[tokio::test]
199 async fn test_note_list_archive() {
200 let bpi = BpiClient::new();
201 let oid = 676931260;
203 let resp = bpi.note_list_archive(oid).await;
204
205 info!("{:?}", resp);
206 assert!(resp.is_ok());
207
208 let resp_data = resp.unwrap();
209 info!("code: {}", resp_data.code);
210 if let Some(data) = resp_data.data {
211 info!("note ids: {:?}", data.note_ids);
212 }
213 }
214
215 #[tokio::test]
216 async fn test_note_list_user_private() {
217 let bpi = BpiClient::new();
218 let resp = bpi.note_list_user_private(1, 10).await;
219
220 info!("{:?}", resp);
221 assert!(resp.is_ok());
222
223 let resp_data = resp.unwrap();
224 resp_data
225 .data
226 .as_ref()
227 .and_then(|data| data.list.as_ref())
228 .and_then(|list| {
229 info!("first note item: {:?}", list.first());
230 Some(())
231 });
232 }
233
234 #[tokio::test]
235 async fn test_note_list_public_archive() {
236 let bpi = BpiClient::new();
237 let oid = 338677252;
239 let resp = bpi.note_list_public_archive(oid, 1, 10).await;
240
241 info!("{:?}", resp);
242 assert!(resp.is_ok());
243
244 let resp_data = resp.unwrap();
245 info!("code: {}", resp_data.code);
246 if let Some(data) = resp_data.data {
247 info!("show_public_note: {}", data.show_public_note);
248 }
249 }
250
251 #[tokio::test]
252 async fn test_note_list_public_user() {
253 let bpi = BpiClient::new();
254 let resp = bpi.note_list_public_user(1, 10).await;
255
256 info!("{:?}", resp);
257 assert!(resp.is_ok());
258
259 let resp_data = resp.unwrap();
260 info!("code: {}", resp_data.code);
261 if let Some(data) = resp_data.data {
262 info!("total public notes: {}", data.page.as_ref().unwrap().total);
263 }
264 }
265}