191 lines
6.0 KiB
C++
191 lines
6.0 KiB
C++
/*
|
|
* Cantata
|
|
*
|
|
* Copyright (c) 2011-2014 Craig Drummond <craig.p.drummond@gmail.com>
|
|
*
|
|
* ----
|
|
*
|
|
* This program 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 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 this program; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "lastfmengine.h"
|
|
#include "network/networkaccessmanager.h"
|
|
#include "support/localize.h"
|
|
#include "gui/covers.h"
|
|
#include "config.h"
|
|
#if QT_VERSION >= 0x050000
|
|
#include <QUrlQuery>
|
|
#endif
|
|
#include <QXmlStreamReader>
|
|
#include <QRegExp>
|
|
|
|
#include <QDebug>
|
|
static bool debugEnabled=false;
|
|
#define DBUG if (debugEnabled) qWarning() << metaObject()->className() << __FUNCTION__
|
|
void LastFmEngine::enableDebug()
|
|
{
|
|
debugEnabled=true;
|
|
}
|
|
|
|
const QLatin1String LastFmEngine::constLang("lastfm");
|
|
const QLatin1String LastFmEngine::constLinkPlaceholder("XXX_CONTEXT_READ_MORE_ON_LASTFM_XXX");
|
|
|
|
static const char * constModeProperty="mode";
|
|
static const char * constQuery="query";
|
|
|
|
LastFmEngine::LastFmEngine(QObject *p)
|
|
: ContextEngine(p)
|
|
{
|
|
}
|
|
|
|
QStringList LastFmEngine::getLangs() const
|
|
{
|
|
QStringList langs;
|
|
langs.append(constLang);
|
|
return langs;
|
|
}
|
|
|
|
QString LastFmEngine::translateLinks(QString text) const
|
|
{
|
|
text=text.replace(constLinkPlaceholder, i18n("Read more on last.fm"));
|
|
return text;
|
|
}
|
|
|
|
void LastFmEngine::search(const QStringList &query, Mode mode)
|
|
{
|
|
QStringList fixedQuery=fixQuery(query);
|
|
QUrl url("https://ws.audioscrobbler.com/2.0/");
|
|
#if QT_VERSION < 0x050000
|
|
QUrl &urlQuery=url;
|
|
#else
|
|
QUrlQuery urlQuery;
|
|
#endif
|
|
|
|
urlQuery.addQueryItem("method", Artist==mode ? "artist.getInfo" : "album.getInfo");
|
|
urlQuery.addQueryItem("api_key", Covers::constLastFmApiKey);
|
|
urlQuery.addQueryItem("autocorrect", "1");
|
|
urlQuery.addQueryItem("artist", Covers::fixArtist(fixedQuery.at(0)));
|
|
if (Album==mode) {
|
|
urlQuery.addQueryItem("album", fixedQuery.at(1));
|
|
}
|
|
#if QT_VERSION >= 0x050000
|
|
url.setQuery(urlQuery);
|
|
#endif
|
|
|
|
job=NetworkAccessManager::self()->get(url);
|
|
job->setProperty(constModeProperty, (int)mode);
|
|
|
|
QStringList queryString;
|
|
foreach (QString q, fixedQuery) {
|
|
q=q.replace("/", "%2F");
|
|
q=q.replace(" ", "+");
|
|
queryString.append(q);
|
|
}
|
|
job->setProperty(constQuery, queryString.join("/"));
|
|
DBUG << url.toString();
|
|
connect(job, SIGNAL(finished()), this, SLOT(parseResponse()));
|
|
}
|
|
|
|
void LastFmEngine::parseResponse()
|
|
{
|
|
DBUG << __FUNCTION__;
|
|
NetworkJob *reply = getReply(sender());
|
|
if (!reply) {
|
|
return;
|
|
}
|
|
|
|
QByteArray data=reply->readAll();
|
|
if (!reply->ok() || data.isEmpty()) {
|
|
DBUG << "Empty/error";
|
|
emit searchResult(QString(), QString());
|
|
return;
|
|
}
|
|
|
|
Mode mode=(Mode)reply->property(constModeProperty).toInt();
|
|
QString text=Artist==mode ? parseArtistResponse(data) : parseAlbumResponse(data);
|
|
if (!text.isEmpty()) {
|
|
static const QRegExp constLicense("User-contributed text is available.*");
|
|
text.remove(constLicense);
|
|
text.replace("\n", "<br>");
|
|
text=text.simplified();
|
|
text.replace(" <br>", "<br>");
|
|
|
|
// Remove last.fm read more link (as we add our own!!)
|
|
int end=text.lastIndexOf(QLatin1String("on Last.fm</a>"));
|
|
if (-1!=end) {
|
|
int start=text.lastIndexOf(QLatin1String("<a href=\"http://www.last.fm/music/"), end);
|
|
if (-1!=start) {
|
|
if (text.indexOf(QLatin1String("Read more about"), start)<end) {
|
|
text=text.left(start);
|
|
}
|
|
}
|
|
}
|
|
text += QLatin1String("<br><br><a href='http://www.last.fm/music/")+reply->property(constQuery).toString()+QLatin1String("/+wiki'>")+constLinkPlaceholder+QLatin1String("</a>");
|
|
text.replace("<br><br><br><br><br>", "<br><br>");
|
|
text.replace("<br><br><br><br>", "<br><br>");
|
|
text.replace("<br><br><br>", "<br><br>");
|
|
}
|
|
emit searchResult(text, text.isEmpty() ? QString() : constLang);
|
|
}
|
|
|
|
QString LastFmEngine::parseArtistResponse(const QByteArray &data)
|
|
{
|
|
QXmlStreamReader xml(data);
|
|
while (xml.readNextStartElement()) {
|
|
if (QLatin1String("artist")==xml.name()) {
|
|
while (xml.readNextStartElement()) {
|
|
if (QLatin1String("bio")==xml.name()) {
|
|
while (xml.readNextStartElement()) {
|
|
if (QLatin1String("content")==xml.name()) {
|
|
return xml.readElementText().trimmed();
|
|
} else {
|
|
xml.skipCurrentElement();
|
|
}
|
|
}
|
|
} else {
|
|
xml.skipCurrentElement();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return QString();
|
|
}
|
|
|
|
QString LastFmEngine::parseAlbumResponse(const QByteArray &data)
|
|
{
|
|
QXmlStreamReader xml(data);
|
|
while (xml.readNextStartElement()) {
|
|
if (QLatin1String("album")==xml.name()) {
|
|
while (xml.readNextStartElement()) {
|
|
if (QLatin1String("wiki")==xml.name()) {
|
|
while (xml.readNextStartElement()) {
|
|
if (QLatin1String("content")==xml.name()) {
|
|
return xml.readElementText().trimmed();
|
|
} else {
|
|
xml.skipCurrentElement();
|
|
}
|
|
}
|
|
} else {
|
|
xml.skipCurrentElement();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return QString();
|
|
}
|