From 22681df199695d10df3671b005361e9c0a2c08f6 Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Sat, 28 Jan 2017 20:41:17 +0100 Subject: [PATCH] Add support for fetching lyrics from jah-lyrics.com and plyrics.com --- NEWS | 1 + doc/config | 2 +- src/configuration.cpp | 26 ++++++++++++++------------ src/lyrics_fetcher.cpp | 33 +++++++++++++++++++++------------ src/lyrics_fetcher.h | 16 ++++++++++++++++ src/screens/lyrics.cpp | 5 ++--- src/settings.cpp | 2 +- 7 files changed, 56 insertions(+), 29 deletions(-) diff --git a/NEWS b/NEWS index 050fe32d..19154e0c 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,7 @@ ncmpcpp-0.8 (????-??-??) * Fixed fetching artist info in language other than English. * Added test that checks if lyrics fetchers work (available via command line parameter --test-lyrics-fetchers). * Fixed fetching lyrics from justsomelyrics.com. +* Added support for fetching lyrics from jah-lyrics.com and plyrics.com. ncmpcpp-0.7.7 (2016-10-31) * Fixed compilation on 32bit platforms. diff --git a/doc/config b/doc/config index 90e5ac1a..d066a923 100644 --- a/doc/config +++ b/doc/config @@ -360,7 +360,7 @@ # #lines_scrolled = 2 # -#lyrics_fetchers = lyricwiki, azlyrics, genius, sing365, lyricsmania, metrolyrics, justsomelyrics, tekstowo, internet +#lyrics_fetchers = lyricwiki, azlyrics, genius, sing365, lyricsmania, metrolyrics, justsomelyrics, jahlyrics, plyrics, tekstowo, internet # #follow_now_playing_lyrics = no # diff --git a/src/configuration.cpp b/src/configuration.cpp index 8c25312d..24ecbf9b 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -139,25 +139,27 @@ bool configure(int argc, char **argv) if (vm.count("test-lyrics-fetchers")) { - std::vector fetcher_names = { - "lyricwiki", - "azlyrics", - "genius", - "sing365", - "lyricsmania", - "metrolyrics", - "justsomelyrics", - "tekstowo", + std::vector> fetcher_data = { + std::make_tuple("lyricwiki", "rihanna", "umbrella"), + std::make_tuple("azlyrics", "rihanna", "umbrella"), + std::make_tuple("genius", "rihanna", "umbrella"), + std::make_tuple("sing365", "rihanna", "umbrella"), + std::make_tuple("lyricsmania", "rihanna", "umbrella"), + std::make_tuple("metrolyrics", "rihanna", "umbrella"), + std::make_tuple("justsomelyrics", "rihanna", "umbrella"), + std::make_tuple("jahlyrics", "sean kingston", "dry your eyes"), + std::make_tuple("plyrics", "offspring", "genocide"), + std::make_tuple("tekstowo", "rihanna", "umbrella"), }; - for (auto &name : fetcher_names) + for (auto &data : fetcher_data) { - auto fetcher = boost::lexical_cast(name); + auto fetcher = boost::lexical_cast(std::get<0>(data)); std::cout << std::setw(20) << std::left << fetcher->name() << " : " << std::flush; - auto result = fetcher->fetch("rihanna", "umbrella"); + auto result = fetcher->fetch(std::get<1>(data), std::get<2>(data)); std::cout << (result.first ? "ok" : "failed") << "\n"; } diff --git a/src/lyrics_fetcher.cpp b/src/lyrics_fetcher.cpp index c9a5516f..b4c47dd8 100644 --- a/src/lyrics_fetcher.cpp +++ b/src/lyrics_fetcher.cpp @@ -52,6 +52,10 @@ std::istream &operator>>(std::istream &is, LyricsFetcher_ &fetcher) fetcher = std::make_unique(); else if (s == "justsomelyrics") fetcher = std::make_unique(); + else if (s == "jahlyrics") + fetcher = std::make_unique(); + else if (s == "plyrics") + fetcher = std::make_unique(); else if (s == "tekstowo") fetcher = std::make_unique(); else if (s == "internet") @@ -63,14 +67,15 @@ std::istream &operator>>(std::istream &is, LyricsFetcher_ &fetcher) const char LyricsFetcher::msgNotFound[] = "Not found"; -LyricsFetcher::Result LyricsFetcher::fetch(const std::string &artist, const std::string &title) +LyricsFetcher::Result LyricsFetcher::fetch(const std::string &artist, + const std::string &title) { Result result; result.first = false; std::string url = urlTemplate(); - boost::replace_all(url, "%artist%", artist); - boost::replace_all(url, "%title%", title); + boost::replace_all(url, "%artist%", Curl::escape(artist)); + boost::replace_all(url, "%title%", Curl::escape(title)); std::string data; CURLcode code = Curl::perform(data, url); @@ -106,7 +111,8 @@ LyricsFetcher::Result LyricsFetcher::fetch(const std::string &artist, const std: return result; } -std::vector LyricsFetcher::getContent(const char *regex_, const std::string &data) +std::vector LyricsFetcher::getContent(const char *regex_, + const std::string &data) { std::vector result; boost::regex rx(regex_); @@ -135,7 +141,8 @@ void LyricsFetcher::postProcess(std::string &data) const /***********************************************************************/ -LyricsFetcher::Result LyricwikiFetcher::fetch(const std::string &artist, const std::string &title) +LyricsFetcher::Result LyricwikiFetcher::fetch(const std::string &artist, + const std::string &title) { LyricsFetcher::Result result = LyricsFetcher::fetch(artist, title); if (result.first == true) @@ -194,16 +201,17 @@ bool LyricwikiFetcher::notLyrics(const std::string &data) const /**********************************************************************/ -LyricsFetcher::Result GoogleLyricsFetcher::fetch(const std::string &artist, const std::string &title) +LyricsFetcher::Result GoogleLyricsFetcher::fetch(const std::string &artist, + const std::string &title) { Result result; result.first = false; - std::string search_str = artist; + std::string search_str = Curl::escape(artist); search_str += "+"; - search_str += title; + search_str += Curl::escape(title); search_str += "+%2B"; - search_str += siteKeyword(); + search_str += Curl::escape(siteKeyword()); std::string google_url = "http://www.google.com/search?hl=en&ie=UTF-8&oe=UTF-8&q="; google_url += search_str; @@ -217,9 +225,9 @@ LyricsFetcher::Result GoogleLyricsFetcher::fetch(const std::string &artist, cons result.second = curl_easy_strerror(code); return result; } - + auto urls = getContent("here", data); - + if (urls.empty() || !isURLOk(urls[0])) { result.second = msgNotFound; @@ -247,7 +255,8 @@ bool MetrolyricsFetcher::isURLOk(const std::string &url) /**********************************************************************/ -LyricsFetcher::Result InternetLyricsFetcher::fetch(const std::string &artist, const std::string &title) +LyricsFetcher::Result InternetLyricsFetcher::fetch(const std::string &artist, + const std::string &title) { GoogleLyricsFetcher::fetch(artist, title); LyricsFetcher::Result result; diff --git a/src/lyrics_fetcher.h b/src/lyrics_fetcher.h index 5693a370..a3216160 100644 --- a/src/lyrics_fetcher.h +++ b/src/lyrics_fetcher.h @@ -131,6 +131,22 @@ protected: virtual const char *regex() const override { return "(.*?)"; } }; +struct JahLyricsFetcher : public GoogleLyricsFetcher +{ + virtual const char *name() const override { return "jah-lyrics.com"; } + +protected: + virtual const char *regex() const override { return "
.*?
(.*?)

"; } +}; + +struct PLyricsFetcher : public GoogleLyricsFetcher +{ + virtual const char *name() const override { return "plyrics.com"; } + +protected: + virtual const char *regex() const override { return "(.*?)"; } +}; + struct TekstowoFetcher : public GoogleLyricsFetcher { virtual const char *name() const override { return "tekstowo.pl"; } diff --git a/src/screens/lyrics.cpp b/src/screens/lyrics.cpp index 7c98439b..bf870141 100644 --- a/src/screens/lyrics.cpp +++ b/src/screens/lyrics.cpp @@ -124,8 +124,8 @@ boost::optional downloadLyrics( std::shared_ptr> download_stopper, LyricsFetcher *current_fetcher) { - std::string s_artist = Curl::escape(s.getArtist()); - std::string s_title = Curl::escape(s.getTitle()); + std::string s_artist = s.getArtist(); + std::string s_title = s.getTitle(); // If artist or title is empty, use filename. This should give reasonable // results for google search based lyrics fetchers. if (s_artist.empty() || s_title.empty()) @@ -137,7 +137,6 @@ boost::optional downloadLyrics( size_t dot = s_title.rfind('.'); if (dot != std::string::npos) s_title.resize(dot); - s_title = Curl::escape(s_title); } auto fetch_lyrics = [&](auto &fetcher_) { diff --git a/src/settings.cpp b/src/settings.cpp index 89dc9e29..3259cb2d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -389,7 +389,7 @@ bool Configuration::read(const std::vector &config_paths, bool igno p.add("cyclic_scrolling", &use_cyclic_scrolling, "no", yes_no); p.add("lines_scrolled", &lines_scrolled, "2"); p.add("lyrics_fetchers", &lyrics_fetchers, - "lyricwiki, azlyrics, genius, sing365, lyricsmania, metrolyrics, justsomelyrics, tekstowo, internet", + "lyricwiki, azlyrics, genius, sing365, lyricsmania, metrolyrics, justsomelyrics, jahlyrics, plyrics, tekstowo, internet", list_of); p.add("follow_now_playing_lyrics", &now_playing_lyrics, "no", yes_no); p.add("fetch_lyrics_for_current_song_in_background", &fetch_lyrics_in_background,