A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 109 lines 3.6 kB view raw
1use std::{fs, thread}; 2 3use anyhow::Error; 4use rockbox_settings::get_music_dir; 5 6use crate::{consts::AUDIO_EXTENSIONS, Context}; 7 8pub fn read_dir( 9 ctx: Context, 10 path: String, 11 recursive: bool, 12 with_metadata: bool, 13) -> Result<String, Error> { 14 let music_dir = get_music_dir()?; 15 let mut files = String::new(); 16 17 fn read_dir_recursive( 18 ctx: &Context, 19 path: String, 20 music_dir: &str, 21 recursive: bool, 22 files: &mut String, 23 with_metadata: bool, 24 ) -> Result<(), Error> { 25 for entry in fs::read_dir(path)? { 26 let entry = entry?; 27 let path = entry.path(); 28 let path_str = path.to_str().unwrap().to_string(); 29 30 if path.is_dir() { 31 if recursive { 32 read_dir_recursive( 33 ctx, 34 path_str.clone(), 35 music_dir, 36 recursive, 37 files, 38 with_metadata, 39 )?; 40 } 41 } 42 43 if AUDIO_EXTENSIONS.iter().any(|ext| path_str.ends_with(ext)) || path.is_dir() { 44 let last_modified = entry.metadata()?.modified()?; 45 let last_modified = chrono::DateTime::from_timestamp( 46 last_modified 47 .duration_since(std::time::UNIX_EPOCH)? 48 .as_secs() as i64, 49 0, 50 ) 51 .unwrap(); 52 53 let last_modified = last_modified.format("%Y-%m-%dT%H:%M:%SZ").to_string(); 54 let entry_str = path_str.replace(music_dir, ""); 55 let entry_str = if entry_str.starts_with('/') { 56 &entry_str[1..] 57 } else { 58 &entry_str 59 }; 60 61 let mut metadata = format!( 62 "{}: {}\nLast-Modified: {}\n", 63 if path.is_dir() { "directory" } else { "file" }, 64 entry_str, 65 last_modified 66 ); 67 68 if !with_metadata { 69 files.push_str(&metadata); 70 continue; 71 } 72 73 let kv = ctx.kv.clone(); 74 let track = thread::spawn(move || { 75 let rt = tokio::runtime::Runtime::new().unwrap(); 76 let kv_clone = kv.clone(); 77 let kv = rt.block_on(kv_clone.lock()); 78 let track = kv.get(&path_str); 79 track.map(|x| x.clone()) 80 }) 81 .join() 82 .unwrap(); 83 84 if let Some(track) = track { 85 metadata.push_str(&format!( 86 "Title: {}\nArtist: {}\nAlbum: {}\nTime: {}\nDuration: {}\n", 87 track.title, 88 track.artist, 89 track.album, 90 (track.length / 1000) as u32, 91 track.length / 1000 92 )); 93 if let Some(track_number) = track.track_number { 94 metadata.push_str(&format!("Track: {}\n", track_number)); 95 } 96 97 if let Some(year) = track.year { 98 metadata.push_str(&format!("Date: {}\n", year)); 99 } 100 } 101 files.push_str(&metadata); 102 } 103 } 104 Ok(()) 105 } 106 107 read_dir_recursive(&ctx, path, &music_dir, recursive, &mut files, with_metadata)?; 108 Ok(files) 109}