From 4e36010d13603f6130428533f051f503ca065c69 Mon Sep 17 00:00:00 2001 From: Nickiel12 Date: Mon, 12 Dec 2022 22:30:03 -0800 Subject: [PATCH] featadded database operations --- Cargo.toml | 2 ++ src/db_operations.rs | 63 ++++++++++++++++++++++++++++++++++ src/file_operations.rs | 77 ++++++++++++++++++++---------------------- src/main.rs | 20 +++++++---- 4 files changed, 116 insertions(+), 46 deletions(-) create mode 100644 src/db_operations.rs diff --git a/Cargo.toml b/Cargo.toml index c241041..aea546b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,5 @@ serde = { version = "1.0.143", features = ["derive"] } serde_json = "1.0.83" rusqlite = {version="0.28.0", features=["bundled"]} scan_dir = "0.3.3" +derive_more = "0.99.17" +id3 = "1.5.1" diff --git a/src/db_operations.rs b/src/db_operations.rs new file mode 100644 index 0000000..dca1a65 --- /dev/null +++ b/src/db_operations.rs @@ -0,0 +1,63 @@ +use derive_more::From; +use rusqlite::{params, Connection, Params, Result}; + +use crate::file_operations::ItemTag; + +#[derive(From, Debug)] +pub enum DatabaseCreationError { + RusqliteError(rusqlite::Error), + IoError(std::io::Error), +} + +pub struct DBObject { + pub conn: Connection, +} + +impl DBObject { + pub fn new( + db_filepath: &std::path::PathBuf, + in_memory: bool, + ) -> Result { + let conn: Connection; + + std::fs::create_dir_all(db_filepath.parent().unwrap())?; + + if in_memory { + conn = Connection::open_in_memory()?; + } else { + conn = Connection::open(db_filepath)?; + } + + // CREATE TABLE IF NOT EXISTS comment ( + // id INTEGER PRIMARY KEY, + // email TEXT, + // author TEXT, + // text TEXT NOT NULL, + // timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, + // content_id TEXT NOT NULL, + // parent INTEGER + // ) + + conn.execute( + "CREATE TABLE IF NOT EXISTS musicinfo ( + path TEXT PRIMARY KEY, + title TEXT NOT NULL, + artist TEXT, + album TEXT, + album_artist TEXT + + )", + params![], + )?; + + Ok(DBObject { conn }) + } + + pub fn save_tag(self: &Self, tag: &ItemTag) -> Result<(), DatabaseCreationError> { + self.conn.execute( + "INSERT INTO musicinfo (path, title, artist, album, album_artist) VALUES ( ?1, ?2, ?3, ?4, ?5 )", + params![tag.path, tag.title, tag.artist, tag.album, tag.album_artist], + )?; + Ok(()) + } +} diff --git a/src/file_operations.rs b/src/file_operations.rs index 2992740..d7c3aad 100644 --- a/src/file_operations.rs +++ b/src/file_operations.rs @@ -1,3 +1,4 @@ +use id3::{Tag, TagLike}; use std::path::PathBuf; use scan_dir::ScanDir; @@ -73,49 +74,45 @@ impl Iterator for MusicScanner { } } -/// Recursivly scans the given root directory for files -/// WIP Function! All it does is print the directories -/// -/// # Examples -/// -/// ```rust -/// scan_music_dir("/home/Documents/RustedBeats"); -/// -///>>> "I found a directory src at .../src" -///>>> "I found a directory debug at .../debug" -///>>> "I found a file Cargo.toml at .../Cargo.toml" -///... -/// ``` -/// -pub fn scan_music_dir(root: String) -> Result<(), ()> { - let mut directories = Vec::::new(); - directories.push(root.into()); +pub struct ItemTag { + pub path: String, + pub title: String, + pub artist: String, + pub album: String, + pub album_artist: String, +} - while directories.len() != 0 { - let target = match directories.pop() { - Some(val) => val, - None => { - panic!("Whoa man this ai't right"); - } - }; +impl ItemTag { + pub fn new() -> Self { + ItemTag { + path: String::new(), + title: String::new(), + artist: String::new(), + album: String::new(), + album_artist: String::new(), + } + } +} - ScanDir::dirs() - .read(target.clone(), |iter| { - for (entry, name) in iter { - directories.push(entry.path()); - println!("I found a director {:?} at path {:?}", name, entry.path()); - } - }) - .unwrap(); +pub fn get_tag(filepath: &PathBuf) -> Result { + let tag = Tag::read_from_path(filepath)?; - ScanDir::files() - .read(target, |iter| { - for (entry, name) in iter { - println!("found file {:?} at path {:?}", name, entry.path()); - } - }) - .unwrap(); + let mut output_tag = ItemTag::new(); + output_tag.path = filepath.to_string_lossy().into_owned(); + + // Get a bunch of frames... + if let Some(artist) = tag.artist() { + output_tag.artist = artist.to_string(); + println!("artist: {}", artist); + } + if let Some(title) = tag.title() { + output_tag.title = title.to_string(); + println!("title: {}", title); + } + if let Some(album) = tag.album() { + output_tag.album = album.to_string(); + println!("album: {}", album); } - Ok(()) + Ok(output_tag) } diff --git a/src/main.rs b/src/main.rs index 883384b..7b0ed77 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,9 @@ +use std::path::PathBuf; + use clap::Parser; use dirs_next; +pub mod db_operations; pub mod file_operations; #[derive(Parser, Debug)] @@ -38,20 +41,25 @@ fn main() { let music_dir: String; if cli.root_directory.is_some() { music_dir = cli.root_directory.clone().unwrap(); - println!( - "Music directory is: {}", - cli.root_directory.clone().unwrap() - ); } else { music_dir = String::from(dirs_next::audio_dir().unwrap().to_str().unwrap()); - println!("Music directory is: {:?}", dirs_next::audio_dir()); } let music_scanner = file_operations::MusicScanner::new(music_dir); + let mut db_path = PathBuf::new(); + db_path.push("/home/nixolas/RustedBeats.db"); + + let dbo = db_operations::DBObject::new(&db_path, false).unwrap(); + for file_batch in music_scanner { for filepath in file_batch { - println!("{:?}", filepath); + if filepath.to_string_lossy().ends_with(".wav") { + continue; + } else { + let tag = file_operations::get_tag(&filepath).unwrap(); + dbo.save_tag(&tag).unwrap(); + } } }