initial implementation in rust
This commit is contained in:
parent
9640d603e5
commit
dce5a3c301
|
@ -1,4 +1,6 @@
|
|||
{
|
||||
"format": "m4a",
|
||||
"genres": {
|
||||
"pop": [
|
||||
{"name": "Green Day - Basket Case", "url": "https://www.youtube.com/watch?v=wZ8eZRxFA-0"},
|
||||
{"name": "Icona Pop - I Love It", "url": "https://www.youtube.com/watch?v=UxxajLWwzqY"}
|
||||
|
@ -115,6 +117,9 @@
|
|||
{"name": "Patruliai - Kur Tu", "url": "https://www.youtube.com/watch?v=OPWhiu3cvj0"},
|
||||
{"name": "Ka Tu Ka Vakare", "url": "https://www.youtube.com/watch?v=6SOS4ljHbJY"}
|
||||
],
|
||||
"lietuviskos/rave": [
|
||||
{"name": "VainHouse - Malunas Prie Kelio", "url": "https://www.youtube.com/watch?v=bbwuNjDXCiM"}
|
||||
],
|
||||
"rusiskos": [
|
||||
{"name": "Topolini puh", "url": "https://www.youtube.com/watch?v=UUryvYF8tUs"},
|
||||
{"name": "Raim & Artur feat. Zhenis - Diskoteka is 90 hit", "url": "https://www.youtube.com/watch?v=GfBhxlNhrn0"},
|
||||
|
@ -136,3 +141,4 @@
|
|||
{"name": "ROMANCEPLANET - DANCE", "url": "https://www.youtube.com/watch?v=ircOfMb4gEw"}
|
||||
]
|
||||
}
|
||||
}
|
261
music_mgr/Cargo.lock
generated
261
music_mgr/Cargo.lock
generated
|
@ -2,6 +2,21 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
|
@ -46,7 +61,7 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -56,15 +71,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.91"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd97381a8cc6493395a5afc4c691c1084b3768db713b73aa215217aa245d153"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.4"
|
||||
|
@ -134,12 +188,24 @@ dependencies = [
|
|||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
|
@ -152,6 +218,18 @@ version = "1.0.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
|
@ -164,18 +242,66 @@ version = "2.7.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "music_mgr"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.32.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.79"
|
||||
|
@ -223,6 +349,12 @@ version = "0.8.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.17"
|
||||
|
@ -260,6 +392,15 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
|
@ -277,6 +418,34 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
|
@ -289,13 +458,43 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
"windows-targets 0.52.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -304,51 +503,93 @@ version = "0.52.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
"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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.4"
|
||||
|
|
|
@ -6,9 +6,12 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
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"
|
||||
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"] }
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use std::default;
|
||||
|
||||
use camino::Utf8PathBuf;
|
||||
use clap::{Parser, Subcommand};
|
||||
|
||||
|
@ -24,5 +22,10 @@ pub struct CliArgs {
|
|||
#[derive(Debug, Subcommand, Default)]
|
||||
pub enum CliCommand {
|
||||
#[default]
|
||||
Download
|
||||
Download,
|
||||
Add {
|
||||
url: String,
|
||||
name: String,
|
||||
genre: String
|
||||
}
|
||||
}
|
115
music_mgr/src/downloader.rs
Normal file
115
music_mgr/src/downloader.rs
Normal file
|
@ -0,0 +1,115 @@
|
|||
use std::{collections::HashMap, path::PathBuf, process::Stdio};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use log::Level;
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
|
||||
use crate::{cli::CliArgs, manifest::Manifest};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone)]
|
||||
struct Proc {
|
||||
url: String,
|
||||
path: String,
|
||||
finished: bool
|
||||
}
|
||||
|
||||
lazy_static!(
|
||||
static ref PROCESSES: Mutex<RwLock<HashMap<usize, Proc>>> = Mutex::new(RwLock::new(HashMap::new()));
|
||||
);
|
||||
|
||||
pub struct Downloader {
|
||||
count: usize,
|
||||
ytdlp_path: String,
|
||||
id_itr: usize,
|
||||
}
|
||||
|
||||
impl Downloader {
|
||||
pub fn new(ytdlp_path: String) -> Self {
|
||||
Self {
|
||||
count: 0,
|
||||
ytdlp_path,
|
||||
id_itr: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn download_all(&mut self, manifest: Manifest, cli: &CliArgs) -> anyhow::Result<usize> {
|
||||
let format = manifest.format()?;
|
||||
|
||||
for (genre, songs) in &manifest.genres {
|
||||
for song in songs {
|
||||
self.download_song(format!("{}/{genre}/{}.{}", cli.output, song.name, &format), &format, &song.url).await?;
|
||||
self.wait_for_procs(10).await?;
|
||||
}
|
||||
}
|
||||
self.wait_for_procs(0).await?;
|
||||
Ok(self.count)
|
||||
}
|
||||
|
||||
async fn download_song(&mut self, path: String, audio_format: &String, url: &String) -> anyhow::Result<()> {
|
||||
if PathBuf::from(&path).exists() {
|
||||
log::info!("File {path} exists, skipping");
|
||||
return Ok(())
|
||||
}
|
||||
let mut cmd = tokio::process::Command::new(&self.ytdlp_path);
|
||||
let cmd = cmd.args([
|
||||
"-x",
|
||||
"--audio-format",
|
||||
audio_format.as_str(),
|
||||
"-o",
|
||||
path.as_str(),
|
||||
url.as_str()
|
||||
]);
|
||||
|
||||
let cmd = if log::max_level() < Level::Debug {
|
||||
cmd.stdout(Stdio::null()).stderr(Stdio::null())
|
||||
} else {cmd};
|
||||
|
||||
let mut proc = cmd.spawn()?;
|
||||
let id = self.id_itr;
|
||||
|
||||
tokio::spawn(async move {
|
||||
let id = id;
|
||||
proc.wait().await
|
||||
.expect("child process encountered an error");
|
||||
PROCESSES.lock().await.write().await.get_mut(&id).unwrap().finished = true;
|
||||
});
|
||||
|
||||
log::info!("Downloading {path}");
|
||||
PROCESSES.lock().await.write().await.insert(id, Proc {
|
||||
url: url.clone(),
|
||||
path,
|
||||
finished: false,
|
||||
});
|
||||
self.id_itr += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn wait_for_procs(&mut self, until: usize) -> anyhow::Result<()> {
|
||||
// NOTE: This looks really fucked because i dont want to deadlock the processes so i lock PROCESSES for as little as possible
|
||||
// NOTE: So its also kinda really slow
|
||||
loop {
|
||||
{
|
||||
if PROCESSES.lock().await.read().await.len() <= until {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let procs = {
|
||||
PROCESSES.lock().await.read().await.clone()
|
||||
};
|
||||
|
||||
for (idx, proc) in procs {
|
||||
if proc.finished {
|
||||
{
|
||||
PROCESSES.lock().await.write().await.remove(&idx);
|
||||
}
|
||||
log::info!("Finished downloading {}", proc.path);
|
||||
self.count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(unreachable_code)] //? rust_analizer not smart enough for this
|
||||
Ok(())
|
||||
}
|
||||
}
|
14
music_mgr/src/logger.rs
Normal file
14
music_mgr/src/logger.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
use log::LevelFilter;
|
||||
|
||||
|
||||
pub fn init_logger(debug: bool) {
|
||||
let level = if debug {
|
||||
LevelFilter::Debug
|
||||
} else {
|
||||
LevelFilter::Info
|
||||
};
|
||||
env_logger::builder()
|
||||
.format_timestamp(None)
|
||||
.filter_level(level)
|
||||
.init();
|
||||
}
|
|
@ -1,24 +1,41 @@
|
|||
use clap::Parser;
|
||||
|
||||
use crate::cli::{CliArgs, CliCommand};
|
||||
use crate::{cli::{CliArgs, CliCommand}, downloader::Downloader};
|
||||
|
||||
mod cli;
|
||||
mod manifest;
|
||||
mod logger;
|
||||
mod downloader;
|
||||
mod util;
|
||||
|
||||
fn main() {
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let cli_args = CliArgs::parse();
|
||||
logger::init_logger(cli_args.debug);
|
||||
let manifest = match manifest::Manifest::from_path(&cli_args.manifest.as_std_path()) {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
log::error!("Failed to parse manifest file {}: {e}", cli_args.manifest);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut downloader = Downloader::new(util::get_ytdlp_path());
|
||||
|
||||
match cli_args.command {
|
||||
None => {
|
||||
// TODO: Download
|
||||
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 => {
|
||||
// TODO: Download
|
||||
},
|
||||
CliCommand::Download => unreachable!(),
|
||||
CliCommand::Add { .. } => todo!(),
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
println!("Hello, world!");
|
||||
}
|
||||
|
|
47
music_mgr/src/manifest.rs
Normal file
47
music_mgr/src/manifest.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
use std::{collections::HashMap, fs::read_to_string, path::Path};
|
||||
|
||||
use anyhow::bail;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const ALLOWED_FORMATS: &[&'static str] = &["m4a", "aac", "flac", "mp3", "vaw"];
|
||||
|
||||
|
||||
|
||||
type Genre = String;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Manifest {
|
||||
format: String,
|
||||
pub genres: HashMap<Genre, Vec<ManifestSong>>
|
||||
}
|
||||
|
||||
impl Manifest {
|
||||
pub fn format(&self) -> anyhow::Result<String> {
|
||||
if !ALLOWED_FORMATS.contains(&self.format.as_str()) {
|
||||
log::error!("Unknown format, allowed formats: {}", ALLOWED_FORMATS.join(", "));
|
||||
bail!("")
|
||||
}
|
||||
Ok(self.format.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ManifestSong {
|
||||
pub name: String,
|
||||
pub url: String
|
||||
}
|
||||
|
||||
|
||||
impl Manifest {
|
||||
pub fn from_string(s: String) -> anyhow::Result<Self> {
|
||||
let s = serde_json::from_str(&s)?;
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
pub fn from_path(p: &Path) -> anyhow::Result<Self> {
|
||||
let data = read_to_string(p)?;
|
||||
Self::from_string(data)
|
||||
}
|
||||
}
|
22
music_mgr/src/util.rs
Normal file
22
music_mgr/src/util.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
fn is_program_in_path(program: &str) -> Option<String> {
|
||||
if let Ok(path) = std::env::var("PATH") {
|
||||
for p in path.split(":") {
|
||||
let p_str = format!("{}/{}", p, program);
|
||||
if std::fs::metadata(&p_str).is_ok() {
|
||||
return Some(p_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub fn get_ytdlp_path() -> String {
|
||||
if let Some(p) = is_program_in_path("yt-dlp") {
|
||||
return p;
|
||||
}
|
||||
// TODO: Download yt-dlp to ./.bin/yt-dlp if doesnt exist
|
||||
todo!()
|
||||
}
|
Loading…
Reference in New Issue
Block a user