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"
|
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1021,8 +1021,8 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itunesdb"
|
name = "itunesdb"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
source = "git+https://gitea.awain.net/alterwain/ITunesDB.git#5a6ca7a9f5eca42959e3498a6eb2700f502b5509"
|
source = "git+https://gitea.awain.net/alterwain/ITunesDB.git#2db99df934c29f03b842a43245f1e93d7d4ade27"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
@ -1662,7 +1662,7 @@ dependencies = [
|
|||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2029,7 +2029,7 @@ dependencies = [
|
|||||||
"getrandom 0.3.1",
|
"getrandom 0.3.1",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2532,7 +2532,7 @@ version = "0.1.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -23,7 +23,7 @@ tokio = { version = "1", features = ["full"] }
|
|||||||
tokio-util = { version = "0.7.12", features = ["codec"] }
|
tokio-util = { version = "0.7.12", features = ["codec"] }
|
||||||
strum = { version = "0.27", features = ["derive"] }
|
strum = { version = "0.27", features = ["derive"] }
|
||||||
soundcloud = { version = "0.1.4", git = "https://gitea.awain.net/alterwain/soundcloud_api.git" }
|
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"
|
ureq = "3.0.5"
|
||||||
color-thief = "0.2"
|
color-thief = "0.2"
|
||||||
redb = "2.4.0"
|
redb = "2.4.0"
|
||||||
|
32
src/db.rs
32
src/db.rs
@ -1,5 +1,6 @@
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
|
||||||
|
use itunesdb::xobjects::{XArgument, XTrackItem};
|
||||||
use md5::{Digest, Md5};
|
use md5::{Digest, Md5};
|
||||||
use redb::{Database, Error, ReadableTable, TableDefinition};
|
use redb::{Database, Error, ReadableTable, TableDefinition};
|
||||||
use serde::{Deserialize, Serialize};
|
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
|
// TODO: implement From (or Into) for Track, convert from Soundcloud Audio or iTunes
|
||||||
|
|
||||||
pub fn init_db() -> Database {
|
pub fn init_db() -> Database {
|
||||||
|
@ -263,6 +263,32 @@ impl MainScreen {
|
|||||||
}
|
}
|
||||||
v
|
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(),
|
_ => Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
113
src/sync.rs
113
src/sync.rs
@ -1,6 +1,7 @@
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use itunesdb::xobjects::XDatabase;
|
use itunesdb::xobjects::{XDatabase, XSomeList};
|
||||||
|
use redb::Database;
|
||||||
use soundcloud::sobjects::{CloudPlaylist, CloudPlaylists};
|
use soundcloud::sobjects::{CloudPlaylist, CloudPlaylists};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
fs::File,
|
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;
|
let _ = sender.send(AppEvent::IPodFound("/Users/michael/Documents/ipod/iTunes/iTunesDB".to_string())).await;
|
||||||
},
|
},
|
||||||
AppEvent::ParseItunes(path) => {
|
AppEvent::ParseItunes(path) => parse_itunes(&database, &sender, path).await,
|
||||||
// todo: parse itunes
|
AppEvent::DownloadPlaylist(playlist) => download_playlist(playlist, &database, &sender).await,
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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