Skip to content

Commit 0e78d42

Browse files
committed
feat: starting to add ability to like all songs
still need to add YtMusic support + properly handle CLI arg
1 parent 9a176a2 commit 0e78d42

File tree

5 files changed

+50
-1
lines changed

5 files changed

+50
-1
lines changed

src/args.rs

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ pub struct RootArgs {
1313
#[arg(long, default_value = "false")]
1414
pub debug: bool,
1515

16+
/// Like all songs that will be sychronized on the destination platform
17+
pub like_all: bool,
18+
1619
/// Proxy to use for all requests in the format http://<ip>:<port>
1720
#[arg(long)]
1821
pub proxy: Option<String>,

src/music_api.rs

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ pub trait MusicApi {
5353
let results = try_join_all(requests).await?;
5454
Ok(results)
5555
}
56+
57+
async fn like_songs(&self, songs: &[Song]) -> Result<()>;
5658
}
5759

5860
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)]

src/spotify/mod.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub struct SpotifyApi {
3333
enum HttpMethod<'a> {
3434
Get(&'a [(&'a str, &'a str)]),
3535
Post(&'a serde_json::Value),
36+
Put(&'a serde_json::Value),
3637
Delete(&'a serde_json::Value),
3738
}
3839

@@ -43,6 +44,7 @@ impl SpotifyApi {
4344
const SCOPES: &'static [&'static str] = &[
4445
"user-read-email",
4546
"user-read-private",
47+
"user-library-modify",
4648
"playlist-read-collaborative",
4749
"playlist-modify-public",
4850
"playlist-read-private",
@@ -200,9 +202,10 @@ impl SpotifyApi {
200202
let mut request = match method {
201203
HttpMethod::Get(p) => self.client.get(endpoint).query(p),
202204
HttpMethod::Post(b) => self.client.post(endpoint).json(b),
205+
HttpMethod::Put(b) => self.client.put(endpoint).json(b),
203206
HttpMethod::Delete(b) => self.client.delete(endpoint).json(b),
204207
};
205-
request = request.query(&[("limit", limit), ("offset", offset)]);
208+
//request = request.query(&[("limit", limit), ("offset", offset)]);
206209
let res = request.send().await?;
207210
if res.status() == StatusCode::TOO_MANY_REQUESTS {
208211
self.api_rate_wait(&res).await?;
@@ -411,6 +414,20 @@ impl MusicApi for SpotifyApi {
411414
}
412415
return Ok(None);
413416
}
417+
418+
async fn like_songs(&self, songs: &[Song]) -> Result<()> {
419+
// NOTE: A maximum of 50 items can be specified in one request
420+
for songs_chunk in songs.chunks(50) {
421+
let ids: Vec<&str> = songs_chunk.iter().map(|s| s.id.as_str()).collect();
422+
let body = json!({
423+
"ids": ids,
424+
});
425+
dbg!(&body);
426+
self.make_request("/me/tracks", &HttpMethod::Put(&body), 50, 0)
427+
.await?;
428+
}
429+
Ok(())
430+
}
414431
}
415432

416433
#[cfg(test)]

src/tidal/mod.rs

+23
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub struct TidalApi {
3131
#[derive(Debug)]
3232
enum HttpMethod<'a> {
3333
Get(&'a serde_json::Value),
34+
Post(&'a serde_json::Value),
3435
Put(&'a serde_json::Value),
3536
}
3637

@@ -182,6 +183,7 @@ impl TidalApi {
182183
) -> Result<Response> {
183184
let mut request = match method {
184185
HttpMethod::Get(p) => self.client.get(url).query(p),
186+
HttpMethod::Post(b) => self.client.post(url).form(b),
185187
HttpMethod::Put(b) => self.client.put(url).form(b),
186188
};
187189
if let Some((limit, offset)) = lim_off {
@@ -371,4 +373,25 @@ impl MusicApi for TidalApi {
371373
}
372374
Ok(None)
373375
}
376+
377+
async fn like_songs(&self, songs: &[Song]) -> Result<()> {
378+
let url = format!(
379+
"{}/v1/users/{}/favorites/tracks",
380+
Self::API_URL,
381+
self.user_id
382+
);
383+
let tracks = songs
384+
.iter()
385+
.map(|s| s.id.as_str())
386+
.collect::<Vec<_>>()
387+
.join(",");
388+
let params = json!({
389+
"countryCode": self.country_code,
390+
"trackIds": tracks,
391+
"onArtifactNotFound": "FAIL",
392+
});
393+
self.make_request(&url, &HttpMethod::Post(&params), None)
394+
.await?;
395+
Ok(())
396+
}
374397
}

src/yt_music/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,10 @@ impl MusicApi for YtMusicApi {
379379
}
380380
Ok(None)
381381
}
382+
383+
async fn like_songs(&self, _songs: &[Song]) -> Result<()> {
384+
todo!();
385+
}
382386
}
383387

384388
#[cfg(test)]

0 commit comments

Comments
 (0)