Added saving to files
This commit is contained in:
parent
87508b6908
commit
b7b3a63cf5
@ -1,10 +1,20 @@
|
|||||||
use crate::lrclib;
|
use crate::lrclib;
|
||||||
|
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
use std::path::Path;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum LyricsResult {
|
||||||
|
Synced(String),
|
||||||
|
Plain(String),
|
||||||
|
Instrumental,
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
const CONFIG_PATH: &str = "/tmp/lrcli.json";
|
const CONFIG_PATH: &str = "/tmp/lrcli.json";
|
||||||
|
|
||||||
type Config = HashMap<String, HashMap<String, String>>;
|
type Config = HashMap<String, HashMap<String, String>>;
|
||||||
@ -14,19 +24,43 @@ pub fn get_lyrics_text(
|
|||||||
track_name: &str,
|
track_name: &str,
|
||||||
album_name: &str,
|
album_name: &str,
|
||||||
duration: Duration,
|
duration: Duration,
|
||||||
) -> Result<Value, String> {
|
) -> Result<LyricsResult, String> {
|
||||||
let lyrics_json = lrclib::get_lyrics(artist_name, track_name, album_name, duration)
|
let lyrics_json = lrclib::get_lyrics(artist_name, track_name, album_name, duration)
|
||||||
.ok_or_else(|| format!("Failed to fetch lyrics for {track_name}"))?;
|
.ok_or_else(|| format!("Failed to fetch lyrics for {track_name}"))?;
|
||||||
|
|
||||||
let parsed: Value = serde_json::from_str(&lyrics_json)
|
let parsed: Value = serde_json::from_str(&lyrics_json)
|
||||||
.map_err(|e| format!("Failed to parse lyrics JSON: {e}"))?;
|
.map_err(|e| format!("Failed to parse lyrics JSON: {e}"))?;
|
||||||
|
|
||||||
let synced_lyrics = parsed
|
if parsed
|
||||||
.get("syncedLyrics")
|
.get("instrumental")
|
||||||
.ok_or_else(|| "Missing `syncedLyrics` field".to_string())?;
|
.and_then(Value::as_bool)
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
return Ok(LyricsResult::Instrumental);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(synced_lyrics.clone())
|
if let Some(synced) = parsed.get("syncedLyrics").and_then(Value::as_str) {
|
||||||
|
return Ok(LyricsResult::Synced(synced.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(plain) = parsed.get("plainLyrics").and_then(Value::as_str) {
|
||||||
|
return Ok(LyricsResult::Plain(plain.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(LyricsResult::None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn save_lyrics_file<P: AsRef<Path>>(audio_path: P, lyrics: String) -> Result<(), io::Error> {
|
||||||
|
let lrc_path = audio_path.as_ref().with_extension("lrc");
|
||||||
|
if !lrc_path.exists() {
|
||||||
|
fs::write(lrc_path, lyrics)?;
|
||||||
|
} else {
|
||||||
|
println!("{:#?} already exists, skipping", lrc_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn load_config() -> io::Result<Config> {
|
pub fn load_config() -> io::Result<Config> {
|
||||||
match fs::read_to_string(CONFIG_PATH) {
|
match fs::read_to_string(CONFIG_PATH) {
|
||||||
Ok(contents) => {
|
Ok(contents) => {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use core::time;
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
mod json_parsing;
|
mod json_parsing;
|
||||||
mod lrclib;
|
mod lrclib;
|
||||||
mod music;
|
mod music;
|
||||||
|
|||||||
37
src/music.rs
37
src/music.rs
@ -1,4 +1,5 @@
|
|||||||
use crate::json_parsing;
|
use crate::json_parsing::{self, add_song};
|
||||||
|
|
||||||
use audiotags::Tag;
|
use audiotags::Tag;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
@ -52,25 +53,45 @@ pub fn get_song_file(path: &Path) -> Result<(), MusicError> {
|
|||||||
&info.album_name,
|
&info.album_name,
|
||||||
info.duration,
|
info.duration,
|
||||||
) {
|
) {
|
||||||
Ok(lyrics) => {
|
Ok(result) => {
|
||||||
json_parsing::add_song(
|
let status = match &result {
|
||||||
|
json_parsing::LyricsResult::Synced(_) => "Synchronized",
|
||||||
|
json_parsing::LyricsResult::Plain(_) => "Plain",
|
||||||
|
json_parsing::LyricsResult::Instrumental => "Instrumental",
|
||||||
|
json_parsing::LyricsResult::None => "NotFound",
|
||||||
|
};
|
||||||
|
|
||||||
|
let _ = add_song(
|
||||||
absolute_path.parent().unwrap().to_str().unwrap(),
|
absolute_path.parent().unwrap().to_str().unwrap(),
|
||||||
absolute_path.file_name().unwrap().to_str().unwrap(),
|
absolute_path.file_name().unwrap().to_str().unwrap(),
|
||||||
"Synchronized",
|
status,
|
||||||
);
|
);
|
||||||
|
|
||||||
println!("{lyrics}")
|
match result {
|
||||||
|
json_parsing::LyricsResult::Synced(lyrics)
|
||||||
|
| json_parsing::LyricsResult::Plain(lyrics) => {
|
||||||
|
json_parsing::save_lyrics_file(absolute_path, lyrics);
|
||||||
|
}
|
||||||
|
json_parsing::LyricsResult::Instrumental => {
|
||||||
|
println!("Instrumental track — no lyrics available");
|
||||||
|
}
|
||||||
|
json_parsing::LyricsResult::None => {
|
||||||
|
println!("No lyrics found");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
json_parsing::add_song(
|
let _ = add_song(
|
||||||
absolute_path.parent().unwrap().to_str().unwrap(),
|
absolute_path.parent().unwrap().to_str().unwrap(),
|
||||||
absolute_path.file_name().unwrap().to_str().unwrap(),
|
absolute_path.file_name().unwrap().to_str().unwrap(),
|
||||||
"NotFound",
|
"Error",
|
||||||
);
|
);
|
||||||
|
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Failed to fetch lyrics for {}, error: {e}",
|
"Failed to fetch lyrics for {}, error: {e}",
|
||||||
pathbuf.to_str().unwrap()
|
pathbuf.to_str().unwrap()
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user