From b7b3a63cf5e308527bdaf840d4b0045861752b0d Mon Sep 17 00:00:00 2001 From: shinya Date: Sat, 31 Jan 2026 09:48:12 +0100 Subject: [PATCH] Added saving to files --- src/json_parsing.rs | 44 +++++++++++++++++++++++++++++++++++++++----- src/main.rs | 1 + src/music.rs | 37 +++++++++++++++++++++++++++++-------- 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/src/json_parsing.rs b/src/json_parsing.rs index 769fb35..a9dfc60 100644 --- a/src/json_parsing.rs +++ b/src/json_parsing.rs @@ -1,10 +1,20 @@ use crate::lrclib; + use serde_json::Value; use std::collections::HashMap; use std::fs; use std::io::{self, Write}; +use std::path::Path; use std::time::Duration; +#[derive(Debug)] +pub enum LyricsResult { + Synced(String), + Plain(String), + Instrumental, + None, +} + const CONFIG_PATH: &str = "/tmp/lrcli.json"; type Config = HashMap>; @@ -14,19 +24,43 @@ pub fn get_lyrics_text( track_name: &str, album_name: &str, duration: Duration, -) -> Result { +) -> Result { let lyrics_json = lrclib::get_lyrics(artist_name, track_name, album_name, duration) .ok_or_else(|| format!("Failed to fetch lyrics for {track_name}"))?; let parsed: Value = serde_json::from_str(&lyrics_json) .map_err(|e| format!("Failed to parse lyrics JSON: {e}"))?; - let synced_lyrics = parsed - .get("syncedLyrics") - .ok_or_else(|| "Missing `syncedLyrics` field".to_string())?; + if parsed + .get("instrumental") + .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>(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 { match fs::read_to_string(CONFIG_PATH) { Ok(contents) => { diff --git a/src/main.rs b/src/main.rs index e0b15ca..7caab24 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use core::time; use std::path::{Path, PathBuf}; use std::thread; use std::time::Duration; + mod json_parsing; mod lrclib; mod music; diff --git a/src/music.rs b/src/music.rs index 8d29a07..b42b4df 100644 --- a/src/music.rs +++ b/src/music.rs @@ -1,4 +1,5 @@ -use crate::json_parsing; +use crate::json_parsing::{self, add_song}; + use audiotags::Tag; use std::fs; use std::path::Path; @@ -52,25 +53,45 @@ pub fn get_song_file(path: &Path) -> Result<(), MusicError> { &info.album_name, info.duration, ) { - Ok(lyrics) => { - json_parsing::add_song( + Ok(result) => { + 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.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) => { - json_parsing::add_song( + let _ = add_song( absolute_path.parent().unwrap().to_str().unwrap(), absolute_path.file_name().unwrap().to_str().unwrap(), - "NotFound", + "Error", ); + eprintln!( "Failed to fetch lyrics for {}, error: {e}", pathbuf.to_str().unwrap() - ) + ); } };