added some utility functions
This commit is contained in:
parent
f4e8f4aca0
commit
33c4e7bd82
111
music_mgr/Cargo.lock
generated
111
music_mgr/Cargo.lock
generated
|
@ -266,15 +266,18 @@ dependencies = [
|
|||
name = "music_mgr"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anyhow",
|
||||
"camino",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -464,6 +467,59 @@ version = "0.11.0+wasi-snapshot-preview1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.56.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.56.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-result",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.56.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.56.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "749f0da9cc72d82e600d8d2e44cadd0b9eedb9038f71a1c58556ac1c5791813b"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
|
@ -479,7 +535,7 @@ version = "0.52.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.4",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -499,17 +555,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.4",
|
||||
"windows_aarch64_msvc 0.52.4",
|
||||
"windows_i686_gnu 0.52.4",
|
||||
"windows_i686_msvc 0.52.4",
|
||||
"windows_x86_64_gnu 0.52.4",
|
||||
"windows_x86_64_gnullvm 0.52.4",
|
||||
"windows_x86_64_msvc 0.52.4",
|
||||
"windows_aarch64_gnullvm 0.52.5",
|
||||
"windows_aarch64_msvc 0.52.5",
|
||||
"windows_i686_gnu 0.52.5",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.5",
|
||||
"windows_x86_64_gnu 0.52.5",
|
||||
"windows_x86_64_gnullvm 0.52.5",
|
||||
"windows_x86_64_msvc 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -520,9 +577,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
|
@ -532,9 +589,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
|
@ -544,9 +601,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
|||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
|
@ -556,9 +619,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
|||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
|
@ -568,9 +631,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
|||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
|
@ -580,9 +643,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
|||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
|
@ -592,6 +655,6 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
|||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
|
|
|
@ -6,12 +6,15 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anstyle = "1.0.6"
|
||||
anyhow = "1.0.81"
|
||||
camino = "1.1.6"
|
||||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
env_logger = "0.11.3"
|
||||
lazy_static = "1.4.0"
|
||||
libc = "0.2.153"
|
||||
log = "0.4.21"
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
serde_json = "1.0.115"
|
||||
tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread", "process", "sync"] }
|
||||
windows = { version = "0.56.0", features = ["Win32_Foundation", "Win32_Storage_FileSystem", "Win32_System_Console"] }
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use camino::Utf8PathBuf;
|
||||
use clap::{Parser, Subcommand};
|
||||
|
||||
use crate::util::isatty;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct CliArgs {
|
||||
/// Show more info
|
||||
|
@ -17,6 +19,9 @@ pub struct CliArgs {
|
|||
|
||||
#[command(subcommand)]
|
||||
pub command: Option<CliCommand>,
|
||||
|
||||
#[clap(skip)]
|
||||
pub is_tty: bool
|
||||
}
|
||||
|
||||
#[derive(Debug, Subcommand, Default)]
|
||||
|
@ -28,4 +33,11 @@ pub enum CliCommand {
|
|||
name: String,
|
||||
genre: String
|
||||
}
|
||||
}
|
||||
|
||||
impl CliArgs {
|
||||
pub fn populate_extra(&mut self) -> &mut Self{
|
||||
self.is_tty = isatty();
|
||||
self
|
||||
}
|
||||
}
|
22
music_mgr/src/commands/mod.rs
Normal file
22
music_mgr/src/commands/mod.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
use crate::{cli::{CliArgs, CliCommand}, downloader::Downloader, manifest::Manifest, util};
|
||||
|
||||
|
||||
pub async fn command_run(cli: &CliArgs, manifest: &Manifest) {
|
||||
let mut downloader = Downloader::new(util::get_ytdlp_path());
|
||||
match &cli.command {
|
||||
None | Some(CliCommand::Download) => {
|
||||
if let Ok(count) = downloader.download_all(manifest, &cli).await {
|
||||
log::info!("Downloaded {count} songs");
|
||||
} else {
|
||||
log::error!("Failed to download songs");
|
||||
return;
|
||||
}
|
||||
},
|
||||
Some(c) => {
|
||||
match c {
|
||||
CliCommand::Download => unreachable!(),
|
||||
CliCommand::Add { .. } => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,7 +33,7 @@ impl Downloader {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn download_all(&mut self, manifest: Manifest, cli: &CliArgs) -> anyhow::Result<usize> {
|
||||
pub async fn download_all(&mut self, manifest: &Manifest, cli: &CliArgs) -> anyhow::Result<usize> {
|
||||
let format = manifest.format()?;
|
||||
|
||||
for (genre, songs) in &manifest.genres {
|
||||
|
|
|
@ -7,11 +7,15 @@ mod manifest;
|
|||
mod logger;
|
||||
mod downloader;
|
||||
mod util;
|
||||
mod commands;
|
||||
mod prompt;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let cli_args = CliArgs::parse();
|
||||
let mut cli_args = CliArgs::parse();
|
||||
cli_args.populate_extra();
|
||||
logger::init_logger(cli_args.debug);
|
||||
|
||||
let manifest = match manifest::Manifest::from_path(&cli_args.manifest.as_std_path()) {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
|
@ -20,22 +24,6 @@ async fn main() {
|
|||
}
|
||||
};
|
||||
|
||||
let mut downloader = Downloader::new(util::get_ytdlp_path());
|
||||
|
||||
match cli_args.command {
|
||||
None | Some(CliCommand::Download) => {
|
||||
if let Ok(count) = downloader.download_all(manifest, &cli_args).await {
|
||||
log::info!("Downloaded {count} songs");
|
||||
} else {
|
||||
log::error!("Failed to download songs");
|
||||
return;
|
||||
}
|
||||
},
|
||||
Some(c) => {
|
||||
match c {
|
||||
CliCommand::Download => unreachable!(),
|
||||
CliCommand::Add { .. } => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
commands::command_run(&cli_args, &manifest);
|
||||
}
|
||||
|
|
75
music_mgr/src/prompt.rs
Normal file
75
music_mgr/src/prompt.rs
Normal file
|
@ -0,0 +1,75 @@
|
|||
use std::{collections::HashMap, io::Write};
|
||||
|
||||
|
||||
|
||||
pub fn simple_prompt(p: &str) -> String {
|
||||
|
||||
print!("{c}prompt{r}: {p}",
|
||||
c=anstyle::AnsiColor::Magenta.render_fg(),
|
||||
r=anstyle::Style::new().render_reset()
|
||||
);
|
||||
|
||||
// I dont care if it fails
|
||||
let _ = std::io::stdout().flush();
|
||||
|
||||
let mut buf = String::new();
|
||||
let _ = std::io::stdin().read_line(&mut buf);
|
||||
|
||||
buf
|
||||
}
|
||||
|
||||
pub fn prompt_with_options(p: &str, options: &[&str]) -> usize {
|
||||
println!("{c}prompt{r}: {p}",
|
||||
c=anstyle::AnsiColor::Magenta.render_fg(),
|
||||
r=anstyle::Style::new().render_reset()
|
||||
);
|
||||
|
||||
for (i, op) in options.iter().enumerate() {
|
||||
println!(" - {}: {}", i, op);
|
||||
}
|
||||
|
||||
print!("> ");
|
||||
// I dont care if it fails
|
||||
let _ = std::io::stdout().flush();
|
||||
|
||||
let mut buf = String::new();
|
||||
let _ = std::io::stdin().read_line(&mut buf);
|
||||
|
||||
if let Ok(num) = buf.parse::<usize>() {
|
||||
if num <= options.len() {
|
||||
return num;
|
||||
} else {
|
||||
log::error!("Number not in range");
|
||||
return prompt_with_options(p, options);
|
||||
}
|
||||
} else {
|
||||
log::error!("Not a number");
|
||||
return prompt_with_options(p, options);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prompt_with_named_options(p: &str, options: HashMap<&str, &str>) -> String {
|
||||
println!("{c}prompt{r}: {p}",
|
||||
c=anstyle::AnsiColor::Magenta.render_fg(),
|
||||
r=anstyle::Style::new().render_reset()
|
||||
);
|
||||
|
||||
let mut keys = Vec::new();
|
||||
|
||||
for (k, v) in &options {
|
||||
println!(" - {}: {}", k, v);
|
||||
keys.push(k.trim().to_lowercase())
|
||||
}
|
||||
|
||||
print!("> ");
|
||||
|
||||
// I dont care if it fails
|
||||
let _ = std::io::stdout().flush();
|
||||
|
||||
let mut buf = String::new();
|
||||
let _ = std::io::stdin().read_line(&mut buf);
|
||||
if !keys.contains(&buf.trim().to_lowercase()) {
|
||||
return prompt_with_named_options(p, options);
|
||||
}
|
||||
buf
|
||||
}
|
|
@ -19,4 +19,30 @@ pub fn get_ytdlp_path() -> String {
|
|||
}
|
||||
// TODO: Download yt-dlp to ./.bin/yt-dlp if doesnt exist
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(target_family="unix")]
|
||||
pub fn isatty() -> bool {
|
||||
use std::{ffi::c_int, os::fd::AsRawFd};
|
||||
unsafe {
|
||||
let fd = std::io::stdin().as_raw_fd();
|
||||
libc::isatty(fd as c_int) == 1
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_family="windows")]
|
||||
pub fn isatty() -> bool {
|
||||
unsafe {
|
||||
use windows::Win32::System::Console;
|
||||
use Console::{CONSOLE_MODE, STD_OUTPUT_HANDLE};
|
||||
let Ok(handle) = Console::GetStdHandle(STD_OUTPUT_HANDLE) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let mut out = CONSOLE_MODE(0);
|
||||
|
||||
let ret = Console::GetConsoleMode(handle, &mut out);
|
||||
|
||||
ret.is_ok()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user