bpi_rs/creativecenter/season/
section.rs1use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
6use serde::{ Deserialize, Serialize };
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct SeasonSectionEpisodesData {
11 pub section: SeasonSectionInfo,
12 pub episodes: Option<Vec<SeasonSectionEpisode>>,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
17#[serde(rename_all = "camelCase")]
18pub struct SeasonSectionInfo {
19 pub id: u64,
20 #[serde(rename = "type")]
21 pub section_type: u32,
22 #[serde(rename = "seasonId")]
23 pub season_id: i64,
24 pub title: String,
25 pub order: i64,
26 pub state: i64,
27 pub part_state: i64,
28 pub reject_reason: String,
29 pub ctime: i64,
30 pub mtime: i64,
31 pub ep_count: i64,
32 pub cover: String,
33 #[serde(rename = "has_charging_pay")]
34 pub has_charging_pay: i64,
35 #[serde(rename = "Episodes")]
36 pub episodes: serde_json::Value,
37 pub show: i64,
38 #[serde(rename = "has_pugv_pay")]
39 pub has_pugv_pay: i64,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct SeasonSectionEpisode {
45 pub id: u64,
46 pub title: String,
47 pub aid: u64,
48 pub bvid: String,
49 pub cid: u64,
50 #[serde(rename = "seasonId")]
51 pub season_id: u64,
52 #[serde(rename = "sectionId")]
53 pub section_id: u64,
54 pub order: u32,
55 #[serde(rename = "videoTitle")]
56 pub video_title: Option<String>,
57 #[serde(rename = "archiveTitle")]
58 pub archive_title: Option<String>,
59 #[serde(rename = "archiveState")]
60 pub archive_state: i32,
61 #[serde(rename = "rejectReason")]
62 pub reject_reason: Option<String>,
63 pub state: u32,
64 pub cover: String,
65 #[serde(rename = "is_free")]
66 pub is_free: u32,
67 #[serde(rename = "aid_owner")]
68 pub aid_owner: bool,
69 #[serde(rename = "charging_pay")]
70 pub charging_pay: u32,
71}
72
73impl BpiClient {
74 pub async fn season_section_episodes(
86 &self,
87 season_id: u64
88 ) -> Result<BpiResponse<SeasonSectionEpisodesData>, BpiError> {
89 self
90 .get("https://member.bilibili.com/x2/creative/web/season/section")
91 .query(&[("id", season_id.to_string())])
92 .send_bpi("获取合集小节中的视频").await
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[tokio::test]
101 async fn test_get_season_section_episodes() -> Result<(), Box<BpiError>> {
102 let bpi = BpiClient::new();
103
104 let season_id = 176088;
105 let data = bpi.season_section_episodes(season_id).await?.into_data()?;
106
107 tracing::info!("小节: {} - {}", data.section.id, data.section.title);
108 if let Some(episodes) = data.episodes {
109 for ep in episodes {
110 tracing::info!("视频: {} - {} (aid={})", ep.id, ep.title, ep.aid);
111 break;
112 }
113 }
114
115 Ok(())
116 }
117}