feat: add scan subcommand

This commit is contained in:
Tsiry Sandratraina
2022-09-18 19:59:50 +00:00
parent f9978b28ad
commit 3975bda9a9
6 changed files with 98 additions and 2 deletions

7
Cargo.lock generated
View File

@@ -1551,9 +1551,12 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
[[package]]
name = "music-player"
version = "0.1.2"
version = "0.1.3"
dependencies = [
"clap",
"futures",
"lofty",
"md5",
"music-player-addons",
"music-player-entity",
"music-player-migration",
@@ -1563,6 +1566,8 @@ dependencies = [
"music-player-settings",
"music-player-storage",
"music-player-tracklist",
"owo-colors",
"sea-orm",
"sea-orm-migration",
"tokio",
]

View File

@@ -1,6 +1,6 @@
[package]
name = "music-player"
version = "0.1.2"
version = "0.1.3"
edition = "2021"
repository = "https://github.com/tsirysndr/music-player"
license = "MIT"
@@ -69,3 +69,8 @@ features = [
[dependencies]
clap = "3.2.20"
tokio = { version = "1.21.0", features = ["full"] }
md5 = "0.7.0"
sea-orm = { version = "0.9.2", features = ["runtime-tokio-rustls", "sqlx-sqlite"] }
futures = "0.3.24"
lofty = "0.8.1"
owo-colors = "3.5.0"

View File

@@ -29,6 +29,10 @@ Note: This is a work in progress.
This is a simple music player that I made for my own use. It is written in Rust and uses [rodio](https://github.com/RustAudio/rodio), [symphonia](https://github.com/pdeljanov/Symphonia), and [gRPC](https://grpc.io/) libraries.
<p style="margin-top: 20px; margin-bottom: 20px;">
<img src="./preview.svg" width="800" />
</p>
## Installation
```bash

1
preview.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 371 KiB

View File

@@ -7,8 +7,11 @@ use music_player_playback::{
player::{Player, PlayerEngine},
};
use music_player_server::server::MusicPlayerServer;
use scan::scan_music_library;
use tokio::sync::Mutex;
mod scan;
fn cli() -> Command<'static> {
const VERSION: &str = env!("CARGO_PKG_VERSION");
Command::new("music-player")
@@ -30,6 +33,7 @@ A simple music player written in Rust"#,
.about("Play a song")
.arg_from_usage("<song> 'The path to the song'"),
)
.subcommand(Command::new("scan").about("Scan music library: $HOME/Music"))
}
#[tokio::main]
@@ -50,6 +54,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
return Ok(());
}
if let Some(_matches) = matches.subcommand_matches("scan") {
scan_music_library().await.map_err(|e| e.to_string())?;
return Ok(());
}
migration::run().await;
MusicPlayerServer::new(Arc::new(Mutex::new(player)))

72
src/scan.rs Normal file
View File

@@ -0,0 +1,72 @@
use futures::future::FutureExt;
use music_player_entity::{album, artist, track};
use music_player_scanner::scan_directory;
use music_player_scanner::types::Song;
use owo_colors::OwoColorize;
use sea_orm::{ActiveModelTrait, ActiveValue};
pub async fn scan_music_library() -> Result<Vec<Song>, lofty::error::LoftyError> {
scan_directory(move |song, db| {
async move {
let id = format!("{:x}", md5::compute(song.artist.to_string()));
let item = artist::ActiveModel {
id: ActiveValue::set(id),
name: ActiveValue::Set(song.artist.clone()),
};
match item.insert(db.get_connection()).await {
Ok(_) => (),
Err(_) => (),
}
let id = format!(
"{:x}",
md5::compute(format!("{}{}", song.album, song.artist))
);
let item = album::ActiveModel {
id: ActiveValue::set(id),
title: ActiveValue::Set(song.album.clone()),
artist: ActiveValue::Set(song.artist.clone()),
artist_id: ActiveValue::Set(Some(format!(
"{:x}",
md5::compute(song.artist.to_string())
))),
};
match item.insert(db.get_connection()).await {
Ok(_) => (),
Err(_) => (),
}
let id = format!("{:x}", md5::compute(song.uri.as_ref().unwrap()));
let item = track::ActiveModel {
id: ActiveValue::set(id),
title: ActiveValue::Set(song.title.clone()),
artist: ActiveValue::Set(song.artist.clone()),
album: ActiveValue::Set(song.album.clone()),
genre: ActiveValue::Set(song.genre.clone()),
year: ActiveValue::Set(song.year),
track: ActiveValue::Set(song.track),
bitrate: ActiveValue::Set(song.bitrate),
sample_rate: ActiveValue::Set(song.sample_rate),
bit_depth: ActiveValue::Set(song.bit_depth),
channels: ActiveValue::Set(song.channels),
duration: ActiveValue::Set(Some(song.duration.as_secs_f32())),
uri: ActiveValue::Set(song.uri.clone().unwrap_or_default()),
album_id: ActiveValue::Set(Some(format!(
"{:x}",
md5::compute(format!("{}{}", song.album, song.artist))
))),
};
let filename = song.uri.as_ref().unwrap().split("/").last().unwrap();
let path = song.uri.as_ref().unwrap().replace(filename, "");
println!("{}{}", path, filename.magenta());
match item.insert(db.get_connection()).await {
Ok(_) => (),
Err(_) => (),
}
}
.boxed()
})
.await
}