modified: Cargo.lock
modified: Cargo.toml modified: src/lib.rs
This commit is contained in:
parent
736d4560a5
commit
656aef28f3
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1036,7 +1036,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "soundcloud"
|
name = "soundcloud"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"regex",
|
"regex",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "soundcloud"
|
name = "soundcloud"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "A small rust crate for fetching data from soundcloud without developer account"
|
description = "A small rust crate for fetching data from soundcloud without developer account"
|
||||||
authors = ["alterwain"]
|
authors = ["alterwain"]
|
||||||
|
69
src/lib.rs
69
src/lib.rs
@ -2,7 +2,7 @@ use std::error::Error;
|
|||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use reqwest::header::USER_AGENT;
|
use reqwest::header::USER_AGENT;
|
||||||
use sobjects::CloudPlaylists;
|
use sobjects::{CloudPlaylists, CloudTrack};
|
||||||
|
|
||||||
pub mod sobjects;
|
pub mod sobjects;
|
||||||
|
|
||||||
@ -26,7 +26,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
pub async fn get_likes(user_id: u64, client_id: String, app_version: String) -> Result<Option<String>, Box<dyn Error>> {
|
pub async fn get_likes(
|
||||||
|
user_id: u64,
|
||||||
|
client_id: String,
|
||||||
|
app_version: String,
|
||||||
|
) -> Result<Option<String>, Box<dyn Error>> {
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
|
|
||||||
let resp = client.get(format!("https://{}/users/{}/likes?client_id={}&limit=10&offset=0&linked_partitioning=1&app_version={}&app_locale=en", SOUNDCLOUD_API_DOMAIN, user_id, client_id, app_version) )
|
let resp = client.get(format!("https://{}/users/{}/likes?client_id={}&limit=10&offset=0&linked_partitioning=1&app_version={}&app_locale=en", SOUNDCLOUD_API_DOMAIN, user_id, client_id, app_version) )
|
||||||
@ -39,7 +43,40 @@ pub async fn get_likes(user_id: u64, client_id: String, app_version: String) ->
|
|||||||
Ok(Some(resp))
|
Ok(Some(resp))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_playlists(user_id: u64, client_id: String, app_version: String) -> Result<CloudPlaylists, Box<dyn Error>> {
|
pub async fn get_tracks(
|
||||||
|
pl: Vec<CloudTrack>,
|
||||||
|
client_id: String,
|
||||||
|
app_version: String,
|
||||||
|
) -> Result<Vec<CloudTrack>, Box<dyn Error>> {
|
||||||
|
let ids = pl
|
||||||
|
.iter()
|
||||||
|
.map(|t| t.id.to_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(",");
|
||||||
|
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
|
||||||
|
let resp = client
|
||||||
|
.get(format!(
|
||||||
|
"https://{}/tracks?ids={}&client_id={}&app_version={}&app_locale=en",
|
||||||
|
SOUNDCLOUD_API_DOMAIN, ids, client_id, app_version
|
||||||
|
))
|
||||||
|
.header(USER_AGENT, CHROME_USER_AGENT)
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.text()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let tracks: Vec<CloudTrack> = serde_json::from_str(&resp)?;
|
||||||
|
|
||||||
|
Ok(tracks)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_playlists(
|
||||||
|
user_id: u64,
|
||||||
|
client_id: String,
|
||||||
|
app_version: String,
|
||||||
|
) -> Result<CloudPlaylists, Box<dyn Error>> {
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
|
|
||||||
let resp = client.get(format!("https://{}/users/{}/playlists_without_albums?client_id={}&limit=10&offset=0&linked_partitioning=1&app_version={}&app_locale=en", SOUNDCLOUD_API_DOMAIN, user_id, client_id, app_version))
|
let resp = client.get(format!("https://{}/users/{}/playlists_without_albums?client_id={}&limit=10&offset=0&linked_partitioning=1&app_version={}&app_locale=en", SOUNDCLOUD_API_DOMAIN, user_id, client_id, app_version))
|
||||||
@ -57,7 +94,8 @@ pub async fn get_playlists(user_id: u64, client_id: String, app_version: String)
|
|||||||
pub async fn get_app() -> Result<Option<String>, Box<dyn Error>> {
|
pub async fn get_app() -> Result<Option<String>, Box<dyn Error>> {
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
|
|
||||||
let resp = client.get(format!("{}/versions.json", SOUNDCLOUD_DOMAIN))
|
let resp = client
|
||||||
|
.get(format!("{}/versions.json", SOUNDCLOUD_DOMAIN))
|
||||||
.header(USER_AGENT, CHROME_USER_AGENT)
|
.header(USER_AGENT, CHROME_USER_AGENT)
|
||||||
.send()
|
.send()
|
||||||
.await?
|
.await?
|
||||||
@ -66,21 +104,14 @@ pub async fn get_app() -> Result<Option<String>, Box<dyn Error>> {
|
|||||||
|
|
||||||
let json: serde_json::Value = serde_json::from_str(&resp).expect("JSON was not well-formatted");
|
let json: serde_json::Value = serde_json::from_str(&resp).expect("JSON was not well-formatted");
|
||||||
|
|
||||||
Ok(
|
Ok(Some(json.get("app").unwrap().as_str().unwrap().to_string()))
|
||||||
Some(
|
|
||||||
json.get("app")
|
|
||||||
.unwrap()
|
|
||||||
.as_str()
|
|
||||||
.unwrap()
|
|
||||||
.to_string()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_client_id() -> Result<Option<String>, Box<dyn Error>> {
|
pub async fn get_client_id() -> Result<Option<String>, Box<dyn Error>> {
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
|
|
||||||
let resp = client.get(format!("{}/soundcloud", SOUNDCLOUD_DOMAIN))
|
let resp = client
|
||||||
|
.get(format!("{}/soundcloud", SOUNDCLOUD_DOMAIN))
|
||||||
.header(USER_AGENT, CHROME_USER_AGENT)
|
.header(USER_AGENT, CHROME_USER_AGENT)
|
||||||
.send()
|
.send()
|
||||||
.await?
|
.await?
|
||||||
@ -91,7 +122,10 @@ pub async fn get_client_id() -> Result<Option<String>, Box<dyn Error>> {
|
|||||||
|
|
||||||
let mut urls = Vec::new();
|
let mut urls = Vec::new();
|
||||||
|
|
||||||
for cap in Regex::new(r#"<script .+src="https://.+""#).unwrap().find_iter(&resp) {
|
for cap in Regex::new(r#"<script .+src="https://.+""#)
|
||||||
|
.unwrap()
|
||||||
|
.find_iter(&resp)
|
||||||
|
{
|
||||||
let script_block = cap.as_str();
|
let script_block = cap.as_str();
|
||||||
if let Some(m) = rg.find(script_block) {
|
if let Some(m) = rg.find(script_block) {
|
||||||
urls.push(&m.as_str()[5..m.as_str().len() - 1]);
|
urls.push(&m.as_str()[5..m.as_str().len() - 1]);
|
||||||
@ -102,10 +136,7 @@ pub async fn get_client_id() -> Result<Option<String>, Box<dyn Error>> {
|
|||||||
|
|
||||||
for i in 0..urls.len() {
|
for i in 0..urls.len() {
|
||||||
let url = urls.get(i).unwrap().to_string();
|
let url = urls.get(i).unwrap().to_string();
|
||||||
let resp = reqwest::get(&url)
|
let resp = reqwest::get(&url).await?.text().await?;
|
||||||
.await?
|
|
||||||
.text()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if let Some(m) = rg.find(&resp) {
|
if let Some(m) = rg.find(&resp) {
|
||||||
return Ok(Some(m.as_str()[11..m.as_str().len() - 1].to_string()));
|
return Ok(Some(m.as_str()[11..m.as_str().len() - 1].to_string()));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user