ncm_api_rs/api/
related_playlist.rs1use crate::error::Result;
2use crate::request::{ApiClient, ApiResponse};
7use regex_lite::Regex;
8use serde_json::json;
9
10impl ApiClient {
11 pub async fn related_playlist(&self, query: &super::Query) -> Result<ApiResponse> {
14 let id = query.get_or("id", "0");
15 let url = format!("https://music.163.com/playlist?id={}", id);
16
17 let resp = self.client.get(&url).send().await?;
18 let status = resp.status().as_u16() as i64;
19 let html = resp.text().await?;
20
21 let pattern = Regex::new(
22 r#"<div class="cver u-cover u-cover-3">[\s\S]*?<img src="([^"]+)">[\s\S]*?<a class="sname f-fs1 s-fc0" href="([^"]+)"[^>]*>([^<]+?)</a>[\s\S]*?<a class="nm nm f-thide s-fc3" href="([^"]+)"[^>]*>([^<]+?)</a>"#,
23 ).map_err(|e| crate::error::NcmError::Unknown(e.to_string()))?;
24
25 let mut playlists = Vec::new();
26 for caps in pattern.captures_iter(&html) {
27 let cover_img_url = caps.get(1).map(|m| m.as_str()).unwrap_or("");
28 let playlist_href = caps.get(2).map(|m| m.as_str()).unwrap_or("");
29 let name = caps.get(3).map(|m| m.as_str()).unwrap_or("");
30 let user_href = caps.get(4).map(|m| m.as_str()).unwrap_or("");
31 let nickname = caps.get(5).map(|m| m.as_str()).unwrap_or("");
32
33 let user_id = user_href
34 .strip_prefix("/user/home?id=")
35 .unwrap_or(user_href);
36 let playlist_id = playlist_href
37 .strip_prefix("/playlist?id=")
38 .unwrap_or(playlist_href);
39 let cover = cover_img_url
40 .strip_suffix("?param=50y50")
41 .unwrap_or(cover_img_url);
42
43 playlists.push(json!({
44 "creator": {
45 "userId": user_id,
46 "nickname": nickname
47 },
48 "coverImgUrl": cover,
49 "name": name,
50 "id": playlist_id
51 }));
52 }
53
54 Ok(ApiResponse {
55 status,
56 body: json!({ "code": 200, "playlists": playlists }),
57 cookie: vec![],
58 })
59 }
60}