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(
97 &self,
98 pn: Option<u32>,
99 ps: Option<u32>,
100 ) -> Result<BpiResponse<PopularListData>, BpiError> {
101 let mut request = self.get("https://api.bilibili.com/x/web-interface/popular");
102
103 if let Some(pn) = pn {
104 request = request.query(&[("pn", pn)]);
105 }
106 if let Some(ps) = ps {
107 request = request.query(&[("ps", ps)]);
108 }
109
110 request.send_bpi("获取当前热门视频列表").await
111 }
112
113 pub async fn video_popular_series_list(
118 &self,
119 ) -> Result<BpiResponse<PopularSeriesListData>, BpiError> {
120 self.get("https://api.bilibili.com/x/web-interface/popular/series/list")
121 .send_bpi("获取每周必看全部列表")
122 .await
123 }
124
125 pub async fn video_popular_series_one(
134 &self,
135 number: u32,
136 ) -> Result<BpiResponse<PopularSeriesOneData>, BpiError> {
137 self.get("https://api.bilibili.com/x/web-interface/popular/series/one")
138 .query(&[("number", number)])
139 .send_bpi("获取每周必看选期详细信息")
140 .await
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147 use tracing::info;
148
149 #[tokio::test]
150 async fn test_video_popular_list() {
151 let bpi = BpiClient::new();
152 let resp = bpi.video_popular_list(Some(1), Some(2)).await;
153
154 info!("{:?}", resp);
155 assert!(resp.is_ok());
156
157 let resp_data = resp.unwrap();
158 info!("code: {}", resp_data.code);
159 if let Some(data) = resp_data.data {
160 info!("no_more: {}", data.no_more);
161 info!("first item: {:?}", data.list.first());
162 }
163 }
164
165 #[tokio::test]
166 async fn test_video_popular_series_list() {
167 let bpi = BpiClient::new();
168 let resp = bpi.video_popular_series_list().await;
169
170 info!("{:?}", resp);
171 assert!(resp.is_ok());
172
173 let resp_data = resp.unwrap();
174 info!("code: {}", resp_data.code);
175 if let Some(data) = resp_data.data {
176 info!("first series: {:?}", data.list.first());
177 }
178 }
179
180 #[tokio::test]
181 async fn test_video_popular_series_one() {
182 let bpi = BpiClient::new();
183 let resp = bpi.video_popular_series_one(1).await;
184
185 info!("{:?}", resp);
186 assert!(resp.is_ok());
187
188 let resp_data = resp.unwrap();
189 info!("code: {}", resp_data.code);
190 if let Some(data) = resp_data.data {
191 info!("config: {:?}", data.config);
192 info!("first video: {:?}", data.list.first());
193 }
194 }
195}