bpi_rs/creativecenter/
upload.rs1use crate::BilibiliRequest;
6use crate::BpiError;
7use crate::BpiResult;
8use crate::creativecenter::CreativeCenterClient;
9use base64::{Engine as _, engine::general_purpose};
10use serde::{Deserialize, Serialize};
11use std::collections::HashMap;
12use std::fs;
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct UploadCoverData {
18 pub url: String,
19}
20
21impl<'a> CreativeCenterClient<'a> {
22 pub async fn upload_cover(
38 &self,
39 mime_type: &str,
40 cover: impl AsRef<str>,
41 ) -> BpiResult<UploadCoverData> {
42 let csrf = self.client.csrf()?;
43 let cover_str = cover.as_ref();
44
45 let final_cover = if cover_str.starts_with("data:") {
46 cover_str.to_string()
47 } else if cover_str
48 .chars()
49 .all(|c| (c.is_ascii_alphanumeric() || c == '+' || c == '/' || c == '='))
50 {
51 format!("data:{};base64,{}", mime_type, cover_str)
52 } else {
53 let file_bytes = fs::read(cover_str).map_err(|e| BpiError::Parse {
54 message: format!("读取文件失败: {}", e),
55 })?;
56 let file_base64 = general_purpose::STANDARD.encode(file_bytes);
57 format!("data:{};base64,{}", mime_type, file_base64)
58 };
59
60 let mut form = HashMap::new();
61 form.insert("csrf", csrf);
62 form.insert("cover", final_cover);
63
64 self.client
65 .post("https://member.bilibili.com/x/vu/web/cover/up")
66 .form(&form)
67 .send_bpi_payload("creativecenter.cover.upload")
68 .await
69 }
70}