Files
timbre/src/adopt.rs
2026-08-24 16:46:42 -04:00

105 lines
3.7 KiB
Rust

// i was gonna do a "filename hack" and name this file "adopte.rs" as in "adopters" but i would need to type
// adopte::adopt which is odd so i didn't
use std::{
fs::{create_dir_all, remove_dir_all, write},
io::{Read, Write},
path::Path,
process::Command,
time::{SystemTime, UNIX_EPOCH},
};
use crate::{coverartarchive::fetch_cover_art, import, musicbrainz::get_disc_info, tagging};
// adopt = rip a disc but ripping sounds like destroying so i'm not using it
pub fn adopt(timbre_dir: &Path) {
let disc = get_disc_info("http://catgpt-server:5000");
let release = &disc.releases[0];
println!("{}", release.id);
let tmp_dir = timbre_dir.join(format!(
".tmp/{}",
SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("time went backwards?? ¯\\_(ツ)_/¯\nquit trying to make me timber!\n")
.as_secs()
));
create_dir_all(&tmp_dir).expect("i couldn't make my workspace :(\n");
write(tmp_dir.join("README.txt"), "I'M DOING IT CHILLAX BRO\n")
.expect("couldn't even write my chillax note :( bro fix ur pc\n");
// as of writing this line here i just donated $2.75 + transaction fees to Wikipedia!
println!("adopting...");
let tracks = &release.media[0].tracks;
let tracks_len = tracks.len();
for track_num in 1..=tracks_len {
let file_name = format!("track{track_num:02}.wav");
let current_track = &tracks[track_num - 1];
let (mut pty, pts) = pty_process::blocking::open().expect("couldn't open a pty :(\n");
pty.resize(pty_process::Size::new(24, 80))
.expect("couldn't size the pty :(\n");
let cmd = pty_process::blocking::Command::new("cdparanoia")
.arg("-e")
.arg(track_num.to_string())
.arg(&tmp_dir.join(&file_name));
let mut child = cmd.spawn(pts).expect("cdparanoia wouldn't start :(\n");
let mut buf = [0u8; 512];
let mut acc = String::new();
loop {
let n = pty.read(&mut buf).unwrap_or(0);
if n == 0 {
// done
println!();
break;
}
acc.push_str(&String::from_utf8_lossy(&buf[..n]));
while let Some(pos) = acc.find('\r') {
let chunk: String = acc.drain(..=pos).collect();
if chunk.contains("PROGRESS") {
let bar = chunk
.split_once("== PROGRESS == [")
.unwrap()
.1
.split_once("|")
.unwrap()
.0;
print!(
"\r[{}] {track_num}/{} {}",
bar, tracks_len, current_track.title
);
std::io::stdout().flush().unwrap();
}
}
}
child.wait().expect("cdparanoia didn't finish cleanly :(\n");
let wav_path = tmp_dir.join(format!("track{track_num:02}.wav"));
let flac_path = tmp_dir.join(format!("track{track_num:02}.flac"));
Command::new("flac")
.arg("--best") // max compression, lossless
.arg(&wav_path) // input WAV
.output()
.expect("flac wouldn't encode :( is it installed?\n");
tagging::write_tags(
&flac_path,
&current_track.title,
&current_track.artist_credit[0].name,
&release.title,
track_num as u32,
fetch_cover_art(&release.id).as_deref(),
);
import::import_file(&flac_path, timbre_dir);
}
remove_dir_all(&tmp_dir).expect("couldn't clean up my mess :(\n");
println!("done!");
}