modified: Cargo.lock
modified: Cargo.toml modified: src/db.rs modified: src/main_screen.rs modified: src/sync.rs
This commit is contained in:
parent
a72a7b8a25
commit
b34032d228
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -433,7 +433,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1021,8 +1021,8 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
||||
|
||||
[[package]]
|
||||
name = "itunesdb"
|
||||
version = "0.1.1"
|
||||
source = "git+https://gitea.awain.net/alterwain/ITunesDB.git#5a6ca7a9f5eca42959e3498a6eb2700f502b5509"
|
||||
version = "0.1.2"
|
||||
source = "git+https://gitea.awain.net/alterwain/ITunesDB.git#2db99df934c29f03b842a43245f1e93d7d4ade27"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"env_logger",
|
||||
@ -1662,7 +1662,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2029,7 +2029,7 @@ dependencies = [
|
||||
"getrandom 0.3.1",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2532,7 +2532,7 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -23,7 +23,7 @@ tokio = { version = "1", features = ["full"] }
|
||||
tokio-util = { version = "0.7.12", features = ["codec"] }
|
||||
strum = { version = "0.27", features = ["derive"] }
|
||||
soundcloud = { version = "0.1.4", git = "https://gitea.awain.net/alterwain/soundcloud_api.git" }
|
||||
itunesdb = { version = "0.1.1", git = "https://gitea.awain.net/alterwain/ITunesDB.git" }
|
||||
itunesdb = { version = "0.1.2", git = "https://gitea.awain.net/alterwain/ITunesDB.git" }
|
||||
ureq = "3.0.5"
|
||||
color-thief = "0.2"
|
||||
redb = "2.4.0"
|
||||
|
32
src/db.rs
32
src/db.rs
@ -1,5 +1,6 @@
|
||||
use std::fs::File;
|
||||
|
||||
use itunesdb::xobjects::{XArgument, XTrackItem};
|
||||
use md5::{Digest, Md5};
|
||||
use redb::{Database, Error, ReadableTable, TableDefinition};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -66,6 +67,37 @@ impl From<CloudTrack> for Track {
|
||||
}
|
||||
}
|
||||
|
||||
fn find_str_arg(value: &XTrackItem, arg_type: u32) -> Option<&XArgument> {
|
||||
value.args.iter().find(|arg| arg.arg_type == arg_type)
|
||||
}
|
||||
|
||||
impl From<XTrackItem> for Track {
|
||||
fn from(value: XTrackItem) -> Self {
|
||||
Track {
|
||||
unique_id: value.data.unique_id,
|
||||
filetype: value.data.filetype,
|
||||
stars: value.data.stars,
|
||||
last_modified_time: value.data.last_modified_time,
|
||||
size: value.data.size,
|
||||
length: value.data.length,
|
||||
year: value.data.year,
|
||||
bitrate: value.data.bitrate,
|
||||
sample_rate: value.data.sample_rate,
|
||||
play_count: value.data.play_count,
|
||||
dbid: value.data.dbid,
|
||||
bpm: value.data.bpm,
|
||||
skip_count: value.data.skip_count,
|
||||
has_artwork: value.data.has_artwork,
|
||||
media_type: value.data.media_type,
|
||||
title: find_str_arg(&value, 1).map_or(String::new(), |a| a.val.clone()),
|
||||
location: find_str_arg(&value, 2).map_or(String::new(), |a| a.val.clone()),
|
||||
album: find_str_arg(&value, 3).map_or(String::new(), |a| a.val.clone()),
|
||||
artist: find_str_arg(&value, 4).map_or(String::new(), |a| a.val.clone()),
|
||||
genre: find_str_arg(&value, 5).map_or(String::new(), |a| a.val.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement From (or Into) for Track, convert from Soundcloud Audio or iTunes
|
||||
|
||||
pub fn init_db() -> Database {
|
||||
|
@ -263,6 +263,32 @@ impl MainScreen {
|
||||
}
|
||||
v
|
||||
}
|
||||
2 => {
|
||||
// local
|
||||
/* let mut v = Vec::new();
|
||||
v.push(
|
||||
Row::new(vec!["Id", "Title", "Artist", "Bitrate", "Hash"])
|
||||
.style(Style::default().fg(Color::Gray)),
|
||||
);
|
||||
if let Some(s) = &self.soundcloud {
|
||||
for (i, playlist) in s.iter().enumerate() {
|
||||
let date: DateTime<Utc> = playlist.created_at.parse().unwrap();
|
||||
let mut row = Row::new(vec![
|
||||
playlist.id.to_string(),
|
||||
playlist.title.clone(),
|
||||
[playlist.track_count.to_string(), " songs".to_string()].concat(),
|
||||
format!("{}", date.format("%Y-%m-%d %H:%M")),
|
||||
"NO".to_string(),
|
||||
]);
|
||||
if self.selected_row == i as i32 {
|
||||
row = row.style(Style::default().bg(Color::Yellow));
|
||||
}
|
||||
v.push(row);
|
||||
}
|
||||
}
|
||||
v*/
|
||||
Vec::new()
|
||||
}
|
||||
_ => Vec::new(),
|
||||
};
|
||||
|
||||
|
113
src/sync.rs
113
src/sync.rs
@ -1,6 +1,7 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use itunesdb::xobjects::XDatabase;
|
||||
use itunesdb::xobjects::{XDatabase, XSomeList};
|
||||
use redb::Database;
|
||||
use soundcloud::sobjects::{CloudPlaylist, CloudPlaylists};
|
||||
use tokio::{
|
||||
fs::File,
|
||||
@ -55,49 +56,8 @@ pub fn initialize_async_service(
|
||||
}*/
|
||||
let _ = sender.send(AppEvent::IPodFound("/Users/michael/Documents/ipod/iTunes/iTunesDB".to_string())).await;
|
||||
},
|
||||
AppEvent::ParseItunes(path) => {
|
||||
// todo: parse itunes
|
||||
let cd = get_temp_itunesdb();
|
||||
let p: PathBuf = Path::new(&path).into();
|
||||
// p.push("iPod_Control");
|
||||
// p.push("iTunes");
|
||||
// p.set_file_name("iTunesDB");
|
||||
let _ = std::fs::copy(p, &cd);
|
||||
let mut file = File::open(cd).await.unwrap();
|
||||
let mut contents = vec![];
|
||||
file.read_to_end(&mut contents).await.unwrap();
|
||||
let xdb = itunesdb::deserializer::parse_bytes(&contents);
|
||||
let _ = sender.send(AppEvent::ITunesParsed(xdb)).await;
|
||||
|
||||
let p = get_config_path();
|
||||
if !p.exists() {
|
||||
let config = LyricaConfiguration::default();
|
||||
let cfg_str = toml::to_string_pretty(&config).unwrap();
|
||||
let mut file = File::create(&p).await.unwrap();
|
||||
file.write(cfg_str.as_bytes()).await;
|
||||
}
|
||||
let mut file = File::open(p).await.unwrap();
|
||||
let mut content = String::new();
|
||||
file.read_to_string(&mut content).await.unwrap();
|
||||
let config: LyricaConfiguration = toml::from_str(&content).unwrap();
|
||||
|
||||
let app_version = soundcloud::get_app().await.unwrap().unwrap();
|
||||
let client_id = soundcloud::get_client_id().await.unwrap().unwrap();
|
||||
let playlists = soundcloud::get_playlists(config.get_soundcloud().user_id, client_id, app_version).await.unwrap();
|
||||
|
||||
let _ = sender.send(AppEvent::SoundcloudGot(playlists)).await;
|
||||
},
|
||||
AppEvent::DownloadPlaylist(playlist) => {
|
||||
if let Ok(()) = dlp::download_from_soundcloud(&playlist.permalink_url, &get_temp_dl_dir(), sender.clone()).await {
|
||||
let tracks = playlist.tracks;
|
||||
for track in tracks {
|
||||
if track.title.is_none() { continue; }
|
||||
let mut t: Track = track.into();
|
||||
t.unique_id = db::get_last_track_id(&database).unwrap_or(80) + 1;
|
||||
let _ = db::insert_track(&database, t);
|
||||
}
|
||||
}
|
||||
},
|
||||
AppEvent::ParseItunes(path) => parse_itunes(&database, &sender, path).await,
|
||||
AppEvent::DownloadPlaylist(playlist) => download_playlist(playlist, &database, &sender).await,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@ -106,3 +66,68 @@ pub fn initialize_async_service(
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async fn download_playlist(
|
||||
playlist: CloudPlaylist,
|
||||
database: &Database,
|
||||
sender: &Sender<AppEvent>,
|
||||
) {
|
||||
if let Ok(()) =
|
||||
dlp::download_from_soundcloud(&playlist.permalink_url, &get_temp_dl_dir(), sender.clone())
|
||||
.await
|
||||
{
|
||||
let tracks = playlist.tracks;
|
||||
for track in tracks {
|
||||
if track.title.is_none() {
|
||||
continue;
|
||||
}
|
||||
let mut t: Track = track.into();
|
||||
t.unique_id = db::get_last_track_id(database).unwrap_or(80) + 1;
|
||||
let _ = db::insert_track(database, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn parse_itunes(database: &Database, sender: &Sender<AppEvent>, path: String) {
|
||||
// todo: parse itunes
|
||||
let cd = get_temp_itunesdb();
|
||||
let p: PathBuf = Path::new(&path).into();
|
||||
// p.push("iPod_Control");
|
||||
// p.push("iTunes");
|
||||
// p.set_file_name("iTunesDB");
|
||||
let _ = std::fs::copy(p, &cd);
|
||||
let mut file = File::open(cd).await.unwrap();
|
||||
let mut contents = vec![];
|
||||
file.read_to_end(&mut contents).await.unwrap();
|
||||
let mut xdb = itunesdb::deserializer::parse_bytes(&contents);
|
||||
|
||||
if let XSomeList::TrackList(tracks) = &xdb.find_dataset(1).child {
|
||||
for track in tracks {
|
||||
let t: Track = track.clone().into();
|
||||
let _ = db::insert_track(database, t);
|
||||
}
|
||||
}
|
||||
|
||||
let _ = sender.send(AppEvent::ITunesParsed(xdb)).await;
|
||||
|
||||
let p = get_config_path();
|
||||
if !p.exists() {
|
||||
let config = LyricaConfiguration::default();
|
||||
let cfg_str = toml::to_string_pretty(&config).unwrap();
|
||||
let mut file = File::create(&p).await.unwrap();
|
||||
file.write(cfg_str.as_bytes()).await;
|
||||
}
|
||||
let mut file = File::open(p).await.unwrap();
|
||||
let mut content = String::new();
|
||||
file.read_to_string(&mut content).await.unwrap();
|
||||
let config: LyricaConfiguration = toml::from_str(&content).unwrap();
|
||||
|
||||
let app_version = soundcloud::get_app().await.unwrap().unwrap();
|
||||
let client_id = soundcloud::get_client_id().await.unwrap().unwrap();
|
||||
let playlists =
|
||||
soundcloud::get_playlists(config.get_soundcloud().user_id, client_id, app_version)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let _ = sender.send(AppEvent::SoundcloudGot(playlists)).await;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user