Skip to content

Commit

Permalink
Started work on Musixmatch fetcher
Browse files Browse the repository at this point in the history
  • Loading branch information
Naapperas committed Jun 26, 2024
1 parent d03ceca commit 1cd6388
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 36 deletions.
64 changes: 54 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 5 additions & 6 deletions src/lyrics.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use log::trace;
use log::debug;
use std::{cell::RefCell, collections::HashMap, sync::Arc};

use crate::{
Expand All @@ -7,15 +7,14 @@ use crate::{
queue::Queue,
};

#[derive(Clone)]
pub struct LyricsManager {
queue: Arc<Queue>,
fetcher: LyricsFetcher,
fetcher: Box<dyn LyricsFetcher>,
cache: RefCell<HashMap<String, String>>,
}

impl LyricsManager {
pub fn new(queue: Arc<Queue>, fetcher: LyricsFetcher) -> Self {
pub fn new(queue: Arc<Queue>, fetcher: Box<dyn LyricsFetcher>) -> Self {
LyricsManager {
queue,
fetcher,
Expand Down Expand Up @@ -43,8 +42,8 @@ impl LyricsManager {
let cache = self.cache.borrow();

if cache.contains_key(track_id) {
trace!("Retrieving cached lyrics for {}", track.title);
return cache.get(track_id).unwrap().to_owned();
debug!("Retrieving cached lyrics for {}", track.title);
return cache.get(track_id).unwrap().into();
}
}

Expand Down
66 changes: 49 additions & 17 deletions src/lyrics_fetcher.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,58 @@
use log::trace;
use std::sync::Arc;

use crate::model::track::Track;
use log::debug;

#[derive(Clone)]
pub struct LyricsFetcher {}
use crate::{config::Config, model::track::Track};

impl LyricsFetcher {
pub fn new() -> LyricsFetcher {
Self {}
}
pub trait LyricsFetcher {
fn fetch(&self, track: &Track) -> String;
}

pub struct MusixMatchLyricsFetcher {
api_key: String,
}

impl LyricsFetcher for MusixMatchLyricsFetcher {
fn fetch(&self, track: &Track) -> String {
let track_title = track.title.clone();
let track_authors = track.artists.join(", ");

debug!("Fetching lyrics for {} by {}", track_title, track_authors);

/// Fetches the lyrics of the given song using the specified lyrics source
pub fn fetch(&self, track: &Track) -> String {
// std::thread::sleep(std::time::Duration::from_secs(2));
trace!("Fetching lyrics for {track}");
let client = reqwest::blocking::Client::new();

format!("Sample Lyrics for {}\n", track.title)
let response = client
.get("https://api.musixmatch.com/ws/1.1/matcher.lyrics.get")
.query(&[
("q_track", track_title.clone()),
("q_artist", track_authors),
("apikey", self.api_key.clone()),
])
.send()
.unwrap();

if response.status() != 200 {
debug!("Error fetching lyrics for {}", track_title);
return format!("Error fetching lyrics for {}", track_title);
}

// Do this since we do not have a specific body type to parse into
let text = response.text().unwrap();
let json: serde_json::Value = serde_json::from_str(&text).unwrap();

debug!("Received {:?}", json);

if json["status_code"] != 200 {
debug!("Error fetching lyrics for {}", track_title);
return format!("Error fetching lyrics for {}", track_title);
}

json["message"]["body"]["lyrics"]["lyrics_body"].to_string()
}
}

impl Default for LyricsFetcher {
fn default() -> Self {
LyricsFetcher::new() // TODO: check the prefered fetcher
}
pub fn default_fetcher(cfg: Arc<Config>) -> Box<dyn LyricsFetcher> {
Box::new(MusixMatchLyricsFetcher {
api_key: cfg.values().backend.clone().unwrap(),
})
}
7 changes: 4 additions & 3 deletions src/ui/lyrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,15 @@ impl LyricsView {
lyrics_view
}

// needs to be made public in order to be updated from main's event loop
pub fn update_lyrics(&self) {
fn update_lyrics(&self) {
// TODO: this should be done in a separate thread and the UI should be updated when the lyrics are fetched (or an error occurs)

let current_track = self.manager.get_current_track();

if let Some(track) = current_track {
let track_title_str = track.clone().title;

let track_authors_str = track.clone().artists.join(", ");
let track_authors_str = track.artists.join(", ");

let track_album_str = match track.clone().album {
None => String::default(),
Expand Down

0 comments on commit 1cd6388

Please sign in to comment.