diff --git a/Cargo.lock b/Cargo.lock
index 1c46e90..cee09e1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1284,8 +1284,8 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
[[package]]
name = "itunesdb"
-version = "0.1.90"
-source = "git+https://gitea.awain.net/alterwain/ITunesDB.git#d37957a9a0b66577dadf3b305b02c72f1ca50a62"
+version = "0.1.95"
+source = "git+https://gitea.awain.net/alterwain/ITunesDB.git#2ecbe7666bf7c561c9ace767d2e4055e0d92127d"
dependencies = [
"bincode",
"env_logger",
@@ -2349,8 +2349,8 @@ dependencies = [
[[package]]
name = "soundcloud"
-version = "0.1.8"
-source = "git+https://gitea.awain.net/alterwain/soundcloud_api.git#656aef28f356411ff25cee14214ea0e677563537"
+version = "0.1.9"
+source = "git+https://gitea.awain.net/alterwain/soundcloud_api.git#a6732847bebbcb6e59a1b8a44a965fe7092af6e9"
dependencies = [
"hyper-util",
"regex",
diff --git a/Cargo.toml b/Cargo.toml
index 4b3310a..00eed0e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,8 +20,8 @@ crossterm = { version = "0.28.1", features = ["event-stream"] }
futures = "0.3"
tokio = { version = "1", features = ["full"] }
tokio-util = { version = "0.7.12", features = ["codec"] }
-soundcloud = { version = "0.1.8", git = "https://gitea.awain.net/alterwain/soundcloud_api.git" }
-itunesdb = { version = "0.1.90", git = "https://gitea.awain.net/alterwain/ITunesDB.git" }
+soundcloud = { version = "0.1.9", git = "https://gitea.awain.net/alterwain/soundcloud_api.git" }
+itunesdb = { version = "0.1.95", git = "https://gitea.awain.net/alterwain/ITunesDB.git" }
rand = "0.8.5"
tui-big-text = "0.7.1"
throbber-widgets-tui = "0.8.0"
diff --git a/README.md b/README.md
index 22adc15..dd4300c 100644
--- a/README.md
+++ b/README.md
@@ -4,10 +4,10 @@
Lightweight iPod manager, batteries included.
-#
+#
-
![]()
+
Screenshot from MacOS Big Sur terminal
@@ -41,6 +41,5 @@ Lightweight iPod manager, batteries included.
## Todos
-- Implement artwork integration
-- Implement youtube api
-- Implement albums generation
\ No newline at end of file
+- Implement manual playlist editing
+- Implement youtube api
\ No newline at end of file
diff --git a/src/config.rs b/src/config.rs
index ff2806f..aee94f8 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -32,12 +32,6 @@ pub fn get_temp_itunesdb() -> PathBuf {
p
}
-pub fn get_db() -> PathBuf {
- let mut p = get_configs_dir();
- p.push("data.redb");
- p
-}
-
#[derive(Debug, Deserialize, Serialize)]
pub struct YouTubeConfiguration {
pub user_id: u64,
diff --git a/src/dlp.rs b/src/dlp.rs
index 1243148..59d12ec 100644
--- a/src/dlp.rs
+++ b/src/dlp.rs
@@ -1,7 +1,7 @@
-use std::{io, path::PathBuf, process::Stdio};
-
+use ratatui::style::Color;
use regex::Regex;
use serde::Deserialize;
+use std::{io, path::PathBuf, process::Stdio};
use tokio::{
io::{AsyncBufReadExt, BufReader},
process::Command,
@@ -59,11 +59,15 @@ pub async fn download_track_from_soundcloud(
while let Ok(Some(line)) = reader.next_line().await {
if line.starts_with("{") {
let progress: DownloadProgress = serde_json::from_str(&line).unwrap();
- let _ = sender.send(AppEvent::OverallProgress((0, 1))).await;
+ let _ = sender
+ .send(AppEvent::OverallProgress((0, 1, Color::Green)))
+ .await;
let _ = sender.send(AppEvent::CurrentProgress(progress)).await;
}
}
- let _ = sender.send(AppEvent::OverallProgress((1, 1))).await;
+ let _ = sender
+ .send(AppEvent::OverallProgress((1, 1, Color::Green)))
+ .await;
Ok(())
}
@@ -114,7 +118,9 @@ pub async fn download_from_soundcloud(
let s: Vec<&str> = s.split(' ').collect();
let cur = s.first().unwrap().trim().parse().unwrap();
let max = s.last().unwrap().trim().parse().unwrap();
- let _ = sender.send(AppEvent::OverallProgress((cur, max))).await;
+ let _ = sender
+ .send(AppEvent::OverallProgress((cur, max, Color::Green)))
+ .await;
}
None => {
if line.starts_with("{") {
diff --git a/src/file_system.rs b/src/file_system.rs
index b7f889e..9b23771 100644
--- a/src/file_system.rs
+++ b/src/file_system.rs
@@ -21,13 +21,30 @@ pub struct FileSystem {
sender: UnboundedSender
,
}
-fn check_extension_compatibility(ext: &OsStr) -> bool {
+fn check_extension_compatibility(ext: &str) -> bool {
matches!(
- ext.to_str().unwrap().to_lowercase().as_str(),
+ ext.to_lowercase().as_str(),
"mp3" | "m4a" | "wav" | "aiff" | "aif"
)
}
+fn get_extension_from_filename(file_name: Option<&OsStr>) -> String {
+ if let Some(fname) = file_name {
+ let file_name = fname.to_str().unwrap();
+ let index = file_name
+ .chars()
+ .enumerate()
+ .filter(|(i, c)| *c == '.')
+ .map(|(i, c)| i)
+ .last();
+ if let Some(index) = index {
+ let extension: String = file_name.chars().skip(index).collect();
+ return extension;
+ }
+ }
+ "none".to_string()
+}
+
fn list_files_recursively(p: PathBuf) -> Vec {
let mut files = Vec::new();
@@ -38,7 +55,14 @@ fn list_files_recursively(p: PathBuf) -> Vec {
continue;
}
let a = path.unwrap().path();
- if a.is_file() && check_extension_compatibility(a.extension().unwrap()) {
+ if a.is_file()
+ && check_extension_compatibility(
+ a.extension()
+ .map_or(&get_extension_from_filename(a.file_name()), |s| {
+ s.to_str().unwrap()
+ }),
+ )
+ {
files.push(a.clone());
}
if a.is_dir() {
@@ -130,10 +154,9 @@ impl FileSystem {
let mut dir = paths
.filter_map(|res| res.ok())
.filter(|p| {
- p.path()
- .extension()
- .map_or(false, check_extension_compatibility)
- || p.path().is_dir()
+ p.path().extension().map_or(false, |s| {
+ check_extension_compatibility(s.to_str().unwrap_or("none"))
+ }) || p.path().is_dir()
})
.collect::>();
dir.sort_by(|a, b| {
diff --git a/src/loading_screen.rs b/src/loading_screen.rs
index 249f8a4..591a60b 100644
--- a/src/loading_screen.rs
+++ b/src/loading_screen.rs
@@ -10,7 +10,8 @@ use crate::{dlp::DownloadProgress, screen::AppScreen, theme::Theme};
#[derive(Default)]
pub struct LoadingScreen {
- pub progress: Option<(u32, u32)>,
+ pub progress: Option<(u32, u32, ratatui::style::Color)>,
+ pub artwork_progress: Option<(u32, u32)>,
pub s_progress: Option,
}
@@ -61,11 +62,29 @@ impl LoadingScreen {
self.render_overall(frame, chunks[1]);
}
- if self.s_progress.is_some() {
+ if self.artwork_progress.is_some() {
+ self.render_artwork_progress(frame, chunks[2]);
+ } else if self.s_progress.is_some() {
self.render_current(frame, chunks[2]);
}
}
+ fn render_artwork_progress(&self, frame: &mut Frame, area: Rect) {
+ let gauge = Gauge::default()
+ .block(
+ Block::default()
+ .borders(Borders::ALL)
+ .title(" Generating album covers "),
+ )
+ .gauge_style(Style::default().fg(Color::LightBlue))
+ .ratio(
+ self.artwork_progress.unwrap().0 as f64 / self.artwork_progress.unwrap().1 as f64,
+ )
+ .label("Generating album covers...");
+
+ frame.render_widget(gauge, area);
+ }
+
fn render_current(&self, frame: &mut Frame, area: Rect) {
let s: String = self
.s_progress
@@ -96,7 +115,7 @@ impl LoadingScreen {
.borders(Borders::ALL)
.title(" Downloading Playlist "),
)
- .gauge_style(Style::default().fg(Color::Green))
+ .gauge_style(Style::default().fg(self.progress.unwrap().2))
.ratio(self.progress.unwrap().0 as f64 / self.progress.unwrap().1 as f64)
.label(format!(
"{:}/{:}",
diff --git a/src/main.rs b/src/main.rs
index 3127574..c912930 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -121,14 +121,22 @@ impl App {
let screen: &mut MainScreen = self.get_screen(&AppState::MainScreen);
screen.set_soundcloud_playlists(playlists);
},
- AppEvent::OverallProgress((c, max)) => {
+ AppEvent::OverallProgress((c, max, color)) => {
+ self.state = AppState::LoadingScreen;
let screen: &mut LoadingScreen = self.get_screen(&AppState::LoadingScreen);
- screen.progress = Some((c, max));
+ screen.progress = Some((c, max, color));
+ screen.artwork_progress = None;
},
AppEvent::CurrentProgress(progress) => {
let screen: &mut LoadingScreen = self.get_screen(&AppState::LoadingScreen);
+ screen.artwork_progress = None;
screen.s_progress = Some(progress);
},
+ AppEvent::ArtworkProgress((c, max)) => {
+ let screen: &mut LoadingScreen = self.get_screen(&AppState::LoadingScreen);
+ screen.artwork_progress = Some((c, max));
+ screen.s_progress = None;
+ },
AppEvent::SwitchScreen(screen) => {
self.state = screen;
}
diff --git a/src/sync.rs b/src/sync.rs
index 52bdf12..ac02f1e 100644
--- a/src/sync.rs
+++ b/src/sync.rs
@@ -6,6 +6,7 @@ use itunesdb::artworkdb::aobjects::ADatabase;
use itunesdb::objects::{ListSortOrder, PlaylistItem};
use itunesdb::serializer;
use itunesdb::xobjects::{XDatabase, XPlArgument, XPlaylist, XTrackItem};
+use ratatui::style::Color;
use soundcloud::sobjects::{CloudPlaylist, CloudPlaylists, CloudTrack};
use std::io::Read;
use std::io::{Cursor, Write};
@@ -34,7 +35,8 @@ pub enum AppEvent {
DownloadPlaylist(CloudPlaylist),
DownloadTrack(CloudTrack),
CurrentProgress(DownloadProgress),
- OverallProgress((u32, u32)),
+ OverallProgress((u32, u32, ratatui::style::Color)),
+ ArtworkProgress((u32, u32)),
SwitchScreen(AppState),
LoadFromFS(PathBuf),
LoadFromFSVec(Vec),
@@ -51,7 +53,11 @@ pub struct DBPlaylist {
pub tracks: Vec,
}
-async fn track_from_soundcloud(value: &CloudTrack, ipod_path: String) -> Option {
+async fn track_from_soundcloud(
+ value: &CloudTrack,
+ ipod_path: String,
+ sender: &Sender,
+) -> Option {
let mut track_path = get_temp_dl_dir();
track_path.push(value.id.to_string());
track_path.set_extension("mp3");
@@ -62,7 +68,6 @@ async fn track_from_soundcloud(value: &CloudTrack, ipod_path: String) -> Option<
.await
.unwrap();
let audio_info = &audio_file.audio_file.tracks.track;
-
let song_dbid = util::hash_from_path(track_path);
let mut track = XTrackItem::new(
@@ -77,20 +82,24 @@ async fn track_from_soundcloud(value: &CloudTrack, ipod_path: String) -> Option<
);
if image_path.exists() {
+ let _ = sender.send(AppEvent::ArtworkProgress((0, 2))).await;
let mut adb = get_artwork_db(&ipod_path);
let image_data = std::fs::read(image_path).unwrap();
- let (small_img_name, large_img_name) = adb.add_images(song_dbid, util::hash(&image_data));
+ let cover_hash = util::hash(&image_data);
- let mut dst = PathBuf::from(&ipod_path);
- dst.push("iPod_Control");
- dst.push("Artwork");
+ let if_cover_present = adb.if_cover_present(cover_hash);
+
+ let (small_img_name, large_img_name) = adb.add_images(song_dbid, cover_hash);
let size = image_data.len();
- make_cover_image(&image_data, &ipod_path, &small_img_name, (100, 100));
- make_cover_image(&image_data, &ipod_path, &large_img_name, (200, 200));
+ if !if_cover_present {
+ make_cover_image(&image_data, &ipod_path, &small_img_name, (100, 100));
+ let _ = sender.send(AppEvent::ArtworkProgress((1, 2))).await;
+ make_cover_image(&image_data, &ipod_path, &large_img_name, (200, 200));
+ }
write_artwork_db(adb, &ipod_path);
@@ -98,6 +107,7 @@ async fn track_from_soundcloud(value: &CloudTrack, ipod_path: String) -> Option<
track.data.mhii_link = 0;
track.data.has_artwork = 1;
track.data.artwork_count = 1;
+ let _ = sender.send(AppEvent::ArtworkProgress((2, 2))).await;
}
audio_file.modify_xtrack(&mut track);
@@ -109,7 +119,9 @@ async fn track_from_soundcloud(value: &CloudTrack, ipod_path: String) -> Option<
.clone()
.map_or(String::new(), |a| a.username.unwrap_or(a.permalink)),
);
- track.set_genre(value.genre.clone().unwrap());
+ if value.genre.is_some() {
+ track.set_genre(value.genre.clone().unwrap());
+ }
Some(track)
}
@@ -207,11 +219,15 @@ async fn remove_track_from_playlist(
sender: &Sender,
ipod_path: String,
) {
- let _ = sender.send(AppEvent::OverallProgress((0, 1))).await;
+ let _ = sender
+ .send(AppEvent::OverallProgress((0, 1, Color::Red)))
+ .await;
database.remove_track_from_playlist(track_id, pl_id);
- let _ = sender.send(AppEvent::OverallProgress((1, 1))).await;
+ let _ = sender
+ .send(AppEvent::OverallProgress((1, 1, Color::Red)))
+ .await;
let _ = sender
.send(AppEvent::SwitchScreen(AppState::MainScreen))
@@ -242,18 +258,22 @@ async fn remove_playlist(
let mut i = 1;
for (item, args) in pl.elems.iter() {
let _ = sender
- .send(AppEvent::OverallProgress((i, max as u32)))
+ .send(AppEvent::OverallProgress((i, max as u32, Color::Red)))
.await;
remove_track(item.track_id, database, sender, ipod_path.clone()).await;
i += 1;
}
}
- let _ = sender.send(AppEvent::OverallProgress((0, 1))).await;
+ let _ = sender
+ .send(AppEvent::OverallProgress((0, 1, Color::Red)))
+ .await;
database.remove_playlist(pl_id);
- let _ = sender.send(AppEvent::OverallProgress((1, 1))).await;
+ let _ = sender
+ .send(AppEvent::OverallProgress((1, 1, Color::Red)))
+ .await;
let _ = sender
.send(AppEvent::SwitchScreen(AppState::MainScreen))
@@ -272,14 +292,18 @@ async fn remove_track(
sender: &Sender,
ipod_path: String,
) {
- let _ = sender.send(AppEvent::OverallProgress((0, 1))).await;
+ let _ = sender
+ .send(AppEvent::OverallProgress((0, 1, Color::Red)))
+ .await;
database.remove_track_completely(id);
for ext in ["mp3", "m4a", "wav", "aif"].iter() {
let dest = get_full_track_location(PathBuf::from(ipod_path.clone()), id, ext);
let _ = std::fs::remove_file(dest);
}
- let _ = sender.send(AppEvent::OverallProgress((1, 1))).await;
+ let _ = sender
+ .send(AppEvent::OverallProgress((1, 1, Color::Red)))
+ .await;
let _ = sender
.send(AppEvent::SwitchScreen(AppState::MainScreen))
@@ -305,7 +329,11 @@ async fn load_files_from_fs_as_playlist(
for (i, file) in files.iter().enumerate() {
let _ = sender
- .send(AppEvent::OverallProgress((i as u32, files.len() as u32)))
+ .send(AppEvent::OverallProgress((
+ i as u32,
+ files.len() as u32,
+ Color::Green,
+ )))
.await;
let id = load_from_fs(file.clone(), database, sender, ipod_path.clone()).await;
@@ -333,7 +361,11 @@ async fn load_files_from_fs(
) {
for (i, file) in files.iter().enumerate() {
let _ = sender
- .send(AppEvent::OverallProgress((i as u32, files.len() as u32)))
+ .send(AppEvent::OverallProgress((
+ i as u32,
+ files.len() as u32,
+ Color::Green,
+ )))
.await;
load_from_fs(file.clone(), database, sender, ipod_path.clone()).await;
}
@@ -347,7 +379,7 @@ async fn load_from_fs(
) -> u32 {
let tag = Tag::new().read_from_path(&path).unwrap();
- let id = database.get_unique_id();
+ let mut id = database.get_unique_id();
let audio_file = audio_file_info::from_path(path.to_str().unwrap())
.await
@@ -356,75 +388,86 @@ async fn load_from_fs(
let song_dbid = util::hash_from_path(path.clone());
- let mut track = XTrackItem::new(
- id,
- audio_info.audio_bytes as u32,
- (audio_info.duration * 1000.0) as u32,
- tag.year().unwrap_or(0) as u32,
- (audio_info.bit_rate / 1000) as u32,
- audio_info.sample_rate as u32,
- song_dbid,
- 0,
- );
+ if !database.if_track_in_library(song_dbid) {
+ let mut track = XTrackItem::new(
+ id,
+ audio_info.audio_bytes as u32,
+ (audio_info.duration * 1000.0) as u32,
+ tag.year().unwrap_or(0) as u32,
+ (audio_info.bit_rate / 1000) as u32,
+ audio_info.sample_rate as u32,
+ song_dbid,
+ 0,
+ );
- audio_file.modify_xtrack(&mut track);
+ audio_file.modify_xtrack(&mut track);
- if let Some(title) = tag.title() {
- track.set_title(title.to_string());
- } else {
- track.set_title(path.file_name().unwrap().to_str().unwrap().to_string());
+ if let Some(title) = tag.title() {
+ track.set_title(title.to_string());
+ } else {
+ track.set_title(path.file_name().unwrap().to_str().unwrap().to_string());
+ }
+
+ if let Some(genre) = tag.genre() {
+ track.set_genre(genre.to_string());
+ }
+
+ if let Some(artist) = tag.artist() {
+ track.set_artist(artist.to_string());
+ }
+
+ if let Some(cover) = tag.album_cover() {
+ let _ = sender.send(AppEvent::ArtworkProgress((0, 2))).await;
+
+ let mut adb = get_artwork_db(&ipod_path);
+
+ let cover_hash = util::hash(cover.data);
+
+ let if_cover_present = adb.if_cover_present(cover_hash);
+
+ let (small_img_name, large_img_name) = adb.add_images(song_dbid, cover_hash);
+
+ let size = cover.data.len();
+
+ if !if_cover_present {
+ make_cover_image(cover.data, &ipod_path, &small_img_name, (100, 100));
+ let _ = sender.send(AppEvent::ArtworkProgress((1, 2))).await;
+ make_cover_image(cover.data, &ipod_path, &large_img_name, (200, 200));
+ }
+
+ write_artwork_db(adb, &ipod_path);
+
+ track.data.artwork_size = size as u32;
+ track.data.mhii_link = 0;
+ track.data.has_artwork = 1;
+ track.data.artwork_count = 1;
+
+ let _ = sender.send(AppEvent::ArtworkProgress((2, 2))).await;
+ }
+
+ if let Some(album) = tag.album() {
+ track.set_album(album.title.to_string());
+ // TODO: Add new album into iTunesDB
+ }
+
+ track.set_location(get_track_location(
+ track.data.unique_id,
+ audio_file.get_audio_extension(),
+ ));
+
+ let dest = get_full_track_location(
+ PathBuf::from(ipod_path.clone()),
+ track.data.unique_id,
+ audio_file.get_audio_extension(),
+ );
+
+ let _ = std::fs::copy(path.to_str().unwrap(), dest.to_str().unwrap());
+
+ database.add_track(track);
+ } else if let Some(unique_id) = database.get_unique_id_by_dbid(song_dbid) {
+ id = unique_id;
}
- if let Some(genre) = tag.genre() {
- track.set_genre(genre.to_string());
- }
-
- if let Some(artist) = tag.artist() {
- track.set_artist(artist.to_string());
- }
-
- if let Some(cover) = tag.album_cover() {
- let mut adb = get_artwork_db(&ipod_path);
-
- let (small_img_name, large_img_name) = adb.add_images(song_dbid, util::hash(cover.data));
-
- let mut dst = PathBuf::from(&ipod_path);
- dst.push("iPod_Control");
- dst.push("Artwork");
-
- let size = cover.data.len();
-
- make_cover_image(cover.data, &ipod_path, &small_img_name, (100, 100));
- make_cover_image(cover.data, &ipod_path, &large_img_name, (200, 200));
-
- write_artwork_db(adb, &ipod_path);
-
- track.data.artwork_size = size as u32;
- track.data.mhii_link = 0;
- track.data.has_artwork = 1;
- track.data.artwork_count = 1;
- }
-
- if let Some(album) = tag.album() {
- track.set_album(album.title.to_string());
- // TODO: Add new album into iTunesDB
- }
-
- track.set_location(get_track_location(
- track.data.unique_id,
- audio_file.get_audio_extension(),
- ));
-
- let dest = get_full_track_location(
- PathBuf::from(ipod_path.clone()),
- track.data.unique_id,
- audio_file.get_audio_extension(),
- );
-
- let _ = std::fs::copy(path.to_str().unwrap(), dest.to_str().unwrap());
-
- database.add_track(track);
-
let _ = sender
.send(AppEvent::SwitchScreen(AppState::MainScreen))
.await;
@@ -522,18 +565,20 @@ async fn download_track(
{
let p: PathBuf = Path::new(&ipod_path).into();
- if let Some(mut t) = track_from_soundcloud(&track, ipod_path.clone()).await {
- t.data.unique_id = database.get_unique_id();
- t.set_location(get_track_location(t.data.unique_id, "mp3"));
- let dest = get_full_track_location(p.clone(), t.data.unique_id, "mp3");
+ if let Some(mut t) = track_from_soundcloud(&track, ipod_path.clone(), sender).await {
+ if !database.if_track_in_library(t.data.dbid) {
+ t.data.unique_id = database.get_unique_id();
+ t.set_location(get_track_location(t.data.unique_id, "mp3"));
+ let dest = get_full_track_location(p.clone(), t.data.unique_id, "mp3");
- let mut track_path = get_temp_dl_dir();
- track_path.push(track.id.to_string());
- track_path.set_extension("mp3");
+ let mut track_path = get_temp_dl_dir();
+ track_path.push(track.id.to_string());
+ track_path.set_extension("mp3");
- let _ = std::fs::copy(track_path.to_str().unwrap(), dest.to_str().unwrap());
+ let _ = std::fs::copy(track_path.to_str().unwrap(), dest.to_str().unwrap());
- database.add_track(t);
+ database.add_track(t);
+ }
}
}
@@ -572,18 +617,21 @@ async fn download_playlist(
if track.title.is_none() {
continue;
}
- if let Some(mut t) = track_from_soundcloud(&track, ipod_path.clone()).await {
- t.data.unique_id = database.get_unique_id();
- new_playlist.add_elem(t.data.unique_id);
- t.set_location(get_track_location(t.data.unique_id, "mp3"));
- let dest = get_full_track_location(p.clone(), t.data.unique_id, "mp3");
- let mut track_path = get_temp_dl_dir();
- track_path.push(track.id.to_string());
- track_path.set_extension("mp3");
+ if let Some(mut t) = track_from_soundcloud(&track, ipod_path.clone(), sender).await {
+ if !database.if_track_in_library(t.data.dbid) {
+ t.data.unique_id = database.get_unique_id();
+ new_playlist.add_elem(t.data.unique_id);
+ t.set_location(get_track_location(t.data.unique_id, "mp3"));
+ let dest = get_full_track_location(p.clone(), t.data.unique_id, "mp3");
+ let mut track_path = get_temp_dl_dir();
+ track_path.push(track.id.to_string());
+ track_path.set_extension("mp3");
- let _ = std::fs::copy(track_path.to_str().unwrap(), dest.to_str().unwrap());
-
- database.add_track(t);
+ let _ = std::fs::copy(track_path.to_str().unwrap(), dest.to_str().unwrap());
+ database.add_track(t);
+ } else if let Some(unique_id) = database.get_unique_id_by_dbid(t.data.dbid) {
+ new_playlist.add_elem(unique_id);
+ }
}
}
@@ -663,14 +711,17 @@ async fn parse_itunes(sender: &Sender, path: String) -> XDatabase {
let mut playlists = playlists.collection;
for playlist in playlists.iter_mut() {
- if let Ok(tracks) = soundcloud::get_tracks(
- playlist.tracks.clone(),
- client_id.clone(),
- app_version.clone(),
- )
- .await
- {
- playlist.tracks = tracks;
+ let trr = playlist.tracks.clone();
+ playlist.tracks = Vec::new();
+ for pl_tracks in trr.clone().chunks(45) {
+ if let Ok(tracks) =
+ soundcloud::get_tracks(pl_tracks.to_vec(), client_id.clone(), app_version.clone())
+ .await
+ {
+ let mut tracks = tracks;
+ tracks.retain(|t| t.title.is_some());
+ playlist.tracks.append(&mut tracks);
+ }
}
}