use crate::models::Vip;
use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
use serde::{ Deserialize, Serialize };
use serde_json::Value;
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RepostItem {
pub desc: Desc,
pub card: String,
pub extend_json: String,
pub display: Display,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Desc {
pub uid: i64,
#[serde(rename = "type")]
pub type_field: i64,
pub rid: i64,
pub acl: i64,
pub view: i64,
pub repost: i64,
pub comment: i64,
pub like: i64,
pub is_liked: i64,
pub dynamic_id: i64,
pub timestamp: i64,
pub pre_dy_id: i64,
pub orig_dy_id: i64,
pub orig_type: i64,
pub user_profile: UserProfile,
pub spec_type: i64,
pub uid_type: i64,
pub stype: i64,
pub r_type: i64,
pub inner_id: i64,
pub status: i64,
pub dynamic_id_str: String,
pub pre_dy_id_str: String,
pub orig_dy_id_str: String,
pub rid_str: String,
pub origin: Origin,
pub bvid: String,
pub previous: Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserProfile {
pub info: Info,
pub card: Card,
pub vip: Vip,
pub pendant: Pendant,
pub rank: String,
pub sign: String,
pub level_info: LevelInfo,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Info {
pub uid: i64,
pub uname: String,
pub face: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Card {
pub official_verify: OfficialVerify,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OfficialVerify {
#[serde(rename = "type")]
pub type_field: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Label {
pub path: String,
pub text: String,
pub label_theme: String,
pub text_color: String,
pub bg_style: i64,
pub bg_color: String,
pub border_color: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Pendant {
pub pid: i64,
pub name: String,
pub image: String,
pub expire: i64,
pub image_enhance: String,
pub image_enhance_frame: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LevelInfo {
pub current_level: i64,
pub current_min: i64,
pub current_exp: i64,
pub next_exp: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Origin {
pub uid: i64,
#[serde(rename = "type")]
pub type_field: i64,
pub rid: i64,
pub acl: i64,
pub view: i64,
pub repost: i64,
pub comment: i64,
pub like: i64,
pub is_liked: i64,
pub dynamic_id: i64,
pub timestamp: i64,
pub pre_dy_id: i64,
pub orig_dy_id: i64,
pub orig_type: i64,
pub user_profile: Value,
pub spec_type: i64,
pub uid_type: i64,
pub stype: i64,
pub r_type: i64,
pub inner_id: i64,
pub status: i64,
pub dynamic_id_str: String,
pub pre_dy_id_str: String,
pub orig_dy_id_str: String,
pub rid_str: String,
pub origin: Value,
pub bvid: String,
pub previous: Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Display {
pub origin: Origin2,
pub usr_action_txt: String,
pub relation: Relation2,
pub live_info: Value,
pub emoji_info: EmojiInfo2,
pub highlight: Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Origin2 {
pub origin: Value,
pub usr_action_txt: String,
pub relation: Relation,
pub live_info: Value,
pub emoji_info: EmojiInfo,
pub highlight: Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Relation {
pub status: i64,
pub is_follow: i64,
pub is_followed: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EmojiInfo {
pub emoji_details: Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Relation2 {
pub status: i64,
pub is_follow: i64,
pub is_followed: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EmojiInfo2 {
pub emoji_details: Value,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct LikeItem {
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PlainTextRequest {
pub content: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Draft {
pub draft_id: String,
pub publish_time: u64,
#[serde(rename = "type")]
pub type_num: u8,
pub uid: u64,
pub user_profile: UserProfile,
pub request: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RepostDetailResponseData {
pub has_more: Option<bool>,
pub total: u64,
pub items: Vec<RepostItem>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SpecItemLikesResponseData {
pub item_likes: Vec<LikeItem>,
pub has_more: bool,
pub total_count: u64,
pub gt: u64,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct GetDraftsResponseData {
pub drafts: Vec<Draft>,
}
impl BpiClient {
pub async fn dynamic_repost_detail(
&self,
dynamic_id: &str,
offset: Option<&str>
) -> Result<BpiResponse<RepostDetailResponseData>, BpiError> {
let mut req = self
.get("https://api.vc.bilibili.com/dynamic_repost/v1/dynamic_repost/repost_detail")
.query(&[("dynamic_id", dynamic_id)]);
if let Some(o) = offset {
req = req.query(&[("offset", o)]);
}
req.send_bpi("获取动态转发列表").await
}
pub async fn dynamic_spec_item_likes(
&self,
dynamic_id: u64,
pn: Option<u64>,
ps: Option<u64>
) -> Result<BpiResponse<SpecItemLikesResponseData>, BpiError> {
let pn_val = pn.unwrap_or(1);
let ps_val = ps.unwrap_or(20);
let req = self
.get("https://api.vc.bilibili.com/dynamic_like/v1/dynamic_like/spec_item_likes")
.query(
&[
("dynamic_id", &dynamic_id.to_string()),
("pn", &pn_val.to_string()),
("ps", &ps_val.to_string()),
]
);
req.send_bpi("获取动态点赞列表").await
}
#[allow(dead_code)]
async fn get_drafts(&self) -> Result<BpiResponse<GetDraftsResponseData>, BpiError> {
let req = self.get("https://api.vc.bilibili.com/dynamic_draft/v1/dynamic_draft/get_drafts");
req.send_bpi("获取草稿列表").await
}
}
#[cfg(test)]
mod tests {
use super::*;
use tracing::info;
#[tokio::test]
async fn test_get_repost_detail() -> Result<(), BpiError> {
let bpi = BpiClient::new();
let dynamic_id = "1099138163191840776";
let resp = bpi.dynamic_repost_detail(dynamic_id, None).await?;
let data = resp.into_data()?;
info!("动态转发列表测试结果: {:?}", data);
assert!(!data.items.iter().len() > 0);
Ok(())
}
}