1use serde::{Deserialize, Serialize};
2
3use crate::{BilibiliRequest, BpiClient, BpiError, BpiResponse};
4
5#[derive(Debug, Serialize, Clone, Deserialize)]
6pub struct FollowUpLiveItem {
7 pub roomid: i64,
9 pub uid: i64,
11 pub uname: String,
13 pub title: String,
15 pub face: String,
17 pub live_status: i32,
19 pub record_live_time: i64,
21 pub area_name_v2: String,
23 pub room_news: String,
25 pub text_small: String,
27 pub room_cover: String,
29 pub parent_area_id: i32,
31 pub area_id: i32,
33}
34
35#[derive(Debug, Serialize, Clone, Deserialize)]
36pub struct FollowUpLiveData {
37 pub title: String,
39
40 #[serde(rename = "pageSize")]
42 pub page_size: i32,
43
44 #[serde(rename = "totalPage")]
46 pub total_page: i32,
47
48 pub list: Vec<FollowUpLiveItem>,
50
51 pub count: i32,
53
54 pub never_lived_count: i32,
56
57 pub live_count: i32,
59
60 pub never_lived_faces: Vec<String>,
62}
63
64#[derive(Debug, Serialize, Clone, Deserialize)]
65pub struct LiveRoom {
66 pub title: String,
68 pub room_id: i64,
70 pub uid: i64,
72 pub online: i32,
74 pub live_time: i64,
76 pub live_status: i32,
78 pub short_id: i32,
80 pub area: i32,
82 pub area_name: String,
84 pub area_v2_id: i32,
86 pub area_v2_name: String,
88 pub area_v2_parent_name: String,
90 pub area_v2_parent_id: i32,
92 pub uname: String,
94 pub face: String,
96 pub tag_name: String,
98 pub tags: String,
100 pub cover_from_user: String,
102 pub keyframe: String,
104 pub lock_till: String,
106 pub hidden_till: String,
108 pub broadcast_type: i32,
110 pub is_encrypt: bool,
112 pub link: String,
114 pub nickname: String,
116 pub roomname: String,
118 pub roomid: i64,
120}
121
122#[derive(Debug, Serialize, Clone, Deserialize)]
123pub struct LiveWebListData {
124 pub rooms: Vec<LiveRoom>,
126 pub list: Vec<LiveRoom>,
128 pub count: i32,
130 pub not_living_num: i32,
132}
133
134impl BpiClient {
135 pub async fn live_follow_up_list(
140 &self,
141 page: Option<i32>,
142 page_size: Option<i32>,
143 ignore_record: Option<i32>,
144 hit_ab: Option<bool>,
145 ) -> Result<BpiResponse<FollowUpLiveData>, BpiError> {
146 let mut query = Vec::new();
147
148 if let Some(page) = page {
149 query.push(("page", page.to_string()));
150 }
151
152 if let Some(page_size) = page_size {
153 query.push(("page_size", page_size.to_string()));
154 }
155
156 if let Some(ignore_record) = ignore_record {
157 query.push(("ignoreRecord", ignore_record.to_string()));
158 }
159
160 if let Some(hit_ab) = hit_ab {
161 query.push(("hit_ab", hit_ab.to_string()));
162 }
163
164 self.get("https://api.live.bilibili.com/xlive/web-ucenter/user/following")
165 .query(&query)
166 .send_bpi("获取用户关注的所有UP的直播情况")
167 .await
168 }
169
170 pub async fn live_follow_up_web_list(
175 &self,
176 hit_ab: Option<bool>,
177 ) -> Result<BpiResponse<LiveWebListData>, BpiError> {
178 let mut query = Vec::new();
179
180 if let Some(hit_ab) = hit_ab {
181 query.push(("hit_ab", hit_ab.to_string()));
182 }
183
184 self.get("https://api.live.bilibili.com/xlive/web-ucenter/v1/xfetter/GetWebList")
185 .query(&query)
186 .send_bpi("获取用户关注的所有UP且正在直播的列表")
187 .await
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use super::*;
194
195 #[tokio::test]
196 async fn test_get_follow_up_live_list() {
197 let bpi = BpiClient::new();
198 let resp = bpi
199 .live_follow_up_list(Some(1), Some(2), Some(1), Some(true))
200 .await
201 .unwrap();
202 tracing::info!("{:?}", resp);
203 }
204
205 #[tokio::test]
206 async fn test_get_follow_up_live_web_list() {
207 let bpi = BpiClient::new();
208 let resp = bpi.live_follow_up_web_list(Some(false)).await.unwrap();
209 tracing::info!("{:?}", resp);
210 }
211}