diff --git a/doc/config b/doc/config index 51b86cb2..6dfb8db0 100644 --- a/doc/config +++ b/doc/config @@ -422,7 +422,7 @@ # #cyclic_scrolling = no # -#lyrics_fetchers = tags, tekstowo, plyrics, justsomelyrics, jahlyrics, zeneszoveg, internet +#lyrics_fetchers = tags, tekstowo, plyrics, justsomelyrics, jahlyrics, zeneszoveg, azlyrics, darklyrics, internet # #follow_now_playing_lyrics = no # diff --git a/src/configuration.cpp b/src/configuration.cpp index 2c9475ad..dfe3ef5c 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -161,6 +161,10 @@ bool configure(int argc, char **argv) std::make_tuple("plyrics", "rihanna", "umbrella"), std::make_tuple("tekstowo", "rihanna", "umbrella"), std::make_tuple("zeneszoveg", "rihanna", "umbrella"), + std::make_tuple("azlyrics", "rihanna", "umbrella"), + std::make_tuple("darklyrics", "agalloch", "falling snow"), + + }; for (auto &data : fetcher_data) { diff --git a/src/lyrics_fetcher.cpp b/src/lyrics_fetcher.cpp index 395dfda2..02b0f142 100644 --- a/src/lyrics_fetcher.cpp +++ b/src/lyrics_fetcher.cpp @@ -54,6 +54,10 @@ std::istream &operator>>(std::istream &is, LyricsFetcher_ &fetcher) fetcher = std::make_unique(); else if (s == "zeneszoveg") fetcher = std::make_unique(); + else if (s == "azlyrics") + fetcher = std::make_unique(); + else if (s == "darklyrics") + fetcher = std::make_unique(); else if (s == "internet") fetcher = std::make_unique(); #ifdef HAVE_TAGLIB_H @@ -206,6 +210,42 @@ bool GoogleLyricsFetcher::isURLOk(const std::string &url) return url.find(siteKeyword()) != std::string::npos; } +LyricsFetcher::Result DarkLyricsFetcher::fetch(const std::string &artist, + const std::string &title, + const MPD::Song &song) +{ + current_title = title; + return GoogleLyricsFetcher::fetch(artist, title, song); +} +void DarkLyricsFetcher::postProcess(std::string &data) const +{ + try { + // Escape any special regex characters in the song title + std::string escaped_title = boost::regex_replace(current_title, boost::regex("[.^$|()\\[\\]{}*+?\\\\]"), "\\\\$&"); + + // Match the

tag with the title, and capture EVERYTHING after it + std::string pattern = "(?is)

.*?" + escaped_title + ".*?

(.*)"; + boost::regex rx(pattern); + boost::smatch match; + + if (boost::regex_search(data, match, rx)) { + std::string song_data = match[1].str(); + + // Cut off the text as soon as the next song's

tag starts + size_t next_h3 = song_data.find("

"); + if (next_h3 != std::string::npos) { + song_data = song_data.substr(0, next_h3); + } + + data = song_data; + } + } catch (...) {} + + // Pass it back to the default postProcess to strip the remaining HTML tags + LyricsFetcher::postProcess(data); +} + + /**********************************************************************/ LyricsFetcher::Result InternetLyricsFetcher::fetch(const std::string &artist, diff --git a/src/lyrics_fetcher.h b/src/lyrics_fetcher.h index d2901b72..b80d6eff 100644 --- a/src/lyrics_fetcher.h +++ b/src/lyrics_fetcher.h @@ -111,6 +111,28 @@ struct ZeneszovegFetcher : public GoogleLyricsFetcher virtual const char *regex() const override { return "
(.*?)
"; } }; +struct AzLyricsFetcher : public GoogleLyricsFetcher +{ + virtual const char *name() const override { return "azlyrics.com"; } +protected: + virtual const char *regex() const override { return "(?s)(.*?)"; } +}; + +struct DarkLyricsFetcher : public GoogleLyricsFetcher +{ + virtual const char *name() const override { return "darklyrics.com"; } + virtual Result fetch(const std::string &artist, const std::string &title, const MPD::Song &song) override; + +protected: + virtual const char *regex() const override { + return "(?s)
(.*?)(?:
)"; + } + virtual void postProcess(std::string &data) const override; + +private: + std::string current_title; +}; + struct InternetLyricsFetcher : public GoogleLyricsFetcher { virtual const char *name() const override { return "the Internet"; } diff --git a/src/settings.cpp b/src/settings.cpp index c337fe5d..b4ac9ae2 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -465,7 +465,7 @@ bool Configuration::read(const std::vector &config_paths, bool igno #ifdef HAVE_TAGLIB_H "tags, " #endif - "tekstowo, plyrics, justsomelyrics, jahlyrics, zeneszoveg, internet", [this](std::string v) { + "tekstowo, plyrics, justsomelyrics, jahlyrics, zeneszoveg, azlyrics, darklyrics, internet", [this](std::string v) { lyrics_fetchers = list_of(v, [](std::string s) { LyricsFetcher_ fetcher; try {