summaryrefslogtreecommitdiff
path: root/media-sound/clementine/files
diff options
context:
space:
mode:
authorV3n3RiX <venerix@redcorelinux.org>2017-10-09 18:53:29 +0100
committerV3n3RiX <venerix@redcorelinux.org>2017-10-09 18:53:29 +0100
commit4f2d7949f03e1c198bc888f2d05f421d35c57e21 (patch)
treeba5f07bf3f9d22d82e54a462313f5d244036c768 /media-sound/clementine/files
reinit the tree, so we can have metadata
Diffstat (limited to 'media-sound/clementine/files')
-rw-r--r--media-sound/clementine/files/clementine-1.3-fix-tokenizer.patch21
-rw-r--r--media-sound/clementine/files/clementine-1.3.1-add-missing-functional-includes.patch51
-rw-r--r--media-sound/clementine/files/clementine-1.3.1-chromaprint14.patch41
-rw-r--r--media-sound/clementine/files/clementine-1.3.1-fix-desktop-file.patch52
-rw-r--r--media-sound/clementine/files/clementine-1.3.1-libechonest_removal.patch701
5 files changed, 866 insertions, 0 deletions
diff --git a/media-sound/clementine/files/clementine-1.3-fix-tokenizer.patch b/media-sound/clementine/files/clementine-1.3-fix-tokenizer.patch
new file mode 100644
index 000000000000..437518695a32
--- /dev/null
+++ b/media-sound/clementine/files/clementine-1.3-fix-tokenizer.patch
@@ -0,0 +1,21 @@
+https://github.com/clementine-player/Clementine/issues/5297
+
+--- a/src/core/database.cpp
++++ b/src/core/database.cpp
+@@ -265,6 +265,16 @@
+ StaticInit();
+
+ {
++#ifdef SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
++ QVariant v = db.driver()->handle();
++ if (v.isValid() && qstrcmp(v.typeName(), "sqlite3*") == 0) {
++ sqlite3* handle = *static_cast<sqlite3**>(v.data());
++ if (handle) {
++ sqlite3_db_config(handle, SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, NULL);
++ }
++ }
++#endif
++
+ QSqlQuery set_fts_tokenizer("SELECT fts3_tokenizer(:name, :pointer)", db);
+ set_fts_tokenizer.bindValue(":name", "unicode");
+ set_fts_tokenizer.bindValue(
diff --git a/media-sound/clementine/files/clementine-1.3.1-add-missing-functional-includes.patch b/media-sound/clementine/files/clementine-1.3.1-add-missing-functional-includes.patch
new file mode 100644
index 000000000000..e480212b883b
--- /dev/null
+++ b/media-sound/clementine/files/clementine-1.3.1-add-missing-functional-includes.patch
@@ -0,0 +1,51 @@
+From 8a6cc8b5069265e1e92e22def985e22c5955e503 Mon Sep 17 00:00:00 2001
+From: Morris Hafner <mmha@users.noreply.github.com>
+Date: Mon, 13 Feb 2017 17:46:46 +0100
+Subject: [PATCH] Add missing <functional> includes (#5630)
+
+---
+ src/core/mergedproxymodel.cpp | 1 +
+ src/devices/giolister.cpp | 1 +
+ src/library/groupbydialog.cpp | 2 ++
+ 3 files changed, 4 insertions(+)
+
+diff --git a/src/core/mergedproxymodel.cpp b/src/core/mergedproxymodel.cpp
+index 56217f6..8c210d3 100644
+--- a/src/core/mergedproxymodel.cpp
++++ b/src/core/mergedproxymodel.cpp
+@@ -23,6 +23,7 @@
+
+ #include <QStringList>
+
++#include <functional>
+ #include <limits>
+
+ // boost::multi_index still relies on these being in the global namespace.
+diff --git a/src/devices/giolister.cpp b/src/devices/giolister.cpp
+index aa3bddb..5f63ef2 100644
+--- a/src/devices/giolister.cpp
++++ b/src/devices/giolister.cpp
+@@ -17,6 +17,7 @@
+
+ #include "config.h"
+
++#include <functional>
+ #include <memory>
+
+ #include <QFile>
+diff --git a/src/library/groupbydialog.cpp b/src/library/groupbydialog.cpp
+index 5efdc9f..e5f711b 100644
+--- a/src/library/groupbydialog.cpp
++++ b/src/library/groupbydialog.cpp
+@@ -20,6 +20,8 @@
+
+ #include <QPushButton>
+
++#include <functional>
++
+ // boost::multi_index still relies on these being in the global namespace.
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+--
+2.10.2
+
diff --git a/media-sound/clementine/files/clementine-1.3.1-chromaprint14.patch b/media-sound/clementine/files/clementine-1.3.1-chromaprint14.patch
new file mode 100644
index 000000000000..bfdc49265aa3
--- /dev/null
+++ b/media-sound/clementine/files/clementine-1.3.1-chromaprint14.patch
@@ -0,0 +1,41 @@
+From ded312685735fc266d4154d355286eeb86db3bcd Mon Sep 17 00:00:00 2001
+From: Chocobozzz <florian.bigard@gmail.com>
+Date: Thu, 8 Dec 2016 23:12:17 +0100
+Subject: [PATCH] Add compatibility with chromaprint >= 1.4
+
+---
+ src/musicbrainz/chromaprinter.cpp | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/src/musicbrainz/chromaprinter.cpp b/src/musicbrainz/chromaprinter.cpp
+index 9579b62..c7ad99e 100644
+--- a/src/musicbrainz/chromaprinter.cpp
++++ b/src/musicbrainz/chromaprinter.cpp
+@@ -143,16 +143,24 @@ QString Chromaprinter::CreateFingerprint() {
+ ChromaprintContext* chromaprint =
+ chromaprint_new(CHROMAPRINT_ALGORITHM_DEFAULT);
+ chromaprint_start(chromaprint, kDecodeRate, kDecodeChannels);
+- chromaprint_feed(chromaprint, reinterpret_cast<void*>(data.data()),
++ chromaprint_feed(chromaprint, reinterpret_cast<int16_t *>(data.data()),
+ data.size() / 2);
+ chromaprint_finish(chromaprint);
+
+- void* fprint = nullptr;
+ int size = 0;
++
++#if CHROMAPRINT_VERSION_MAJOR >= 1 && CHROMAPRINT_VERSION_MINOR >= 4
++ u_int32_t *fprint = nullptr;
++ char *encoded = nullptr;
++#else
++ void *fprint = nullptr;
++ void *encoded = nullptr;
++#endif
++
+ int ret = chromaprint_get_raw_fingerprint(chromaprint, &fprint, &size);
++
+ QByteArray fingerprint;
+ if (ret == 1) {
+- void* encoded = nullptr;
+ int encoded_size = 0;
+ chromaprint_encode_fingerprint(fprint, size, CHROMAPRINT_ALGORITHM_DEFAULT,
+ &encoded, &encoded_size, 1);
diff --git a/media-sound/clementine/files/clementine-1.3.1-fix-desktop-file.patch b/media-sound/clementine/files/clementine-1.3.1-fix-desktop-file.patch
new file mode 100644
index 000000000000..bb561318c59d
--- /dev/null
+++ b/media-sound/clementine/files/clementine-1.3.1-fix-desktop-file.patch
@@ -0,0 +1,52 @@
+This patch fixes gentoo QA notices against the desktop file (see gentoo bug 460412#3)
+Based upon patch extracted from upstream git; original patch info:
+commit 04f73d125365d97fa6f72677ec5d220292690e56
+Author: Golubev Alexander <fatzer2@gmail.com>
+Date: Mon Jul 18 13:45:03 2016 +0400
+
+ Remove OnlyShowIn=Unity from clementine.desktop's action sections (#5444)
+
+diff --git a/dist/clementine.desktop b/dist/clementine.desktop
+index 2fb9559..9ee881e 100644
+--- a/dist/clementine.desktop
++++ b/dist/clementine.desktop
+@@ -38,7 +38,6 @@ Actions=Play;Pause;Stop;Previous;Next;
+ [Desktop Action Play]
+ Name=Play
+ Exec=clementine --play
+-OnlyShowIn=Unity;
+ Name[af]=Speel
+ Name[be]=Прайграць
+ Name[bg]=Възпроизвеждане
+@@ -89,7 +88,6 @@ Name[zh_TW]=播放
+ [Desktop Action Pause]
+ Name=Pause
+ Exec=clementine --pause
+-OnlyShowIn=Unity;
+ Name[be]=Прыпыніць
+ Name[bg]=Пауза
+ Name[br]=Ehan
+@@ -135,7 +133,6 @@ Name[zh_TW]=暫停
+ [Desktop Action Stop]
+ Name=Stop
+ Exec=clementine --stop
+-OnlyShowIn=Unity;
+ Name[be]=Спыніць
+ Name[bg]=Спиране
+ Name[br]=Paouez
+@@ -184,7 +181,6 @@ Name[zh_TW]=停止
+ [Desktop Action Previous]
+ Name=Previous
+ Exec=clementine --previous
+-OnlyShowIn=Unity;
+ Name[af]=Vorige
+ Name[be]=Папярэдні
+ Name[bg]=Предишна
+@@ -232,7 +228,6 @@ Name[zh_TW]=往前
+ [Desktop Action Next]
+ Name=Next
+ Exec=clementine --next
+-OnlyShowIn=Unity;
+ Name[af]=Volgende
+ Name[be]=Далей
+ Name[bg]=Следваща
diff --git a/media-sound/clementine/files/clementine-1.3.1-libechonest_removal.patch b/media-sound/clementine/files/clementine-1.3.1-libechonest_removal.patch
new file mode 100644
index 000000000000..63eb096d84d0
--- /dev/null
+++ b/media-sound/clementine/files/clementine-1.3.1-libechonest_removal.patch
@@ -0,0 +1,701 @@
+Remove depend upon media-libs/libechonest and its support from clementine due to echonest service
+was shutdown and this functionality is useless now and results in nothing but a slight security
+and privacy risk.
+See Gentoo bug #573712.
+Based upon patch extracted from upstream git; original patch info:
+commit a8a0f2e4fdd3d4b2fd23b8628a3abc27c290d01d
+Author: John Maguire <john.maguire@gmail.com>
+Date: Mon Jun 27 14:45:40 2016 +0100
+
+ Remove echonest and update songkick concert fetcher.
+--- Clementine-1.3.1/CMakeLists.txt
++++ Clementine-1.3.1/CMakeLists.txt
+@@ -365,9 +365,6 @@
+ 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)
+--- Clementine-1.3.1/src/CMakeLists.txt
++++ Clementine-1.3.1/src/CMakeLists.txt
+@@ -35,7 +35,6 @@
+ 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})
+@@ -297,8 +296,6 @@
+ songinfo/artistinfoview.cpp
+ songinfo/collapsibleinfoheader.cpp
+ songinfo/collapsibleinfopane.cpp
+- songinfo/echonestbiographies.cpp
+- songinfo/echonestimages.cpp
+ songinfo/songinfobase.cpp
+ songinfo/songinfofetcher.cpp
+ songinfo/songinfoprovider.cpp
+@@ -586,8 +583,6 @@
+ songinfo/artistinfoview.h
+ songinfo/collapsibleinfoheader.h
+ songinfo/collapsibleinfopane.h
+- songinfo/echonestbiographies.h
+- songinfo/echonestimages.h
+ songinfo/songinfobase.h
+ songinfo/songinfofetcher.h
+ songinfo/songinfoprovider.h
+@@ -822,16 +817,12 @@
+ 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
+@@ -1241,7 +1232,6 @@
+ ${TAGLIB_LIBRARIES}
+ ${MYGPOQT_LIBRARIES}
+ ${CHROMAPRINT_LIBRARIES}
+- ${ECHONEST_LIBRARIES}
+ ${GOBJECT_LIBRARIES}
+ ${GLIB_LIBRARIES}
+ ${GIO_LIBRARIES}
+--- Clementine-1.3.1/src/main.cpp
++++ Clementine-1.3.1/src/main.cpp
+@@ -76,8 +76,6 @@
+ #include <glib.h>
+ #include <gst/gst.h>
+
+-#include <echonest/Config.h>
+-
+ #ifdef Q_OS_DARWIN
+ #include <sys/resource.h>
+ #include <sys/sysctl.h>
+@@ -401,8 +399,8 @@
+ // 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();
+@@ -440,10 +438,6 @@
+ Application app;
+ app.set_language_name(language);
+
+- Echonest::Config::instance()->setAPIKey("DFLFLJBUF4EGTXHIG");
+- Echonest::Config::instance()->setNetworkAccessManager(
+- new NetworkAccessManager);
+-
+ // Network proxy
+ QNetworkProxyFactory::setApplicationProxyFactory(
+ NetworkProxyFactory::Instance());
+--- Clementine-1.3.1/src/songinfo/artistinfoview.cpp
++++ Clementine-1.3.1/src/songinfo/artistinfoview.cpp
+@@ -16,25 +16,12 @@
+ */
+
+ #include "artistinfoview.h"
+-#include "echonestbiographies.h"
+-#include "echonestimages.h"
+ #include "songinfofetcher.h"
+ #include "songkickconcerts.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 EchoNestImages);
+ fetcher_->AddProvider(new SongkickConcerts);
+-#ifdef HAVE_LIBLASTFM
+- fetcher_->AddProvider(new EchoNestSimilarArtists);
+- fetcher_->AddProvider(new EchoNestTags);
+-#endif
+ }
+
+ ArtistInfoView::~ArtistInfoView() {}
+--- Clementine-1.3.1/src/songinfo/echonestbiographies.cpp
++++ Clementine-1.3.1/src/songinfo/echonestbiographies.cpp
+@@ -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_);
+-}
+--- Clementine-1.3.1/src/songinfo/echonestbiographies.h
++++ Clementine-1.3.1/src/songinfo/echonestbiographies.h
+@@ -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
+--- Clementine-1.3.1/src/songinfo/echonestsimilarartists.cpp
++++ Clementine-1.3.1/src/songinfo/echonestsimilarartists.cpp
+@@ -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);
+-}
+--- Clementine-1.3.1/src/songinfo/echonestsimilarartists.h
++++ Clementine-1.3.1/src/songinfo/echonestsimilarartists.h
+@@ -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
+--- Clementine-1.3.1/src/songinfo/echonesttags.cpp
++++ Clementine-1.3.1/src/songinfo/echonesttags.cpp
+@@ -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_);
+-}
+--- Clementine-1.3.1/src/songinfo/echonesttags.h
++++ Clementine-1.3.1/src/songinfo/echonesttags.h
+@@ -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
+--- Clementine-1.3.1/src/songinfo/songkickconcerts.cpp
++++ Clementine-1.3.1/src/songinfo/songkickconcerts.cpp
+@@ -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;
+- }
+- }
+-
+- if (songkick_id.isEmpty()) {
+- qLog(Debug) << "Failed to fetch songkick foreign id for artist";
+- emit Finished(id);
+- return;
+- }
+-
+- 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();
++
++ QJson::Parser parser;
++ QVariantMap json = parser.parse(reply).toMap();
++
++ QVariantMap results_page = json["resultsPage"].toMap();
++ QVariantMap results = results_page["results"].toMap();
++ QVariantList artists = results["artist"].toList();
++
++ 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,
+--- Clementine-1.3.1/src/songinfo/songkickconcerts.h
++++ Clementine-1.3.1/src/songinfo/songkickconcerts.h
+@@ -44,9 +44,6 @@
+
+ NetworkAccessManager network_;
+ Geolocator::LatLng latlng_;
+-
+- static const char* kSongkickArtistBucket;
+- static const char* kSongkickArtistCalendarUrl;
+ };
+
+ #endif