parent
f13288876f
commit
a8a0f2e4fd
@ -364,9 +364,6 @@ else (USE_SYSTEM_QXT)
|
||||
endif (NOT APPLE)
|
||||
endif (USE_SYSTEM_QXT)
|
||||
|
||||
find_path(ECHONEST_INCLUDE_DIRS echonest/echonest_export.h)
|
||||
find_library(ECHONEST_LIBRARIES echonest)
|
||||
|
||||
# Use system gmock if it's available
|
||||
# We need to look for both gmock and gtest
|
||||
find_path(GMOCK_INCLUDE_DIRS gmock/gmock.h)
|
||||
|
@ -35,7 +35,6 @@ include_directories(${LIBPROJECTM_INCLUDE_DIRS})
|
||||
include_directories(${QTSINGLEAPPLICATION_INCLUDE_DIRS})
|
||||
include_directories(${QTIOCOMPRESSOR_INCLUDE_DIRS})
|
||||
include_directories(${QXT_INCLUDE_DIRS})
|
||||
include_directories(${ECHONEST_INCLUDE_DIRS})
|
||||
include_directories(${SHA2_INCLUDE_DIRS})
|
||||
include_directories(${CHROMAPRINT_INCLUDE_DIRS})
|
||||
include_directories(${MYGPOQT_INCLUDE_DIRS})
|
||||
@ -301,7 +300,6 @@ set(SOURCES
|
||||
songinfo/artistinfoview.cpp
|
||||
songinfo/collapsibleinfoheader.cpp
|
||||
songinfo/collapsibleinfopane.cpp
|
||||
songinfo/echonestbiographies.cpp
|
||||
songinfo/songinfobase.cpp
|
||||
songinfo/songinfofetcher.cpp
|
||||
songinfo/songinfoprovider.cpp
|
||||
@ -593,7 +591,6 @@ set(HEADERS
|
||||
songinfo/artistinfoview.h
|
||||
songinfo/collapsibleinfoheader.h
|
||||
songinfo/collapsibleinfopane.h
|
||||
songinfo/echonestbiographies.h
|
||||
songinfo/songinfobase.h
|
||||
songinfo/songinfofetcher.h
|
||||
songinfo/songinfoprovider.h
|
||||
@ -830,16 +827,12 @@ optional_source(HAVE_LIBLASTFM
|
||||
internet/lastfm/lastfmcompat.cpp
|
||||
internet/lastfm/lastfmservice.cpp
|
||||
internet/lastfm/lastfmsettingspage.cpp
|
||||
songinfo/echonestsimilarartists.cpp
|
||||
songinfo/echonesttags.cpp
|
||||
songinfo/lastfmtrackinfoprovider.cpp
|
||||
songinfo/tagwidget.cpp
|
||||
HEADERS
|
||||
covers/lastfmcoverprovider.h
|
||||
internet/lastfm/lastfmservice.h
|
||||
internet/lastfm/lastfmsettingspage.h
|
||||
songinfo/echonestsimilarartists.h
|
||||
songinfo/echonesttags.h
|
||||
songinfo/lastfmtrackinfoprovider.h
|
||||
songinfo/tagwidget.h
|
||||
UI
|
||||
@ -1254,7 +1247,6 @@ target_link_libraries(clementine_lib
|
||||
${TAGLIB_LIBRARIES}
|
||||
${MYGPOQT_LIBRARIES}
|
||||
${CHROMAPRINT_LIBRARIES}
|
||||
${ECHONEST_LIBRARIES}
|
||||
${GOBJECT_LIBRARIES}
|
||||
${GLIB_LIBRARIES}
|
||||
${GIO_LIBRARIES}
|
||||
|
10
src/main.cpp
10
src/main.cpp
@ -73,8 +73,6 @@
|
||||
#include <glib.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <echonest/Config.h>
|
||||
|
||||
#ifdef Q_OS_DARWIN
|
||||
#include <sys/resource.h>
|
||||
#include <sys/sysctl.h>
|
||||
@ -398,8 +396,8 @@ int main(int argc, char* argv[]) {
|
||||
// Add root CA cert for SoundCloud, whose certificate is missing on OS X.
|
||||
QSslSocket::addDefaultCaCertificates(
|
||||
QSslCertificate::fromPath(":/soundcloud-ca.pem", QSsl::Pem));
|
||||
QSslSocket::addDefaultCaCertificates(
|
||||
QSslCertificate::fromPath(":/Equifax_Secure_Certificate_Authority.pem", QSsl::Pem));
|
||||
QSslSocket::addDefaultCaCertificates(QSslCertificate::fromPath(
|
||||
":/Equifax_Secure_Certificate_Authority.pem", QSsl::Pem));
|
||||
|
||||
// Has the user forced a different language?
|
||||
QString override_language = options.language();
|
||||
@ -437,10 +435,6 @@ int main(int argc, char* argv[]) {
|
||||
Application app;
|
||||
app.set_language_name(language);
|
||||
|
||||
Echonest::Config::instance()->setAPIKey("DFLFLJBUF4EGTXHIG");
|
||||
Echonest::Config::instance()->setNetworkAccessManager(
|
||||
new NetworkAccessManager);
|
||||
|
||||
// Network proxy
|
||||
QNetworkProxyFactory::setApplicationProxyFactory(
|
||||
NetworkProxyFactory::Instance());
|
||||
|
@ -17,25 +17,14 @@
|
||||
|
||||
#include "artistinfoview.h"
|
||||
|
||||
#include "songinfo/echonestbiographies.h"
|
||||
#include "songinfo/songinfofetcher.h"
|
||||
#include "songinfo/songkickconcerts.h"
|
||||
#include "songinfo/spotifyimages.h"
|
||||
#include "widgets/prettyimageview.h"
|
||||
|
||||
#ifdef HAVE_LIBLASTFM
|
||||
#include "echonestsimilarartists.h"
|
||||
#include "echonesttags.h"
|
||||
#endif
|
||||
|
||||
ArtistInfoView::ArtistInfoView(QWidget* parent) : SongInfoBase(parent) {
|
||||
fetcher_->AddProvider(new EchoNestBiographies);
|
||||
fetcher_->AddProvider(new SongkickConcerts);
|
||||
fetcher_->AddProvider(new SpotifyImages);
|
||||
#ifdef HAVE_LIBLASTFM
|
||||
fetcher_->AddProvider(new EchoNestSimilarArtists);
|
||||
fetcher_->AddProvider(new EchoNestTags);
|
||||
#endif
|
||||
}
|
||||
|
||||
ArtistInfoView::~ArtistInfoView() {}
|
||||
|
@ -1,123 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine 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.
|
||||
|
||||
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "echonestbiographies.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <echonest/Artist.h>
|
||||
|
||||
#include "songinfotextview.h"
|
||||
#include "core/logging.h"
|
||||
#include "ui/iconloader.h"
|
||||
|
||||
struct EchoNestBiographies::Request {
|
||||
Request(int id) : id_(id), artist_(new Echonest::Artist) {}
|
||||
|
||||
int id_;
|
||||
std::unique_ptr<Echonest::Artist> artist_;
|
||||
};
|
||||
|
||||
EchoNestBiographies::EchoNestBiographies() {
|
||||
site_relevance_["wikipedia"] = 100;
|
||||
site_relevance_["lastfm"] = 60;
|
||||
site_relevance_["amazon"] = 30;
|
||||
|
||||
site_icons_["amazon"] = IconLoader::Load("amazon", IconLoader::Provider);
|
||||
site_icons_["aol"] = IconLoader::Load("aol", IconLoader::Provider);
|
||||
site_icons_["cdbaby"] = IconLoader::Load("cdbaby", IconLoader::Provider);
|
||||
site_icons_["lastfm"] = IconLoader::Load("as", IconLoader::Lastfm);
|
||||
site_icons_["mog"] = IconLoader::Load("mog", IconLoader::Provider);
|
||||
site_icons_["mtvmusic"] = IconLoader::Load("mtvmusic", IconLoader::Provider);
|
||||
site_icons_["myspace"] = IconLoader::Load("myspace", IconLoader::Provider);
|
||||
site_icons_["wikipedia"] = IconLoader::Load("wikipedia", IconLoader::Provider);
|
||||
}
|
||||
|
||||
void EchoNestBiographies::FetchInfo(int id, const Song& metadata) {
|
||||
std::shared_ptr<Request> request(new Request(id));
|
||||
request->artist_->setName(metadata.artist());
|
||||
|
||||
QNetworkReply* reply = request->artist_->fetchBiographies();
|
||||
connect(reply, SIGNAL(finished()), SLOT(RequestFinished()));
|
||||
requests_[reply] = request;
|
||||
}
|
||||
|
||||
void EchoNestBiographies::RequestFinished() {
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
||||
if (!reply || !requests_.contains(reply)) return;
|
||||
reply->deleteLater();
|
||||
|
||||
RequestPtr request = requests_.take(reply);
|
||||
|
||||
try {
|
||||
request->artist_->parseProfile(reply);
|
||||
}
|
||||
catch (Echonest::ParseError e) {
|
||||
qLog(Warning) << "Error parsing echonest reply:" << e.errorType()
|
||||
<< e.what();
|
||||
}
|
||||
|
||||
QSet<QString> already_seen;
|
||||
|
||||
for (const Echonest::Biography& bio : request->artist_->biographies()) {
|
||||
QString canonical_site = bio.site().toLower();
|
||||
canonical_site.replace(QRegExp("[^a-z]"), "");
|
||||
|
||||
if (already_seen.contains(canonical_site)) continue;
|
||||
already_seen.insert(canonical_site);
|
||||
|
||||
CollapsibleInfoPane::Data data;
|
||||
data.id_ = "echonest/bio/" + bio.site();
|
||||
data.title_ = tr("Biography from %1").arg(bio.site());
|
||||
data.type_ = CollapsibleInfoPane::Data::Type_Biography;
|
||||
|
||||
if (site_relevance_.contains(canonical_site))
|
||||
data.relevance_ = site_relevance_[canonical_site];
|
||||
if (site_icons_.contains(canonical_site))
|
||||
data.icon_ = site_icons_[canonical_site];
|
||||
|
||||
SongInfoTextView* editor = new SongInfoTextView;
|
||||
QString text;
|
||||
// Add a link to the bio webpage at the top if we have one
|
||||
if (!bio.url().isEmpty()) {
|
||||
QString bio_url = bio.url().toEncoded();
|
||||
if (bio.site() == "facebook") {
|
||||
bio_url.replace("graph.facebook.com", "www.facebook.com");
|
||||
}
|
||||
text += "<p><a href=\"" + bio_url + "\">" +
|
||||
tr("Open in your browser") + "</a></p>";
|
||||
}
|
||||
|
||||
text += bio.text();
|
||||
if (bio.site() == "last.fm") {
|
||||
// Echonest lost formatting and it seems there is currently no plans on
|
||||
// Echonest side for changing this.
|
||||
// But with last.fm, we can guess newlines: " " corresponds to a newline
|
||||
// (this seems to be because on last.fm' website, extra blank is inserted
|
||||
// before <br /> tag, and this blank is kept).
|
||||
// This is tricky, but this make the display nicer for last.fm
|
||||
// biographies.
|
||||
text.replace(" ", "<p>");
|
||||
}
|
||||
editor->SetHtml(text);
|
||||
data.contents_ = editor;
|
||||
|
||||
emit InfoReady(request->id_, data);
|
||||
}
|
||||
|
||||
emit Finished(request->id_);
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine 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.
|
||||
|
||||
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECHONESTBIOGRAPHIES_H
|
||||
#define ECHONESTBIOGRAPHIES_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "songinfoprovider.h"
|
||||
|
||||
class QNetworkReply;
|
||||
|
||||
class EchoNestBiographies : public SongInfoProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EchoNestBiographies();
|
||||
|
||||
void FetchInfo(int id, const Song& metadata);
|
||||
|
||||
private slots:
|
||||
void RequestFinished();
|
||||
|
||||
private:
|
||||
QMap<QString, int> site_relevance_;
|
||||
QMap<QString, QIcon> site_icons_;
|
||||
|
||||
struct Request;
|
||||
typedef std::shared_ptr<Request> RequestPtr;
|
||||
|
||||
QMap<QNetworkReply*, RequestPtr> requests_;
|
||||
};
|
||||
|
||||
#endif // ECHONESTBIOGRAPHIES_H
|
@ -1,76 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine 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.
|
||||
|
||||
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "echonestsimilarartists.h"
|
||||
#include "tagwidget.h"
|
||||
#include "core/logging.h"
|
||||
#include "ui/iconloader.h"
|
||||
|
||||
#include <echonest/Artist.h>
|
||||
|
||||
Q_DECLARE_METATYPE(QVector<QString>);
|
||||
|
||||
void EchoNestSimilarArtists::FetchInfo(int id, const Song& metadata) {
|
||||
using Echonest::Artist;
|
||||
|
||||
Artist::SearchParams params;
|
||||
params << Artist::SearchParamEntry(Artist::Name, metadata.artist());
|
||||
params << Artist::SearchParamEntry(Artist::MinHotttnesss, 0.5);
|
||||
|
||||
QNetworkReply* reply = Echonest::Artist::fetchSimilar(params);
|
||||
connect(reply, SIGNAL(finished()), SLOT(RequestFinished()));
|
||||
requests_[reply] = id;
|
||||
}
|
||||
|
||||
void EchoNestSimilarArtists::RequestFinished() {
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
||||
if (!reply || !requests_.contains(reply)) return;
|
||||
reply->deleteLater();
|
||||
|
||||
int id = requests_.take(reply);
|
||||
|
||||
Echonest::Artists artists;
|
||||
try {
|
||||
artists = Echonest::Artist::parseSimilar(reply);
|
||||
}
|
||||
catch (Echonest::ParseError e) {
|
||||
qLog(Warning) << "Error parsing echonest reply:" << e.errorType()
|
||||
<< e.what();
|
||||
}
|
||||
|
||||
if (!artists.isEmpty()) {
|
||||
CollapsibleInfoPane::Data data;
|
||||
data.id_ = "echonest/similarartists";
|
||||
data.title_ = tr("Similar artists");
|
||||
data.type_ = CollapsibleInfoPane::Data::Type_Similar;
|
||||
data.icon_ = IconLoader::Load("echonest", IconLoader::Provider);
|
||||
|
||||
TagWidget* widget = new TagWidget(TagWidget::Type_Artists);
|
||||
data.contents_ = widget;
|
||||
|
||||
widget->SetIcon(IconLoader::Load("x-clementine-artist", IconLoader::Base));
|
||||
|
||||
for (const Echonest::Artist& artist : artists) {
|
||||
widget->AddTag(artist.name());
|
||||
if (widget->count() >= 10) break;
|
||||
}
|
||||
|
||||
emit InfoReady(id, data);
|
||||
}
|
||||
|
||||
emit Finished(id);
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine 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.
|
||||
|
||||
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECHONESTSIMILARARTISTS_H
|
||||
#define ECHONESTSIMILARARTISTS_H
|
||||
|
||||
#include "songinfoprovider.h"
|
||||
|
||||
class QNetworkReply;
|
||||
|
||||
class EchoNestSimilarArtists : public SongInfoProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void FetchInfo(int id, const Song& metadata);
|
||||
|
||||
private slots:
|
||||
void RequestFinished();
|
||||
|
||||
private:
|
||||
QMap<QNetworkReply*, int> requests_;
|
||||
};
|
||||
|
||||
#endif // ECHONESTSIMILARARTISTS_H
|
@ -1,80 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine 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.
|
||||
|
||||
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "echonesttags.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <echonest/Artist.h>
|
||||
|
||||
#include "tagwidget.h"
|
||||
#include "core/logging.h"
|
||||
#include "ui/iconloader.h"
|
||||
|
||||
struct EchoNestTags::Request {
|
||||
Request(int id) : id_(id), artist_(new Echonest::Artist) {}
|
||||
|
||||
int id_;
|
||||
std::unique_ptr<Echonest::Artist> artist_;
|
||||
};
|
||||
|
||||
void EchoNestTags::FetchInfo(int id, const Song& metadata) {
|
||||
std::shared_ptr<Request> request(new Request(id));
|
||||
request->artist_->setName(metadata.artist());
|
||||
|
||||
QNetworkReply* reply = request->artist_->fetchTerms();
|
||||
connect(reply, SIGNAL(finished()), SLOT(RequestFinished()));
|
||||
requests_[reply] = request;
|
||||
}
|
||||
|
||||
void EchoNestTags::RequestFinished() {
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
||||
if (!reply || !requests_.contains(reply)) return;
|
||||
reply->deleteLater();
|
||||
|
||||
RequestPtr request = requests_.take(reply);
|
||||
|
||||
try {
|
||||
request->artist_->parseProfile(reply);
|
||||
}
|
||||
catch (Echonest::ParseError e) {
|
||||
qLog(Warning) << "Error parsing echonest reply:" << e.errorType()
|
||||
<< e.what();
|
||||
}
|
||||
|
||||
if (!request->artist_->terms().isEmpty()) {
|
||||
CollapsibleInfoPane::Data data;
|
||||
data.id_ = "echonest/artisttags";
|
||||
data.title_ = tr("Artist tags");
|
||||
data.type_ = CollapsibleInfoPane::Data::Type_Tags;
|
||||
data.icon_ = IconLoader::Load("icon_tag", IconLoader::Lastfm);
|
||||
|
||||
TagWidget* widget = new TagWidget(TagWidget::Type_Tags);
|
||||
data.contents_ = widget;
|
||||
|
||||
widget->SetIcon(data.icon_);
|
||||
|
||||
for (const Echonest::Term& term : request->artist_->terms()) {
|
||||
widget->AddTag(term.name());
|
||||
if (widget->count() >= 10) break;
|
||||
}
|
||||
|
||||
emit InfoReady(request->id_, data);
|
||||
}
|
||||
|
||||
emit Finished(request->id_);
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
|
||||
Clementine 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.
|
||||
|
||||
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECHONESTTAGS_H
|
||||
#define ECHONESTTAGS_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "songinfoprovider.h"
|
||||
|
||||
class QNetworkReply;
|
||||
|
||||
class EchoNestTags : public SongInfoProvider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void FetchInfo(int id, const Song& metadata);
|
||||
|
||||
private slots:
|
||||
void RequestFinished();
|
||||
|
||||
private:
|
||||
struct Request;
|
||||
typedef std::shared_ptr<Request> RequestPtr;
|
||||
|
||||
QMap<QNetworkReply*, RequestPtr> requests_;
|
||||
};
|
||||
|
||||
#endif // ECHONESTTAGS_H
|
@ -21,9 +21,6 @@
|
||||
#include <QVBoxLayout>
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
#include <echonest/Artist.h>
|
||||
#include <echonest/TypeInformation.h>
|
||||
|
||||
#include <qjson/parser.h>
|
||||
|
||||
#include "core/closure.h"
|
||||
@ -31,77 +28,64 @@
|
||||
#include "songkickconcertwidget.h"
|
||||
#include "ui/iconloader.h"
|
||||
|
||||
const char* SongkickConcerts::kSongkickArtistBucket = "songkick";
|
||||
const char* SongkickConcerts::kSongkickArtistCalendarUrl =
|
||||
"https://api.songkick.com/api/3.0/artists/%1/calendar.json?"
|
||||
"per_page=5&"
|
||||
"apikey=8rgKfy1WU6IlJFfN";
|
||||
namespace {
|
||||
const char* kSongkickArtistCalendarUrl =
|
||||
"https://api.songkick.com/api/3.0/artists/%1/calendar.json";
|
||||
const char* kSongkickArtistSearchUrl =
|
||||
"https://api.songkick.com/api/3.0/search/artists.json";
|
||||
const char* kSongkickApiKey = "8rgKfy1WU6IlJFfN";
|
||||
} // namespace
|
||||
|
||||
SongkickConcerts::SongkickConcerts() {
|
||||
Geolocator* geolocator = new Geolocator;
|
||||
geolocator->Geolocate();
|
||||
connect(geolocator, SIGNAL(Finished(Geolocator::LatLng)),
|
||||
SLOT(GeolocateFinished(Geolocator::LatLng)));
|
||||
NewClosure(geolocator, SIGNAL(Finished(Geolocator::LatLng)), geolocator,
|
||||
SLOT(deleteLater()));
|
||||
connect(geolocator, SIGNAL(Finished(Geolocator::LatLng)), geolocator,
|
||||
SLOT(deleteLater()));
|
||||
}
|
||||
|
||||
void SongkickConcerts::FetchInfo(int id, const Song& metadata) {
|
||||
Echonest::Artist::SearchParams params;
|
||||
params.push_back(
|
||||
qMakePair(Echonest::Artist::Name, QVariant(metadata.artist())));
|
||||
qLog(Debug) << "Params:" << params;
|
||||
QNetworkReply* reply = Echonest::Artist::search(
|
||||
params,
|
||||
Echonest::ArtistInformation(Echonest::ArtistInformation::NoInformation,
|
||||
QStringList() << kSongkickArtistBucket));
|
||||
qLog(Debug) << reply->request().url();
|
||||
if (metadata.artist().isEmpty()) {
|
||||
emit Finished(id);
|
||||
return;
|
||||
}
|
||||
|
||||
QUrl url(kSongkickArtistSearchUrl);
|
||||
url.addQueryItem("apikey", kSongkickApiKey);
|
||||
url.addQueryItem("query", metadata.artist());
|
||||
|
||||
QNetworkRequest request(url);
|
||||
QNetworkReply* reply = network_.get(request);
|
||||
NewClosure(reply, SIGNAL(finished()), this,
|
||||
SLOT(ArtistSearchFinished(QNetworkReply*, int)), reply, id);
|
||||
}
|
||||
|
||||
void SongkickConcerts::ArtistSearchFinished(QNetworkReply* reply, int id) {
|
||||
reply->deleteLater();
|
||||
try {
|
||||
Echonest::Artists artists = Echonest::Artist::parseSearch(reply);
|
||||
if (artists.isEmpty()) {
|
||||
qLog(Debug) << "Failed to find artist in echonest";
|
||||
emit Finished(id);
|
||||
return;
|
||||
}
|
||||
|
||||
const Echonest::Artist& artist = artists[0];
|
||||
const Echonest::ForeignIds& foreign_ids = artist.foreignIds();
|
||||
QString songkick_id;
|
||||
for (const Echonest::ForeignId& id : foreign_ids) {
|
||||
if (id.catalog == "songkick") {
|
||||
songkick_id = id.foreign_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
QJson::Parser parser;
|
||||
QVariantMap json = parser.parse(reply).toMap();
|
||||
|
||||
if (songkick_id.isEmpty()) {
|
||||
qLog(Debug) << "Failed to fetch songkick foreign id for artist";
|
||||
emit Finished(id);
|
||||
return;
|
||||
}
|
||||
QVariantMap results_page = json["resultsPage"].toMap();
|
||||
QVariantMap results = results_page["results"].toMap();
|
||||
QVariantList artists = results["artist"].toList();
|
||||
|
||||
QStringList split = songkick_id.split(':');
|
||||
if (split.count() != 3) {
|
||||
qLog(Error) << "Weird songkick id";
|
||||
emit Finished(id);
|
||||
return;
|
||||
}
|
||||
|
||||
FetchSongkickCalendar(split[2], id);
|
||||
} catch (Echonest::ParseError& e) {
|
||||
qLog(Error) << "Error parsing echonest reply:" << e.errorType() << e.what();
|
||||
if (artists.isEmpty()) {
|
||||
emit Finished(id);
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap artist = artists.first().toMap();
|
||||
QString artist_id = artist["id"].toString();
|
||||
|
||||
FetchSongkickCalendar(artist_id, id);
|
||||
}
|
||||
|
||||
void SongkickConcerts::FetchSongkickCalendar(const QString& artist_id, int id) {
|
||||
QUrl url(QString(kSongkickArtistCalendarUrl).arg(artist_id));
|
||||
url.addQueryItem("per_page", "5");
|
||||
url.addQueryItem("apikey", kSongkickApiKey);
|
||||
qLog(Debug) << url;
|
||||
QNetworkReply* reply = network_.get(QNetworkRequest(url));
|
||||
NewClosure(reply, SIGNAL(finished()), this,
|
||||
|
@ -44,9 +44,6 @@ class SongkickConcerts : public SongInfoProvider {
|
||||
|
||||
NetworkAccessManager network_;
|
||||
Geolocator::LatLng latlng_;
|
||||
|
||||
static const char* kSongkickArtistBucket;
|
||||
static const char* kSongkickArtistCalendarUrl;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user