Skip to main content

bpi_rs/bangumi/
info.rs

1//! 番剧基本信息
2//!
3//! [查看 API 文档](https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/bangumi/info.md)
4use crate::models::VipLabel;
5use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
6use serde::{ Deserialize, Serialize };
7
8/// 剧集地区
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum BangumiArea {
11    /// 中国大陆
12    MainlandChina = 1,
13    /// 日本
14    Japan = 2,
15    /// 美国
16    UnitedStates = 3,
17    /// 英国
18    UnitedKingdom = 4,
19    /// 加拿大
20    Canada = 5,
21    /// 中国香港
22    HongKong = 6,
23    /// 中国台湾
24    Taiwan = 7,
25    /// 韩国
26    SouthKorea = 8,
27    /// 法国
28    France = 9,
29    /// 泰国
30    Thailand = 10,
31    /// 马来西亚
32    Malaysia = 11,
33    /// 新加坡
34    Singapore = 12,
35    /// 西班牙
36    Spain = 13,
37    /// 俄罗斯
38    Russia = 14,
39    /// 德国
40    Germany = 15,
41    /// 其他
42    Other = 16,
43    /// 丹麦
44    Denmark = 17,
45    /// 乌克兰
46    Ukraine = 18,
47    /// 以色列
48    Israel = 19,
49    /// 伊朗
50    Iran = 20,
51    /// 保加利亚
52    Bulgaria = 21,
53    /// 克罗地亚
54    Croatia = 22,
55    /// 冰岛
56    Iceland = 23,
57    /// 匈牙利
58    Hungary = 24,
59    /// 南非
60    SouthAfrica = 25,
61    /// 印尼
62    Indonesia = 26,
63    /// 印度
64    India = 27,
65    /// 哥伦比亚
66    Colombia = 28,
67    /// 土耳其
68    Turkey = 30,
69    /// 墨西哥
70    Mexico = 31,
71    /// 委内瑞拉
72    Venezuela = 32,
73    /// 巴西
74    Brazil = 33,
75    /// 希腊
76    Greece = 34,
77    /// 意大利
78    Italy = 35,
79    /// 挪威
80    Norway = 36,
81    /// 捷克
82    CzechRepublic = 37,
83    /// 摩洛哥
84    Morocco = 38,
85    /// 新西兰
86    NewZealand = 39,
87    /// 智利
88    Chile = 40,
89    /// 比利时
90    Belgium = 41,
91    /// 波兰
92    Poland = 42,
93    /// 澳大利亚
94    Australia = 43,
95    /// 爱尔兰
96    Ireland = 44,
97    /// 瑞典
98    Sweden = 45,
99    /// 瑞士
100    Switzerland = 46,
101    /// 芬兰
102    Finland = 47,
103    /// 苏联
104    SovietUnion = 48,
105    /// 荷兰
106    Netherlands = 49,
107    /// 越南
108    Vietnam = 50,
109    /// 阿根廷
110    Argentina = 51,
111    /// 马耳他
112    Malta = 52,
113    /// 古巴
114    Cuba = 53,
115    /// 菲律宾
116    Philippines = 54,
117    /// 哈萨克斯坦
118    Kazakhstan = 55,
119    /// 黎巴嫩
120    Lebanon = 56,
121    /// 塞浦路斯
122    Cyprus = 57,
123    /// 卡塔尔
124    Qatar = 58,
125    /// 阿联酋
126    UnitedArabEmirates = 59,
127    /// 奥地利
128    Austria = 60,
129    /// 西德
130    WestGermany = 61,
131    /// 卢森堡
132    Luxembourg = 62,
133    /// 罗马尼亚
134    Romania = 63,
135    /// 印度尼西亚
136    Indonesia2 = 64,
137    /// 南斯拉夫
138    Yugoslavia = 65,
139    /// 蒙古
140    Mongolia = 66,
141    /// 葡萄牙
142    Portugal = 70,
143}
144
145impl BangumiArea {
146    pub fn as_u32(self) -> u32 {
147        self as u32
148    }
149}
150
151/// 剧集类型
152#[derive(Debug, Clone, Copy, PartialEq, Eq)]
153pub enum BangumiType {
154    /// 番剧
155    Anime = 1,
156    /// 电影
157    Movie = 2,
158    /// 纪录片
159    Documentary = 3,
160    /// 国创
161    ChineseAnimation = 4,
162    /// 电视剧
163    TVSeries = 5,
164    /// 漫画
165    Manga = 6,
166    /// 综艺
167    Variety = 7,
168}
169
170impl BangumiType {
171    pub fn as_u32(self) -> u32 {
172        self as u32
173    }
174}
175
176/// 剧集基本信息(mdid方式)响应
177pub type BangumiInfoResponse = BpiResponse<BangumiInfoResult>;
178
179#[derive(Debug, Clone, Serialize, Deserialize)]
180pub struct BangumiInfoResult {
181    pub media: BangumiMedia,
182    pub review: Option<BangumiReview>,
183}
184
185#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct BangumiMedia {
187    pub areas: Vec<BangumiAreaInfo>,
188    pub cover: String,
189    pub horizontal_picture: String,
190    pub media_id: u64,
191    pub new_ep: BangumiMediaNewEp,
192    pub rating: BangumiRating,
193    pub season_id: u64,
194    pub share_url: String,
195    pub title: String,
196    pub r#type: u32,
197    pub type_name: String,
198}
199
200#[derive(Debug, Clone, Serialize, Deserialize)]
201pub struct BangumiAreaInfo {
202    pub id: u32,
203    pub name: String,
204}
205
206#[derive(Debug, Clone, Serialize, Deserialize)]
207pub struct BangumiMediaNewEp {
208    pub id: u64,
209    pub index: String,
210    pub index_show: String,
211}
212
213#[derive(Debug, Clone, Serialize, Deserialize)]
214pub struct BangumiDetailNewEp {
215    pub id: u64,
216    pub desc: String,
217    pub is_new: u32,
218    pub title: String,
219}
220
221#[derive(Debug, Clone, Serialize, Deserialize)]
222pub struct BangumiRating {
223    pub count: u64,
224    pub score: f64,
225}
226
227#[derive(Debug, Clone, Serialize, Deserialize)]
228pub struct BangumiReview {
229    pub is_coin: u32,
230    pub is_open: u32,
231}
232
233/// 获取剧集明细(web端)响应
234pub type BangumiDetailResponse = BpiResponse<BangumiDetailResult>;
235
236#[derive(Debug, Clone, Serialize, Deserialize)]
237pub struct BangumiDetailResult {
238    pub activity: Option<BangumiActivity>,
239    pub actors: String,
240    pub alias: String,
241    pub areas: Vec<BangumiAreaInfo>,
242    pub bkg_cover: String,
243    pub cover: String,
244    pub delivery_fragment_video: bool,
245    pub enable_vt: bool,
246    pub episodes: Vec<BangumiEpisode>,
247    pub evaluate: String,
248    pub freya: Option<BangumiFreya>,
249    pub hide_ep_vv_vt_dm: u32,
250    pub icon_font: Option<BangumiIconFont>,
251    pub jp_title: String,
252    pub link: String,
253    pub media_id: u64,
254    pub mode: u32,
255    pub multi_view_info: Option<BangumiMultiViewInfo>,
256    pub new_ep: BangumiDetailNewEp,
257    pub payment: Option<BangumiPayment>,
258    #[serde(rename = "payPack")]
259    pub pay_pack: Option<BangumiPayPack>,
260    pub play_strategy: Option<BangumiPlayStrategy>,
261    pub positive: Option<BangumiPositive>,
262    pub publish: BangumiPublish,
263    pub rating: Option<BangumiRating>,
264    pub record: String,
265    pub rights: BangumiRights,
266    pub season_id: u64,
267    pub season_title: String,
268    pub seasons: Vec<BangumiSeason>,
269    pub section: Option<Vec<BangumiSection>>,
270    pub section_bottom_desc: Option<String>,
271    pub series: Option<BangumiSeries>,
272    pub share_copy: String,
273    pub share_sub_title: String,
274    pub share_url: String,
275    pub show: Option<BangumiShow>,
276    pub show_season_type: u32,
277    pub square_cover: String,
278    pub staff: String,
279    pub stat: BangumiStat,
280    pub status: u32,
281    pub styles: Vec<String>,
282    pub subtitle: String,
283    pub title: String,
284    pub total: u32,
285    pub r#type: u32,
286    pub up_info: Option<BangumiUpInfo>,
287    pub user_status: Option<BangumiUserStatus>,
288}
289
290#[derive(Debug, Clone, Serialize, Deserialize)]
291pub struct BangumiActivity {
292    pub head_bg_url: String,
293    pub id: u64,
294    pub title: String,
295    pub link: Option<String>,
296    pub pendants: Option<Vec<BangumiPendant>>,
297    pub cover: Option<String>,
298}
299
300#[derive(Debug, Clone, Serialize, Deserialize)]
301pub struct BangumiPendant {
302    pub image: String,
303    pub name: String,
304    pub pid: u64,
305}
306
307#[derive(Debug, Clone, Serialize, Deserialize)]
308pub struct BangumiEpisode {
309    pub aid: u64,
310    pub badge: String,
311    pub badge_info: Option<BangumiBadgeInfo>,
312    pub badge_type: u32,
313    pub bvid: String,
314    pub cid: u64,
315    pub cover: String,
316    pub dimension: Option<BangumiDimension>,
317    pub duration: u64,
318    pub enable_vt: bool,
319    pub ep_id: u64,
320    pub from: String,
321    pub id: u64,
322    pub interaction: Option<BangumiInteraction>,
323    pub is_view_hide: bool,
324    pub link: String,
325    pub long_title: String,
326    pub multi_view_eps: Option<Vec<BangumiMultiViewEp>>,
327    pub pub_time: u64,
328    pub pv: u64,
329    pub release_date: String,
330    pub rights: Option<BangumiEpisodeRights>,
331    pub section_type: u32,
332    pub share_copy: String,
333    pub share_url: String,
334    pub short_link: String,
335    pub show_title: String,
336    #[serde(rename = "showDrmLoginDialog")]
337    pub show_drm_login_dialog: bool,
338    pub skip: Option<BangumiSkip>,
339    pub status: u32,
340    pub subtitle: String,
341    pub title: String,
342    pub vid: String,
343}
344
345#[derive(Debug, Clone, Serialize, Deserialize)]
346pub struct BangumiBadgeInfo {
347    pub bg_color: String,
348    pub bg_color_night: String,
349    pub text: String,
350}
351
352#[derive(Debug, Clone, Serialize, Deserialize)]
353pub struct BangumiDimension {
354    pub height: u32,
355    pub rotate: u32,
356    pub width: u32,
357}
358
359#[derive(Debug, Clone, Serialize, Deserialize)]
360pub struct BangumiInteraction {
361    pub graph_version: u32,
362    pub interaction: bool,
363}
364
365#[derive(Debug, Clone, Serialize, Deserialize)]
366pub struct BangumiMultiViewEp {
367    pub ep_id: u64,
368}
369
370#[derive(Debug, Clone, Serialize, Deserialize)]
371pub struct BangumiEpisodeRights {
372    pub allow_dm: u32,
373    pub allow_download: u32,
374    pub area_limit: u32,
375
376    pub allow_demand: Option<u32>,
377}
378
379#[derive(Debug, Clone, Serialize, Deserialize)]
380pub struct BangumiSkip {
381    pub ed: Option<BangumiSkipTime>,
382    pub op: Option<BangumiSkipTime>,
383}
384
385#[derive(Debug, Clone, Serialize, Deserialize)]
386pub struct BangumiSkipTime {
387    pub end: u32,
388    pub start: u32,
389}
390
391#[derive(Debug, Clone, Serialize, Deserialize)]
392pub struct BangumiFreya {
393    pub bubble_desc: String,
394    pub bubble_show_cnt: u32,
395    pub icon_show: u32,
396}
397
398#[derive(Debug, Clone, Serialize, Deserialize)]
399pub struct BangumiIconFont {
400    pub name: String,
401    pub text: String,
402}
403
404#[derive(Debug, Clone, Serialize, Deserialize)]
405pub struct BangumiMultiViewInfo {
406    pub changing_dance: String,
407    pub is_multi_view_season: bool,
408}
409
410#[derive(Debug, Clone, Serialize, Deserialize)]
411pub struct BangumiPayment {
412    pub discount: u32,
413    pub pay_type: BangumiPayType,
414    pub price: String,
415    pub promotion: String,
416    pub tip: String,
417    pub view_start_time: u64,
418    pub vip_discount: u32,
419    pub vip_first_promotion: String,
420    pub vip_price: String,
421    pub vip_promotion: String,
422}
423
424#[derive(Debug, Clone, Serialize, Deserialize)]
425pub struct BangumiPayType {
426    pub allow_discount: u32,
427    pub allow_pack: u32,
428    pub allow_ticket: u32,
429    pub allow_time_limit: u32,
430    pub allow_vip_discount: u32,
431    pub forbid_bb: u32,
432}
433
434#[derive(Debug, Clone, Serialize, Deserialize)]
435pub struct BangumiPayPack {
436    pub id: u64,
437    pub not_paid_text_for_app: String,
438    pub paid_text_for_app: String,
439    pub pay_pack_url: String,
440    pub status: u32,
441    pub title: String,
442}
443
444#[derive(Debug, Clone, Serialize, Deserialize)]
445pub struct BangumiPlayStrategy {
446    pub strategies: Vec<serde_json::Value>,
447}
448
449#[derive(Debug, Clone, Serialize, Deserialize)]
450pub struct BangumiPositive {
451    pub id: u64,
452    pub title: String,
453}
454
455#[derive(Debug, Clone, Serialize, Deserialize)]
456pub struct BangumiPublish {
457    pub is_finish: u32,
458    pub is_started: u32,
459    pub pub_time: String,
460    pub pub_time_show: String,
461    pub unknow_pub_date: u32,
462    pub weekday: u32,
463}
464
465#[derive(Debug, Clone, Serialize, Deserialize)]
466pub struct BangumiRights {
467    pub allow_bp: u32,
468    pub allow_bp_rank: u32,
469    pub allow_download: u32,
470    pub allow_review: u32,
471    pub area_limit: u32,
472    pub ban_area_show: u32,
473    pub can_watch: u32,
474    pub copyright: String,
475    pub forbid_pre: u32,
476    pub freya_white: u32,
477    pub is_cover_show: u32,
478    pub is_preview: u32,
479    pub only_vip_download: u32,
480    pub resource: String,
481    pub watch_platform: u32,
482}
483
484#[derive(Debug, Clone, Serialize, Deserialize)]
485pub struct BangumiSeason {
486    pub badge: String,
487    pub badge_info: Option<BangumiBadgeInfo>,
488    pub badge_type: u32,
489    pub cover: String,
490    pub enable_vt: bool,
491    pub horizontal_cover_1610: String,
492    pub horizontal_cover_169: String,
493    pub icon_font: Option<BangumiIconFont>,
494    pub media_id: u64,
495    pub new_ep: Option<BangumiSeasonNewEp>,
496    pub season_id: u64,
497    pub season_title: String,
498    pub season_type: u32,
499    pub stat: Option<BangumiSeasonStat>,
500}
501
502#[derive(Debug, Clone, Serialize, Deserialize)]
503pub struct BangumiSeasonNewEp {
504    pub cover: String,
505    pub id: u64,
506    pub index_show: String,
507}
508
509#[derive(Debug, Clone, Serialize, Deserialize)]
510pub struct BangumiSeasonStat {
511    pub favorites: u64,
512    pub series_follow: u64,
513    pub views: u64,
514    pub vt: u64,
515}
516
517#[derive(Debug, Clone, Serialize, Deserialize)]
518pub struct BangumiSection {
519    pub attr: u32,
520    pub episode_id: u64,
521    pub episode_ids: Vec<u64>,
522    pub episodes: Vec<BangumiSectionEpisode>,
523    pub id: u64,
524    pub report: Option<BangumiReport>,
525    pub title: String,
526    pub r#type: u32,
527    pub type2: u32,
528}
529
530#[derive(Debug, Clone, Serialize, Deserialize)]
531pub struct BangumiSectionEpisode {
532    pub aid: u64,
533    pub archive_attr: Option<u32>,
534    pub badge: String,
535    pub badge_info: Option<BangumiBadgeInfo>,
536    pub badge_type: u32,
537    pub bvid: String,
538    pub cid: u64,
539    pub cover: String,
540    pub dimension: Option<BangumiDimension>,
541    pub duration: u64,
542    pub enable_vt: bool,
543    pub ep_id: u64,
544    pub from: String,
545    pub icon_font: Option<BangumiIconFont>,
546    pub id: u64,
547    pub interaction: Option<BangumiInteraction>,
548    pub is_view_hide: bool,
549    pub link: String,
550    pub link_type: String,
551    pub long_title: String,
552    pub pub_time: u64,
553    pub pv: u64,
554    pub release_date: String,
555    pub report: Option<BangumiReport>,
556    pub rights: Option<BangumiEpisodeRights>,
557    pub section_type: u32,
558    pub share_copy: String,
559    pub share_url: String,
560    pub short_link: String,
561    pub show_title: String,
562    #[serde(rename = "showDrmLoginDialog")]
563    pub show_drm_login_dialog: bool,
564    pub skip: Option<BangumiSkip>,
565    pub stat: Option<BangumiStat>,
566    pub stat_for_unity: Option<BangumiStatForUnity>,
567    pub status: u32,
568    pub subtitle: String,
569    pub title: String,
570    pub toast_title: String,
571    pub up_info: Option<BangumiUpInfo>,
572    pub vid: String,
573}
574
575#[derive(Debug, Clone, Serialize, Deserialize)]
576pub struct BangumiReport {
577    pub aid: String,
578    pub ep_title: String,
579    pub position: String,
580    pub season_id: String,
581    pub season_type: String,
582    pub section_id: String,
583    pub section_type: String,
584}
585
586#[derive(Debug, Clone, Serialize, Deserialize)]
587pub struct BangumiStatForUnity {
588    pub coin: u64,
589    pub danmaku: Option<BangumiDanmaku>,
590    pub likes: u64,
591    pub reply: u64,
592    pub vt: Option<BangumiVt>,
593}
594
595#[derive(Debug, Clone, Serialize, Deserialize)]
596pub struct BangumiDanmaku {
597    pub icon: String,
598    pub pure_text: String,
599    pub text: String,
600    pub value: u64,
601}
602
603#[derive(Debug, Clone, Serialize, Deserialize)]
604pub struct BangumiVt {
605    pub icon: String,
606    pub pure_text: String,
607    pub text: String,
608    pub value: u64,
609}
610
611#[derive(Debug, Clone, Serialize, Deserialize)]
612pub struct BangumiStat {
613    pub coins: u64,
614    pub danmakus: u64,
615    pub favorite: u64,
616    pub favorites: u64,
617    pub follow_text: String,
618    pub hot: Option<u64>,
619    pub likes: u64,
620    pub reply: u64,
621    pub share: u64,
622    pub views: u64,
623    pub vt: u64,
624}
625
626#[derive(Debug, Clone, Serialize, Deserialize)]
627pub struct BangumiSeries {
628    pub display_type: u32,
629    pub series_id: u64,
630    pub series_title: String,
631}
632
633#[derive(Debug, Clone, Serialize, Deserialize)]
634pub struct BangumiShow {
635    pub wide_screen: u32,
636}
637
638#[derive(Debug, Clone, Serialize, Deserialize)]
639pub struct BangumiUpInfo {
640    pub avatar: String,
641    pub avatar_subscript_url: String,
642    pub follower: u64,
643    pub is_follow: u32,
644    pub mid: u64,
645    pub nickname_color: String,
646    pub pendant: Option<BangumiPendant>,
647    pub theme_type: u32,
648    pub uname: String,
649    pub verify_type: u32,
650    pub vip_label: Option<VipLabel>,
651    pub vip_status: u32,
652    pub vip_type: u32,
653}
654
655#[derive(Debug, Clone, Serialize, Deserialize)]
656pub struct BangumiUserStatus {
657    pub area_limit: u32,
658    pub ban_area_show: u32,
659    pub follow: u32,
660    pub follow_status: u32,
661    pub login: u32,
662    pub pay: u32,
663    pub pay_pack_paid: u32,
664    pub sponsor: u32,
665}
666
667#[derive(Debug, Clone, Serialize, Deserialize)]
668pub struct BangumiSectionResult {
669    pub main_section: BangumiMainSection,
670    pub section: Vec<BangumiMainSection>,
671}
672
673#[derive(Debug, Clone, Serialize, Deserialize)]
674pub struct BangumiMainSection {
675    pub episodes: Vec<BangumiSectionEpisodeInfo>,
676    pub id: u64,
677    pub r#type: u32,
678    pub title: String,
679}
680
681#[derive(Debug, Clone, Serialize, Deserialize)]
682pub struct BangumiSectionEpisodeInfo {
683    pub aid: u64,
684    pub badge: String,
685    pub badge_info: BangumiBadgeInfo,
686    pub badge_type: u32,
687    pub cid: u64,
688    pub cover: String,
689    pub from: String,
690    pub id: u64,
691    pub is_premiere: u32,
692    pub long_title: String,
693    pub share_url: String,
694    pub status: u32,
695    pub title: String,
696    pub vid: String,
697}
698
699impl BpiClient {
700    /// 获取剧集基本信息(mdid方式)
701    ///
702    /// # 参数
703    /// * `media_id` - 剧集mdid
704    ///
705    /// # 文档
706    /// [剧集基本信息(mdid方式)](https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/bangumi/info.md#剧集基本信息mdid方式)
707    pub async fn bangumi_info(&self, media_id: u64) -> Result<BangumiInfoResponse, BpiError> {
708        let result: BangumiInfoResponse = self
709            .get("https://api.bilibili.com/pgc/review/user")
710            .query(&[("media_id", media_id.to_string())])
711            .send_bpi("获取剧集基本信息").await?;
712        Ok(result)
713    }
714
715    /// 获取剧集明细(web端)(ssid方式)
716    ///
717    /// # 参数
718    /// * `season_id` - 番剧ssid
719    ///
720    /// # 文档
721    /// [获取剧集明细(web端)(ssid/epid方式)](https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/bangumi/info.md#获取剧集明细web端ssidepid方式)
722    pub async fn bangumi_detail_by_season_id(
723        &self,
724        season_id: u64
725    ) -> Result<BangumiDetailResponse, BpiError> {
726        let result: BangumiDetailResponse = self
727            .get("https://api.bilibili.com/pgc/view/web/season")
728            .query(&[("season_id", season_id.to_string())])
729            .send_bpi("获取剧集明细").await?;
730        Ok(result)
731    }
732
733    /// 获取剧集明细(web端)(epid方式)
734    ///
735    /// # 参数
736    /// * `ep_id` - 剧集epid
737    ///
738    /// # 文档
739    /// [获取剧集明细(web端)(ssid/epid方式)](https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/bangumi/info.md#获取剧集明细web端ssidepid方式)
740    pub async fn bangumi_detail_by_epid(
741        &self,
742        ep_id: u64
743    ) -> Result<BangumiDetailResponse, BpiError> {
744        self
745            .get("https://api.bilibili.com/pgc/view/web/season")
746            .query(&[("ep_id", ep_id.to_string())])
747            .send_bpi("获取剧集明细").await
748    }
749
750    /// 获取剧集分集信息
751    ///
752    /// # 参数
753    /// * `season_id` - 剧集ssid
754    ///
755    /// # 文档
756    /// [获取剧集明细(web端)(ssid/epid方式)](https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/bangumi/info.md#获取剧集分集信息)
757    pub async fn bangumi_sections_by_season_id(
758        &self,
759        season_id: u64
760    ) -> Result<BpiResponse<BangumiSectionResult>, BpiError> {
761        self
762            .get("https://api.bilibili.com/pgc/web/season/section")
763            .query(&[("season_id", season_id.to_string())])
764            .send_bpi("获取剧集分集信息").await
765    }
766}
767
768#[cfg(test)]
769mod tests {
770    use super::*;
771
772    const TEST_SEASON_ID: u64 = 1172; // ssid
773    const TEST_EP_ID: u64 = 21265; // epid
774    const TEST_MEDIA_ID: u64 = 28220978; //  mdid
775
776    #[tokio::test]
777    async fn test_bangumi_info() -> Result<(), Box<BpiError>> {
778        let bpi = BpiClient::new();
779        let result = bpi.bangumi_info(TEST_MEDIA_ID).await?;
780        let data = result.into_data()?;
781        tracing::info!("{:#?}", data);
782
783        assert_eq!(data.media.media_id, TEST_MEDIA_ID);
784        assert!(!data.media.title.is_empty());
785        assert!(!data.media.areas.is_empty());
786
787        Ok(())
788    }
789
790    #[tokio::test]
791    async fn test_bangumi_detail_by_season_id() -> Result<(), Box<BpiError>> {
792        let bpi = BpiClient::new();
793        let result = bpi.bangumi_detail_by_season_id(TEST_SEASON_ID).await?;
794        let data = result.into_data()?;
795        tracing::info!("{:#?}", data);
796
797        assert_eq!(data.season_id, TEST_SEASON_ID);
798        assert!(!data.title.is_empty());
799        assert!(!data.episodes.is_empty());
800
801        Ok(())
802    }
803
804    #[tokio::test]
805    async fn test_bangumi_detail_by_epid() -> Result<(), Box<BpiError>> {
806        let bpi = BpiClient::new();
807        let result = bpi.bangumi_detail_by_epid(TEST_EP_ID).await?;
808        let data = result.into_data()?;
809        tracing::info!("{:#?}", data);
810
811        assert!(!data.title.is_empty());
812        assert!(!data.episodes.is_empty());
813
814        Ok(())
815    }
816
817    #[tokio::test]
818    async fn test_bangumi_section() -> Result<(), Box<BpiError>> {
819        let bpi = BpiClient::new();
820        let result = bpi.bangumi_sections_by_season_id(TEST_SEASON_ID).await?;
821        let data = result.into_data()?;
822        tracing::info!("{:#?}", data);
823
824        assert!(!data.main_section.episodes.is_empty());
825
826        Ok(())
827    }
828}