repair
This commit is contained in:
142
Cargo.lock
generated
142
Cargo.lock
generated
@@ -8,6 +8,56 @@ version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.12.1"
|
||||
@@ -29,6 +79,52 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
|
||||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.10.2"
|
||||
@@ -89,6 +185,12 @@ dependencies = [
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
@@ -104,6 +206,12 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.189"
|
||||
@@ -161,6 +269,12 @@ dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell_polyfill"
|
||||
version = "1.70.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
@@ -202,6 +316,12 @@ version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "3.0.3"
|
||||
@@ -217,6 +337,7 @@ dependencies = [
|
||||
name = "timbre"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"hex",
|
||||
"lofty",
|
||||
"sha2",
|
||||
@@ -233,3 +354,24 @@ name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
@@ -4,6 +4,7 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.6.6", features = ["derive"] }
|
||||
hex = "0.4.3"
|
||||
lofty = "0.25.1"
|
||||
sha2 = "0.11.0"
|
||||
|
||||
138
src/main.rs
138
src/main.rs
@@ -1,3 +1,7 @@
|
||||
use clap::{
|
||||
Parser, Subcommand,
|
||||
builder::styling::{AnsiColor, Effects, Styles},
|
||||
};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::{
|
||||
fs::{self, File, create_dir_all},
|
||||
@@ -5,18 +9,24 @@ use std::{
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
const CLAP_STYLING: Styles = Styles::styled()
|
||||
.header(AnsiColor::Green.on_default().effects(Effects::BOLD))
|
||||
.usage(AnsiColor::Green.on_default().effects(Effects::BOLD))
|
||||
.literal(AnsiColor::Cyan.on_default().effects(Effects::BOLD))
|
||||
.placeholder(AnsiColor::Cyan.on_default());
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
compile_error!("kitty like linux more");
|
||||
|
||||
fn hashcat(cat_path: &Path) {
|
||||
let file = File::open(cat_path).expect("how dare u! i want my cat back :(");
|
||||
fn check_cat_hash(cat_path: &Path) -> bool {
|
||||
let file = File::open(cat_path).expect("how dare u! i want my cat back :(\n");
|
||||
let mut cat = BufReader::new(file);
|
||||
|
||||
let mut hasher = Sha256::new();
|
||||
|
||||
let mut buffer = [0u8; 4096];
|
||||
loop {
|
||||
let bytes_read = cat.read(&mut buffer).expect("what happened to my cat!?");
|
||||
let bytes_read = cat.read(&mut buffer).expect("what happened to my cat!?\n");
|
||||
if bytes_read == 0 {
|
||||
break;
|
||||
}
|
||||
@@ -25,13 +35,33 @@ fn hashcat(cat_path: &Path) {
|
||||
|
||||
let file_hash = hex::encode(hasher.finalize());
|
||||
|
||||
if !file_hash
|
||||
file_hash
|
||||
.eq_ignore_ascii_case("45d4cf2fb11999c39ec5cd0cbedb436767421c8b8dab575c76f0b6ad9265d640")
|
||||
{
|
||||
}
|
||||
fn hashcat(cat_path: &Path) {
|
||||
if !check_cat_hash(cat_path) {
|
||||
panic!("this is not my cat. where is my cat. what did you do!? KITTYYYYYYYYYY")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(name = "timbre")]
|
||||
#[command(about = "a music manager to finally solve this huge mess of music management")]
|
||||
#[command(styles=CLAP_STYLING)]
|
||||
struct Cli {
|
||||
#[command(subcommand)]
|
||||
command: Commands,
|
||||
}
|
||||
#[derive(Subcommand, PartialEq)]
|
||||
enum Commands {
|
||||
/// give timbre a home so it can help you
|
||||
Init,
|
||||
/// look through your library and see what's there
|
||||
Scan,
|
||||
/// attempt to repair timbre's home, this won't restore lost tracks
|
||||
Repair,
|
||||
}
|
||||
|
||||
fn is_audio(path: &Path) -> bool {
|
||||
match path.extension().and_then(|e| e.to_str()) {
|
||||
Some(ext) => {
|
||||
@@ -42,7 +72,7 @@ fn is_audio(path: &Path) -> bool {
|
||||
true
|
||||
} else {
|
||||
println!(
|
||||
"while looking through each of your songs, i found one that i don't understand.\nits named {}, and i don't understand it's file extension.\nyou can try to help teach me by opening a git issue if it's a music file! :)\ni will continue, but ignore this file :(",
|
||||
"while looking through each of your songs, i found one that i don't understand.\nits named {}, and i don't understand its file extension.\nyou can try to help teach me by opening a git issue if it's a music file! :)\ni will continue, but ignore this file :(",
|
||||
path.display()
|
||||
);
|
||||
false
|
||||
@@ -53,10 +83,10 @@ fn is_audio(path: &Path) -> bool {
|
||||
}
|
||||
fn scan(dir: &Path, out: &mut Vec<PathBuf>) {
|
||||
for entry in fs::read_dir(dir)
|
||||
.expect("i want to help you, but i don't know how to read your music folder :( sorry.")
|
||||
.expect("i want to help you, but i had trouble reading my music folder :( sorry.\n")
|
||||
{
|
||||
let path=entry.expect(
|
||||
"i wanna help you, but, i can't do everything. i couldn't read a file, to the point where i can't tell you which :(").path();
|
||||
"i wanna help you, but, i can't do everything. i couldn't read a file, to the point where i can't tell you which :(\n").path();
|
||||
if path.is_dir() {
|
||||
scan(&path, out);
|
||||
} else if is_audio(&path) {
|
||||
@@ -68,20 +98,98 @@ fn scan(dir: &Path, out: &mut Vec<PathBuf>) {
|
||||
fn main() {
|
||||
let cat = include_bytes!("../cat_01.jpg"); // my kitty!
|
||||
|
||||
let cli = Cli::parse();
|
||||
|
||||
let timbre_dir = Path::new(&std::env::var("HOME").expect("NERD!!!"))
|
||||
.join("Music")
|
||||
.join("Timbre");
|
||||
|
||||
if cli.command != Commands::Init && cli.command != Commands::Repair {
|
||||
if timbre_dir.exists() {
|
||||
hashcat(&timbre_dir.join("cat_01.jpg")); // meow
|
||||
} else {
|
||||
println!(
|
||||
"i can't help you since i don't have a home :(\nyou can create one with the command timbre init."
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
match cli.command {
|
||||
Commands::Init => {
|
||||
if !timbre_dir.exists() {
|
||||
println!("First run detected... Initializing...");
|
||||
println!("making a home...");
|
||||
create_dir_all(&timbre_dir).expect("wat");
|
||||
fs::write(timbre_dir.join("cat_01.jpg"), cat)
|
||||
.expect("my cat! he can't come! what did you do!?!");
|
||||
println!("Done!");
|
||||
} else {
|
||||
hashcat(&timbre_dir.join("cat_01.jpg")); // meow
|
||||
.expect("my cat! he can't come! what did you do!?!\n");
|
||||
for dir in ["Albums", "Singles", "Unidentified"] {
|
||||
create_dir_all(timbre_dir.join(dir))
|
||||
.expect("sorry, but i couldn't create a folder that i need.\n");
|
||||
}
|
||||
println!("i now have a home!");
|
||||
} else {
|
||||
println!("i already has a home!");
|
||||
}
|
||||
}
|
||||
Commands::Scan => {
|
||||
let mut tracks = Vec::new();
|
||||
scan(&timbre_dir.join("Tracks"), &mut tracks);
|
||||
println!("Found {} audio files", tracks.len());
|
||||
scan(&timbre_dir.join("Singles"), &mut tracks);
|
||||
scan(&timbre_dir.join("Albums"), &mut tracks);
|
||||
if tracks.is_empty() {
|
||||
println!("i couldn't find any audio files :(");
|
||||
} else {
|
||||
println!("i found {} audio files :)", tracks.len());
|
||||
}
|
||||
}
|
||||
Commands::Repair => {
|
||||
println!("repairing my home...");
|
||||
let mut fixed_something = false;
|
||||
|
||||
if !timbre_dir.exists() {
|
||||
println!(
|
||||
"it appears that my home is gone. your songs may have been deleted :(\nrebuilding my home..."
|
||||
);
|
||||
create_dir_all(&timbre_dir).expect("wat");
|
||||
fs::write(timbre_dir.join("cat_01.jpg"), cat)
|
||||
.expect("my cat! he can't come! what did you do!?!\n");
|
||||
for dir in ["Albums", "Singles", "Unidentified"] {
|
||||
create_dir_all(timbre_dir.join(dir))
|
||||
.expect("sorry, but i couldn't create a folder that i need.\n");
|
||||
}
|
||||
println!("i rebuilt my home! your audio won't be there though :(");
|
||||
fixed_something = true;
|
||||
}
|
||||
if !timbre_dir.join("Albums").exists()
|
||||
|| !timbre_dir.join("Singles").exists()
|
||||
|| !timbre_dir.join("Unidentified").exists()
|
||||
{
|
||||
println!("i found folders that don't exist! recreating them...");
|
||||
for dir in ["Albums", "Singles", "Unidentified"] {
|
||||
create_dir_all(timbre_dir.join(dir))
|
||||
.expect("sorry, but i couldn't create a folder that i need.\n");
|
||||
}
|
||||
println!("done!");
|
||||
fixed_something = true;
|
||||
}
|
||||
if !timbre_dir.join("cat_01.jpg").exists() {
|
||||
println!("where did my cat go!?!");
|
||||
fs::write(timbre_dir.join("cat_01.jpg"), cat)
|
||||
.expect("my cat! he can't come! what did you do!?!\n");
|
||||
println!("he's back :)");
|
||||
fixed_something = true;
|
||||
}
|
||||
if !check_cat_hash(&timbre_dir.join("cat_01.jpg")) {
|
||||
println!("what happened to my cat :( let me bring my kitty back.");
|
||||
fs::write(timbre_dir.join("cat_01.jpg"), cat)
|
||||
.expect("what did you do! i can't bring my cat back :(\n");
|
||||
println!("yay he's back!");
|
||||
fixed_something = true;
|
||||
}
|
||||
if !fixed_something {
|
||||
println!(
|
||||
"i wasn't able to fix anything :(\neither there is no problem, or i couldn't fix it :("
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user