tranxuanthang / lrcget

Utility for mass-downloading LRC synced lyrics for your offline music library.
MIT License
535 stars 20 forks source link

Select multiple library directories #84

Open gryffyn opened 1 month ago

gryffyn commented 1 month ago

Currently, adding directories to scan has to be done one at a time. Would it be possible to allow selecting multiple directories at the same time?

p0lygun commented 1 month ago

would it not be easier to make a parent dir (say music) and add symlinks to all you music dirs in that, then lrcget will pick all of them and you will have to choose only one.

EDIT: looks like the app does not work on symlinks, IMO it should support them

p0lygun commented 1 month ago

well it works fine with WalkDir image

diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock
index 15d1001..f67793e 100644
--- a/src-tauri/Cargo.lock
+++ b/src-tauri/Cargo.lock
@@ -1907,6 +1907,7 @@ dependencies = [
  "tauri-build",
  "thiserror",
  "tokio",
+ "walkdir",
 ]

 [[package]]
diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index 041accb..d6ab5f3 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -31,6 +31,7 @@ data-encoding = "2.4.0"
 kira = "0.8.7"
 symphonia = { version = "0.5.2", features = ["all"] }
 regex = "1.10.4"
+walkdir = "2"

 [features]
 # by default Tauri runs in production mode
diff --git a/src-tauri/src/fs_track.rs b/src-tauri/src/fs_track.rs
index 9d776a6..e5de178 100644
--- a/src-tauri/src/fs_track.rs
+++ b/src-tauri/src/fs_track.rs
@@ -13,6 +13,7 @@ use thiserror::Error;
 use std::time::Instant;
 use crate::db;
 use tauri::Manager;
+use walkdir::WalkDir;

 #[derive(Serialize, Deserialize, Clone, Debug)]
 pub struct FsTrack {
@@ -199,19 +200,25 @@ pub fn load_tracks_from_directories(directories: &Vec<String>, conn: &mut Connec
   let mut files_scanned: usize = 0;
   for directory in directories.iter() {
     let mut entry_batch: Vec<DirEntry> = vec![];
-    let globwalker = glob(format!("{}/**/*.{{mp3,m4a,flac,ogg,opus,wav,MP3,M4A,FLAC,OGG,OPUS,WAV}}", directory))?;
-    for item in globwalker {
-      let entry = item?;
-      entry_batch.push(entry);
-      if entry_batch.len() == 100 {
-        let tracks = load_tracks_from_entry_batch(&entry_batch)?;
-
-        db::add_tracks(&tracks, conn)?;
-        files_scanned += entry_batch.len();
-        app_handle.emit_all("initialize-progress", ScanProgress { progress: None, files_scanned, files_count: Some(files_count) }).unwrap();
-        entry_batch.clear();
+    for entry in WalkDir::new(directory).follow_links(true).into_iter().filter_map(Result::ok) {
+      if let Some(extension) = entry.path().extension() {
+          match extension.to_str().unwrap_or("").to_lowercase().as_str() {
+              "mp3" | "m4a" | "flac" | "ogg" | "opus" | "wav" => {
+                  entry_batch.push(entry);
+              },
+              _ => {}
+          }
       }
+    if entry_batch.len() == 100 {
+      let tracks = load_tracks_from_entry_batch(&entry_batch)?;
+
+      db::add_tracks(&tracks, conn)?;
+      files_scanned += entry_batch.len();
+      app_handle.emit_all("initialize-progress", ScanProgress { progress: None, files_scanned, files_count: Some(files_count) }).unwrap();
+      entry_batch.clear();
     }
+  }
+
     let tracks = load_tracks_from_entry_batch(&entry_batch)?;
     db::add_tracks(&tracks, conn)?;
     files_scanned += entry_batch.len();
@@ -222,11 +229,25 @@ pub fn load_tracks_from_directories(directories: &Vec<String>, conn: &mut Connec
   Ok(())
 }

+
 pub fn count_files_from_directories(directories: &Vec<String>) -> Result<usize> {
   let mut files_count = 0;
+
   for directory in directories.iter() {
-    let files_in_dir = glob(format!("{}/**/*.{{mp3,m4a,flac,ogg,opus,wav,MP3,M4A,FLAC,OGG,OPUS,WAV}}", directory))?;
-    files_count += files_in_dir.into_iter().count();
+      println!("Scanning directory: {}", directory);
+
+      for entry in WalkDir::new(directory).follow_links(true).into_iter().filter_map(Result::ok) {
+          let path = entry.path();
+
+          if let Some(extension) = path.extension() {
+              match extension.to_str().unwrap_or("").to_lowercase().as_str() {
+                  "mp3" | "m4a" | "flac" | "ogg" | "opus" | "wav" => {
+                      files_count += 1;
+                  },
+                  _ => {}
+              }
+          }
+      }
   }

   Ok(files_count)
gryffyn commented 1 month ago

It would, yes. My music is already in folders that way (well, without the symlinks). I don't want to load my entire music library at once though.

tranxuanthang commented 1 month ago

@p0lygun Overall it looks good, but I need some more time to test and review, and to compare performance and pros/cons between walkdir and globwalk crates. Would you like to create a PR for this?

p0lygun commented 1 month ago

yh, i dont mind, but i also dont like have two packages that do the same thing, so i'll probably do a migration to walkdir and we can test that PR