diff --git a/Cargo.lock b/Cargo.lock index d02cc58..bbe0240 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -265,6 +265,27 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.59.0", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -807,7 +828,7 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "itunesdb" version = "0.1.0" -source = "git+https://gitea.awain.net/alterwain/ITunesDB.git#de2c8bb1be0656557427214f91e57aa7bb3e673b" +source = "git+https://gitea.awain.net/alterwain/ITunesDB.git#9e20fe785dc9cd1268641dad9730a8fb3ff246c5" dependencies = [ "bincode", "env_logger", @@ -839,6 +860,16 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", +] + [[package]] name = "libusb1-sys" version = "0.7.0" @@ -894,13 +925,16 @@ version = "0.1.0" dependencies = [ "color-eyre", "crossterm", + "dirs", "itunesdb", "ratatui", "regex", "rusb", + "serde", "soundcloud", "tokio", "tokio-util", + "toml", ] [[package]] @@ -1027,6 +1061,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "owo-colors" version = "3.5.0" @@ -1180,6 +1220,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_users" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +dependencies = [ + "getrandom 0.2.15", + "libredox", + "thiserror", +] + [[package]] name = "regex" version = "1.11.1" @@ -1418,6 +1469,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1628,7 +1688,7 @@ dependencies = [ "getrandom 0.3.1", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1640,6 +1700,26 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thiserror" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -1743,6 +1823,40 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02a8b472d1a3d7c18e2d61a489aee3453fd9031c33e4f55bd533f4a7adca1bee" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.5.2" @@ -2020,7 +2134,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2141,6 +2255,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86e376c75f4f43f44db463cf729e0d3acbf954d13e22c51e26e4c264b4ab545f" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen-rt" version = "0.33.0" diff --git a/Cargo.toml b/Cargo.toml index 0b61b7d..f54c06e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,9 @@ authors = ["Michael Wain "] [dependencies] rusb = "0.9.4" +dirs = "6.0.0" +toml = "0.8.20" +serde = "1.0.217" regex = "1.11.1" ratatui = { version = "0.29.0", features = ["all-widgets"] } color-eyre = "0.6.3" diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..7406d12 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,27 @@ +use serde::Deserialize; + +#[derive(Debug, Deserialize)] +struct YouTubeConfiguration { + pub user_id: u64 +} + +#[derive(Debug, Deserialize)] +struct SoundCloudConfiguration { + pub user_id: u64 +} + +#[derive(Debug, Deserialize)] +pub struct LyricaConfiguration { + soundcloud: SoundCloudConfiguration, + youtube: YouTubeConfiguration +} + +impl LyricaConfiguration { + pub fn get_soundcloud(&self) -> &SoundCloudConfiguration { + &self.soundcloud + } + + pub fn get_youtube(&self) -> &YouTubeConfiguration { + &self.youtube + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index ae6f6e9..7cee4e5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,21 @@ -use std::{error::Error, io}; +use std::{error::Error, io, path::{Path, PathBuf}}; use color_eyre::Result; use crossterm::{event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEvent, KeyEventKind}, execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}}; use ratatui::{buffer::Buffer, layout::Rect, prelude::{Backend, CrosstermBackend}, style::Stylize, symbols::border, text::{Line, Text}, widgets::{Block, Paragraph, Widget}, DefaultTerminal, Frame, Terminal}; -use tokio::sync::mpsc::{self, Receiver, Sender, UnboundedReceiver, UnboundedSender}; +use tokio::{fs::File, io::AsyncReadExt, sync::mpsc::{self, Receiver, Sender, UnboundedReceiver, UnboundedSender}}; use tokio_util::sync::CancellationToken; +use itunesdb::xobjects::XDatabase; + mod util; +mod config; + +fn get_configs_dir() -> PathBuf { + let mut p = dirs::home_dir().unwrap(); + p.push(".lyrica"); + p +} #[derive(Debug, Clone)] enum AppState { @@ -21,6 +30,8 @@ enum AppEvent { SearchIPod, IPodFound(String), IPodNotFound, + ParseItunes(String), + ITunesParsed(XDatabase) } fn initialize_async_service(sender: Sender, receiver: UnboundedReceiver, token: CancellationToken) { @@ -39,6 +50,26 @@ fn initialize_async_service(sender: Sender, receiver: UnboundedReceive let _ = sender.send(AppEvent::IPodNotFound).await; } }, + AppEvent::ParseItunes(path) => { + // todo: parse itunes + let _ = std::fs::create_dir_all(get_configs_dir()); + let mut cd = get_configs_dir(); + cd.push("idb"); + /*let mut p = get_configs_dir(); + p.push("config"); + p.set_extension(".toml"); + p.exists()*/ + let mut 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; + }, _ => {} } } @@ -90,7 +121,8 @@ impl App { if let Ok(event) = self.receiver.try_recv() { match event { AppEvent::IPodFound(path) => { - self.state = AppState::MainScreen(path); + self.state = AppState::MainScreen(path.clone()); + let _ = self.sender.send(AppEvent::ParseItunes(path)); }, AppEvent::IPodNotFound => { let _ = self.sender.send(AppEvent::SearchIPod); @@ -128,7 +160,7 @@ impl AppState { vec![ Line::from( vec![ - "Found iPod...".into(), + "Parsing iTunesDB...".into(), path.blue().bold() ] )