modified: Cargo.lock

modified:   Cargo.toml
	modified:   src/main.rs
This commit is contained in:
Michael Wain 2024-12-23 04:37:27 +03:00
parent a4f37099b1
commit f9914523bc
3 changed files with 120 additions and 10 deletions

41
Cargo.lock generated
View File

@ -17,6 +17,15 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "atomic-waker"
version = "1.1.2"
@ -751,6 +760,35 @@ dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "reqwest"
version = "0.12.9"
@ -999,7 +1037,10 @@ dependencies = [
name = "soundcloud"
version = "0.1.0"
dependencies = [
"regex",
"reqwest",
"serde",
"serde_json",
"tokio",
]

View File

@ -7,9 +7,9 @@ authors = ["alterwain"]
keywords = ["api", "network", "audio", "music"]
categories = ["network-programming", "asynchronous", "api", "music", "audio"]
[lib]
crate-type = ["staticlib", "cdylib", "lib"]
[dependencies]
reqwest = { version = "0.12", features = ["json"] }
tokio = { version = "1", features = ["full"] }
tokio = { version = "1", features = ["full"] }
regex = "1.11.1"
serde = { version = "1.0.104", features = ["derive"] }
serde_json = "1.0.48"

View File

@ -1,15 +1,84 @@
use std::collections::HashMap;
use std::{collections::HashMap, error::Error};
use regex::Regex;
/*
[lib]
crate-type = ["staticlib", "cdylib", "lib"]
*/
// https://soundcloud.com/soundcloud regex: "<script crossorigin src=\"" search for client_id inside of script
// https://soundcloud.com/versions.json
// likes: https://api-v2.soundcloud.com/users/774639751/likes?client_id=zFEmsF1cEZZQ92nRRXKOg7e6ibFR1L7c&limit=10&offset=0&linked_partitioning=1&app_version=1734537250&app_locale=en
// playlists: https://api-v2.soundcloud.com/users/774639751/playlists_without_albums?client_id=zFEmsF1cEZZQ92nRRXKOg7e6ibFR1L7c&limit=10&offset=0&linked_partitioning=1&app_version=1734537250&app_locale=en
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::get("https://api-v2.soundcloud.com/users/774639751/playlists_without_albums?client_id=zFEmsF1cEZZQ92nRRXKOg7e6ibFR1L7c&limit=10&offset=0&linked_partitioning=1&app_version=1734537250&app_locale=en")
.await?
.json::<HashMap<String, String>>()
.await?;
println!("{resp:#?}");
println!("{}", get_app().await.unwrap().unwrap());
Ok(())
}
async fn get_likes() -> Result<Option<String>, Box<dyn Error>> {
}
async fn get_playlists() -> Result<Option<String>, Box<dyn Error>> {
}
async fn get_app() -> Result<Option<String>, Box<dyn Error>> {
let resp = reqwest::get("https://soundcloud.com/versions.json")
.await?
.text()
.await?;
let json: serde_json::Value = serde_json::from_str(&resp).expect("JSON was not well-formatted");
Ok(
Some(
json.get("app")
.unwrap()
.as_str()
.unwrap()
.to_string()
)
)
}
async fn get_client_id() -> Result<Option<String>, Box<dyn Error>> {
let resp = reqwest::get("https://soundcloud.com/soundcloud")
.await?
.text()
.await?;
let rg = Regex::new(r#"src=".+""#).unwrap();
let mut urls = Vec::new();
for cap in Regex::new(r#"<script .+src="https://.+""#).unwrap().find_iter(&resp) {
let script_block = cap.as_str();
if let Some(m) = rg.find(script_block) {
urls.push(&m.as_str()[5..m.as_str().len()-1]);
}
}
let rg = Regex::new(r#""client_id=[a-zA-Z0-9]+""#).unwrap();
for i in 0..urls.len() {
let url = urls.get(i).unwrap().to_string();
let resp = reqwest::get(&url)
.await?
.text()
.await?;
if let Some(m) = rg.find(&resp) {
return Ok(Some(m.as_str()[11..m.as_str().len()-1].to_string()));
}
}
Ok(None)
}