diff --git a/README.md b/README.md index b7d3e3892..1cb7ec3c4 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Strawberry is a music player and music collection organizer. It is a fork of Cle * Edit tags on music files * Fetch tags from MusicBrainz * Album cover art from Last.fm, Musicbrainz, Discogs, Deezer and Tidal - * Song lyrics from AudD and lyrics.ovh + * Song lyrics from AudD, lyrics.ovh and lololyrics.com * Support for multiple backends * Audio analyzer * Audio equalizer diff --git a/debian/control b/debian/control index d164027fa..c4e3fd1b3 100644 --- a/debian/control +++ b/debian/control @@ -58,7 +58,7 @@ Description: Audio player and music collection organizer - Edit tags on music files - Fetch tags from MusicBrainz - Album cover art from Lastfm, Musicbrainz, Discogs, Deezer and Tidal - - Song lyrics from AudD and lyrics.ovh + - Song lyrics from AudD, lyrics.ovh and lololyrics.com - Support for multiple backends - Audio analyzer - Audio equalizer diff --git a/dist/man/strawberry.1 b/dist/man/strawberry.1 index 8d6dfbb73..dba6f99e3 100644 --- a/dist/man/strawberry.1 +++ b/dist/man/strawberry.1 @@ -27,7 +27,7 @@ Features: .br - Album cover art from Lastfm, Musicbrainz, Discogs, Deezer and Tidal .br -- Song lyrics from AudD and lyrics.ovh +- Song lyrics from AudD, lyrics.ovh and lololyrics.com .br - Support for multiple backends .br diff --git a/dist/rpm/strawberry.spec.in b/dist/rpm/strawberry.spec.in index c48dac9ea..f54ee587a 100644 --- a/dist/rpm/strawberry.spec.in +++ b/dist/rpm/strawberry.spec.in @@ -102,7 +102,7 @@ Features: - Edit tags on music files - Fetch tags from MusicBrainz - Album cover art from Last.fm, Musicbrainz, Discogs, Deezer and Tidal - - Song lyrics from AudD and lyrics.ovh + - Song lyrics from AudD, lyrics.ovh and lololyrics.com - Support for multiple backends - Audio analyzer - Audio equalizer diff --git a/dist/unix/org.strawbs.strawberry.appdata.xml b/dist/unix/org.strawbs.strawberry.appdata.xml index 4e53b5584..643f1c5b9 100644 --- a/dist/unix/org.strawbs.strawberry.appdata.xml +++ b/dist/unix/org.strawbs.strawberry.appdata.xml @@ -29,7 +29,7 @@
  • Edit tags on music files
  • Fetch tags from MusicBrainz
  • Album cover art from Last.fm, Musicbrainz and Discogs
  • -
  • Song lyrics from AudD and lyrics.ovh
  • +
  • Song lyrics from AudD, lyrics.ovh and lololyrics.com
  • Support for multiple backends
  • Audio analyzer
  • Audio equalizer
  • diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5d07e604b..dd166c472 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -210,6 +210,7 @@ set(SOURCES lyrics/jsonlyricsprovider.cpp lyrics/auddlyricsprovider.cpp lyrics/ovhlyricsprovider.cpp + lyrics/lololyricsprovider.cpp settings/settingsdialog.cpp settings/settingspage.cpp @@ -393,6 +394,7 @@ set(HEADERS lyrics/jsonlyricsprovider.h lyrics/auddlyricsprovider.h lyrics/ovhlyricsprovider.h + lyrics/lololyricsprovider.h settings/settingsdialog.h settings/settingspage.h diff --git a/src/core/application.cpp b/src/core/application.cpp index af9d11fe2..9a49a4a99 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -60,6 +60,7 @@ #include "lyrics/lyricsprovider.h" #include "lyrics/auddlyricsprovider.h" #include "lyrics/ovhlyricsprovider.h" +#include "lyrics/lololyricsprovider.h" #include "scrobbler/audioscrobbler.h" @@ -137,6 +138,7 @@ class ApplicationImpl { LyricsProviders *lyrics_providers = new LyricsProviders(app); lyrics_providers->AddProvider(new AuddLyricsProvider(app)); lyrics_providers->AddProvider(new OVHLyricsProvider(app)); + lyrics_providers->AddProvider(new LoloLyricsProvider(app)); return lyrics_providers; }), internet_services_([=]() { diff --git a/src/lyrics/lololyricsprovider.cpp b/src/lyrics/lololyricsprovider.cpp new file mode 100644 index 000000000..a4634682a --- /dev/null +++ b/src/lyrics/lololyricsprovider.cpp @@ -0,0 +1,137 @@ +/* + * Strawberry Music Player + * Copyright 2019, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "core/closure.h" +#include "core/logging.h" +#include "core/network.h" +#include "lyricsprovider.h" +#include "lyricsfetcher.h" +#include "lololyricsprovider.h" + +const char *LoloLyricsProvider::kUrlSearch = "http://api.lololyrics.com/0.5/getLyric"; + +LoloLyricsProvider::LoloLyricsProvider(QObject *parent) : LyricsProvider("LoloLyrics", parent), network_(new NetworkAccessManager(this)) {} + +bool LoloLyricsProvider::StartSearch(const QString &artist, const QString &album, const QString &title, const quint64 id) { + + const ParamList params = ParamList() << Param("artist", artist) + << Param("track", title); + + QUrlQuery url_query; + for (const Param ¶m : params) { + url_query.addQueryItem(QUrl::toPercentEncoding(param.first), QUrl::toPercentEncoding(param.second)); + } + + QUrl url(kUrlSearch); + url.setQuery(url_query); + QNetworkReply *reply = network_->get(QNetworkRequest(url)); + NewClosure(reply, SIGNAL(finished()), this, SLOT(HandleSearchReply(QNetworkReply*, const quint64, const QString&, const QString&)), reply, id, artist, title); + + //qLog(Debug) << "LoloLyrics: Sending request for" << url; + + return true; + +} + +void LoloLyricsProvider::CancelSearch(const quint64 id) {} + +void LoloLyricsProvider::HandleSearchReply(QNetworkReply *reply, const quint64 id, const QString &artist, const QString &title) { + + reply->deleteLater(); + + QByteArray data; + QString failure_reason; + + if (reply->error() != QNetworkReply::NoError) { + failure_reason = QString("%1 (%2)").arg(reply->errorString()).arg(reply->error()); + if (reply->error() < 200) { + Error(id, failure_reason); + return; + } + } + else if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) { + failure_reason = QString("Received HTTP code %1").arg(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); + } + + data = reply->readAll(); + LyricsSearchResults results; + + if (!data.isEmpty()) { + QXmlStreamReader reader(data); + LyricsSearchResult result; + QString status; + while (!reader.atEnd()) { + QXmlStreamReader::TokenType type = reader.readNext(); + QStringRef name = reader.name(); + if (type == QXmlStreamReader::StartElement) { + if (name == "result") { + status.clear(); + result = LyricsSearchResult(); + } + else if (name == "status") { + status = reader.readElementText(); + } + else if (name == "response") { + if (status == "OK") { + result.lyrics = reader.readElementText(); + } + else { + failure_reason = reader.readElementText(); + result = LyricsSearchResult(); + } + } + } + else if (type == QXmlStreamReader::EndElement) { + if (name == "result") { + if (!result.lyrics.isEmpty()) { + results << result; + } + result = LyricsSearchResult(); + } + } + } + } + + if (results.isEmpty()) qLog(Debug) << "LoloLyrics: No lyrics for" << artist << title << failure_reason; + else qLog(Debug) << "LoloLyrics: Got lyrics for" << artist << title; + + emit SearchFinished(id, results); + +} + +void LoloLyricsProvider::Error(const quint64 id, const QString &error, QVariant debug) { + + qLog(Error) << "LoloLyrics:" << error; + if (debug.isValid()) qLog(Debug) << debug; + emit SearchFinished(id, LyricsSearchResults()); + +} diff --git a/src/lyrics/lololyricsprovider.h b/src/lyrics/lololyricsprovider.h new file mode 100644 index 000000000..ca197d525 --- /dev/null +++ b/src/lyrics/lololyricsprovider.h @@ -0,0 +1,56 @@ +/* + * Strawberry Music Player + * Copyright 2019, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef LOLOLYRICSPROVIDER_H +#define LOLOLYRICSPROVIDER_H + +#include "config.h" + +#include + +#include +#include +#include + +#include "lyricsprovider.h" +#include "lyricsfetcher.h" + +class QNetworkAccessManager; +class QNetworkReply; + +class LoloLyricsProvider : public LyricsProvider { + Q_OBJECT + + public: + explicit LoloLyricsProvider(QObject *parent = nullptr); + + bool StartSearch(const QString &artist, const QString &album, const QString &title, const quint64 id); + void CancelSearch(quint64 id); + + private slots: + void HandleSearchReply(QNetworkReply *reply, const quint64 id, const QString &artist, const QString &title); + + private: + static const char *kUrlSearch; + QNetworkAccessManager *network_; + void Error(const quint64 id, const QString &error, QVariant debug = QVariant()); + +}; + +#endif // LOLOLYRICSPROVIDER_H