bpi_rs/video_ranking/
popular.rs1use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
2use serde::{ Deserialize, Serialize };
3
4#[derive(Debug, Clone, Deserialize, Serialize)]
8pub struct PopularListData {
9 pub list: Vec<serde_json::Value>, pub no_more: bool,
13}
14
15#[derive(Debug, Clone, Deserialize, Serialize)]
19pub struct PopularSeriesItem {
20 pub number: u32,
22 pub subject: String,
24 pub status: u8,
26 pub name: String,
28}
29
30#[derive(Debug, Clone, Deserialize, Serialize)]
32pub struct PopularSeriesListData {
33 pub list: Vec<PopularSeriesItem>,
35}
36
37#[derive(Debug, Clone, Deserialize, Serialize)]
41pub struct PopularSeriesConfig {
42 pub id: u64,
44 #[serde(rename = "type")]
46 pub type_name: String,
47 pub number: u32,
49 pub subject: String,
51 pub stime: u64,
53 pub etime: u64,
55 pub status: u8,
57 pub name: String,
59 pub label: String,
61 pub hint: String,
63 pub color: u32,
65 pub cover: String,
67 pub share_title: String,
69 pub share_subtitle: String,
71 pub media_id: u64,
73}
74
75#[derive(Debug, Clone, Deserialize, Serialize)]
77pub struct PopularSeriesOneData {
78 pub config: PopularSeriesConfig,
80 pub reminder: Option<String>,
82 pub list: Vec<serde_json::Value>,
84}
85
86impl BpiClient {
87 pub async fn video_popular_list(
98 &self,
99 pn: Option<u32>,
100 ps: Option<u32>
101 ) -> Result<BpiResponse<PopularListData>, BpiError> {
102 let mut request = self.get("https://api.bilibili.com/x/web-interface/popular");
103
104 if let Some(pn) = pn {
105 request = request.query(&[("pn", pn)]);
106 }
107 if let Some(ps) = ps {
108 request = request.query(&[("ps", ps)]);
109 }
110
111 request.send_bpi("获取当前热门视频列表").await
112 }
113
114 pub async fn video_popular_series_list(
120 &self
121 ) -> Result<BpiResponse<PopularSeriesListData>, BpiError> {
122 self
123 .get("https://api.bilibili.com/x/web-interface/popular/series/list")
124 .send_bpi("获取每周必看全部列表").await
125 }
126
127 pub async fn video_popular_series_one(
137 &self,
138 number: u32
139 ) -> Result<BpiResponse<PopularSeriesOneData>, BpiError> {
140 self
141 .get("https://api.bilibili.com/x/web-interface/popular/series/one")
142 .query(&[("number", number)])
143 .send_bpi("获取每周必看选期详细信息").await
144 }
145}
146
147#[cfg(test)]
148mod tests {
149 use super::*;
150 use tracing::info;
151
152 #[tokio::test]
153 async fn test_video_popular_list() {
154 let bpi = BpiClient::new();
155 let resp = bpi.video_popular_list(Some(1), Some(2)).await;
156
157 info!("{:?}", resp);
158 assert!(resp.is_ok());
159
160 let resp_data = resp.unwrap();
161 info!("code: {}", resp_data.code);
162 if let Some(data) = resp_data.data {
163 info!("no_more: {}", data.no_more);
164 info!("first item: {:?}", data.list.first());
165 }
166 }
167
168 #[tokio::test]
169 async fn test_video_popular_series_list() {
170 let bpi = BpiClient::new();
171 let resp = bpi.video_popular_series_list().await;
172
173 info!("{:?}", resp);
174 assert!(resp.is_ok());
175
176 let resp_data = resp.unwrap();
177 info!("code: {}", resp_data.code);
178 if let Some(data) = resp_data.data {
179 info!("first series: {:?}", data.list.first());
180 }
181 }
182
183 #[tokio::test]
184 async fn test_video_popular_series_one() {
185 let bpi = BpiClient::new();
186 let resp = bpi.video_popular_series_one(1).await;
187
188 info!("{:?}", resp);
189 assert!(resp.is_ok());
190
191 let resp_data = resp.unwrap();
192 info!("code: {}", resp_data.code);
193 if let Some(data) = resp_data.data {
194 info!("config: {:?}", data.config);
195 info!("first video: {:?}", data.list.first());
196 }
197 }
198}