diff options
-rw-r--r-- | src/library/dlgtagfetcher.cpp | 51 | ||||
-rw-r--r-- | src/library/dlgtagfetcher.h | 2 | ||||
-rw-r--r-- | src/library/dlgtagfetcher.ui | 20 | ||||
-rw-r--r-- | src/musicbrainz/acoustidclient.cpp | 63 | ||||
-rw-r--r-- | src/musicbrainz/acoustidclient.h | 4 | ||||
-rw-r--r-- | src/musicbrainz/musicbrainzclient.cpp | 58 | ||||
-rw-r--r-- | src/musicbrainz/musicbrainzclient.h | 6 | ||||
-rw-r--r-- | src/musicbrainz/network.cpp | 4 | ||||
-rw-r--r-- | src/musicbrainz/tagfetcher.cpp | 24 | ||||
-rw-r--r-- | src/musicbrainz/tagfetcher.h | 2 |
10 files changed, 138 insertions, 96 deletions
diff --git a/src/library/dlgtagfetcher.cpp b/src/library/dlgtagfetcher.cpp index b470121a75..6909ef80eb 100644 --- a/src/library/dlgtagfetcher.cpp +++ b/src/library/dlgtagfetcher.cpp @@ -16,23 +16,23 @@ DlgTagFetcher::~DlgTagFetcher() { void DlgTagFetcher::init() { setupUi(this); - connect(btnApply, SIGNAL(clicked()), - this, SLOT(apply())); - connect(btnQuit, SIGNAL(clicked()), - this, SLOT(quit())); - connect(btnPrev, SIGNAL(clicked()), - this, SIGNAL(previous())); - connect(btnNext, SIGNAL(clicked()), - this, SIGNAL(next())); - connect(results, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), - this, SLOT(resultSelected())); - - connect(&m_TagFetcher, SIGNAL(resultAvailable(const TrackPointer,const QList<TrackPointer>&)), - this, SLOT(fetchTagFinished(const TrackPointer,const QList<TrackPointer>&))); - connect(&m_TagFetcher, SIGNAL(fetchProgress(QString)), - this, SLOT(fetchTagProgress(QString))); - connect(&m_TagFetcher, SIGNAL(networkError(int, QString)), - this, SLOT(slotNetworkError(int, QString))); + connect(btnApply, &QPushButton::clicked, + this, &DlgTagFetcher::apply); + connect(btnQuit, &QPushButton::clicked, + this, &DlgTagFetcher::quit); + connect(btnPrev, &QPushButton::clicked, + this, &DlgTagFetcher::previous); + connect(btnNext, &QPushButton::clicked, + this, &DlgTagFetcher::next); + connect(results, &QTreeWidget::currentItemChanged, + this, &DlgTagFetcher::resultSelected); + + connect(&m_TagFetcher, &TagFetcher::resultAvailable, + this, &DlgTagFetcher::fetchTagFinished); + connect(&m_TagFetcher, &TagFetcher::fetchProgress, + this, &DlgTagFetcher::fetchTagProgress); + connect(&m_TagFetcher, &TagFetcher::networkError, + this, &DlgTagFetcher::slotNetworkError); // Resize columns, this can't be set in the ui file results->setColumnWidth(0, 50); // Track column @@ -47,14 +47,16 @@ void DlgTagFetcher::loadTrack(const TrackPointer track) { return; } results->clear(); + disconnect(track.get(), &Track::changed, + this, &DlgTagFetcher::updateTrackMetadata); + m_track = track; m_data = Data(); m_networkError = NOERROR; m_TagFetcher.startFetch(m_track); - disconnect(this, SLOT(updateTrackMetadata(Track*))); - connect(track.get(), SIGNAL(changed(Track*)), - this, SLOT(updateTrackMetadata(Track*))); + connect(track.get(), &Track::changed, + this, &DlgTagFetcher::updateTrackMetadata); updateStack(); } @@ -110,11 +112,12 @@ void DlgTagFetcher::fetchTagFinished(const TrackPointer track, updateStack(); } -void DlgTagFetcher::slotNetworkError(int errorCode, QString app) { - m_networkError = errorCode==0 ? FTWERROR : HTTPERROR; +void DlgTagFetcher::slotNetworkError(int httpError, QString app, QString message, int code) { + m_networkError = httpError == 0 ? FTWERROR : HTTPERROR; m_data.m_pending = false; - QString httpStatusMessage = tr("HTTP Status: %1"); - httpStatus->setText(httpStatusMessage.arg(errorCode)); + QString strError = tr("HTTP Status: %1"); + QString strCode = tr("Code: %1"); + httpStatus->setText(strError.arg(httpError) + "\n" + strCode.arg(code) + "\n" + message); QString unknownError = tr("Mixxx can't connect to %1 for an unknown reason."); cantConnectMessage->setText(unknownError.arg(app)); QString cantConnect = tr("Mixxx can't connect to %1."); diff --git a/src/library/dlgtagfetcher.h b/src/library/dlgtagfetcher.h index fcb954ca85..714e7b6507 100644 --- a/src/library/dlgtagfetcher.h +++ b/src/library/dlgtagfetcher.h @@ -35,7 +35,7 @@ class DlgTagFetcher : public QDialog, public Ui::DlgTagFetcher { void fetchTagFinished(const TrackPointer,const QList<TrackPointer>& tracks); void resultSelected(); void fetchTagProgress(QString); - void slotNetworkError(int, QString); + void slotNetworkError(int httpStatus, QString app, QString message, int code); void apply(); void quit(); diff --git a/src/library/dlgtagfetcher.ui b/src/library/dlgtagfetcher.ui index 161f8c969b..99d1efcee9 100644 --- a/src/library/dlgtagfetcher.ui +++ b/src/library/dlgtagfetcher.ui @@ -17,7 +17,7 @@ <item> <widget class="QStackedWidget" name="stack"> <property name="currentIndex"> - <number>0</number> + <number>2</number> </property> <widget class="QWidget" name="results_page"> <layout class="QVBoxLayout" name="verticalLayout_2"> @@ -45,12 +45,6 @@ <attribute name="headerMinimumSectionSize"> <number>50</number> </attribute> - <attribute name="headerDefaultSectionSize"> - <number>150</number> - </attribute> - <attribute name="headerMinimumSectionSize"> - <number>50</number> - </attribute> <column> <property name="text"> <string>Track</string> @@ -253,9 +247,21 @@ </item> <item> <widget class="QLabel" name="httpStatus"> + <property name="maximumSize"> + <size> + <width>600</width> + <height>300</height> + </size> + </property> <property name="text"> <string notr="true">HTTP Status: %1</string> </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::TextSelectableByMouse</set> + </property> </widget> </item> <item> diff --git a/src/musicbrainz/acoustidclient.cpp b/src/musicbrainz/acoustidclient.cpp index 46ad81c60f..8e03c89c3a 100644 --- a/src/musicbrainz/acoustidclient.cpp +++ b/src/musicbrainz/acoustidclient.cpp @@ -18,16 +18,20 @@ #include "musicbrainz/gzip.h" #include "musicbrainz/network.h" +namespace { + // see API-KEY site here http://acoustid.org/application/496 // I registered the KEY for version 1.12 -- kain88 (may 2013) const QString CLIENT_APIKEY = "czKxnkyO"; const QString ACOUSTID_URL = "http://api.acoustid.org/v2/lookup"; -const int AcoustidClient::m_DefaultTimeout = 5000; // msec +constexpr int kDefaultTimeout = 5000; // msec + +} // anonymous namespace AcoustidClient::AcoustidClient(QObject* parent) : QObject(parent), m_network(this), - m_timeouts(m_DefaultTimeout, this) { + m_timeouts(kDefaultTimeout, this) { } void AcoustidClient::setTimeout(int msec) { @@ -53,7 +57,7 @@ void AcoustidClient::start(int id, const QString& fingerprint, int duration) { << "body:" << body; QNetworkReply* reply = m_network.post(req, gzipCompress(body)); - connect(reply, SIGNAL(finished()), SLOT(requestFinished())); + connect(reply, &QNetworkReply::finished, this, &AcoustidClient::requestFinished); m_requests[reply] = id; m_timeouts.addReply(reply); @@ -87,30 +91,53 @@ void AcoustidClient::requestFinished() { int id = m_requests.take(reply); int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (status != 200) { - QTextStream body(reply); - qDebug() << "AcoustIdClient POST reply status:" << status << "body:" << body.readAll(); + QTextStream textReader(reply); + const QByteArray body(reply->readAll()); + QXmlStreamReader reader(body); + + QString statusText; + while (!reader.atEnd() && statusText.isEmpty()) { + if (reader.readNextStartElement()) { + const QStringRef name = reader.name(); + if (name == "status") { + statusText = reader.readElementText(); + } + } + } + + if (status != 200 || statusText != "ok") { + qDebug() << "AcoustIdClient POST reply status:" << status << "body:" << body; + QString message; + QString code; + while (!reader.atEnd() && (message.isEmpty() || code.isEmpty())) { + if (reader.readNextStartElement()) { + const QStringRef name = reader.name(); + if (name == "message") { + DEBUG_ASSERT(name.isEmpty()); // fail if we have duplicated message elements. + message = reader.readElementText(); + } else if (name == "code") { + DEBUG_ASSERT(code.isEmpty()); // fail if we have duplicated code elements. + code = reader.readElementText(); + } + } + } emit(networkError( reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), - "AcoustID")); + "AcoustID", message, code.toInt())); return; } - - QTextStream textReader(reply); - QString body = textReader.readAll(); qDebug() << "AcoustIdClient POST reply status:" << status << "body:" << body; - QXmlStreamReader reader(body); - QString ID; - while (!reader.atEnd()) { - if (reader.readNext() == QXmlStreamReader::StartElement - && reader.name()== "results") { - ID = parseResult(reader); - } + QString resultId; + while (!reader.atEnd() && resultId.isEmpty()) { + if (reader.readNextStartElement() + && reader.name()== "results") { + resultId = parseResult(reader); + } } - emit(finished(id, ID)); + emit(finished(id, resultId)); } QString AcoustidClient::parseResult(QXmlStreamReader& reader) { diff --git a/src/musicbrainz/acoustidclient.h b/src/musicbrainz/acoustidclient.h index a7ce14e136..551dce9fa6 100644 --- a/src/musicbrainz/acoustidclient.h +++ b/src/musicbrainz/acoustidclient.h @@ -52,14 +52,12 @@ class AcoustidClient : public QObject { signals: void finished(int id, const QString& mbid); - void networkError(int, QString); + void networkError(int httpStatus, QString app, QString message, int code); private slots: void requestFinished(); private: - static const int m_DefaultTimeout; - QNetworkAccessManager m_network; NetworkTimeouts m_timeouts; QMap<QNetworkReply*, int> m_requests; diff --git a/src/musicbrainz/musicbrainzclient.cpp b/src/musicbrainz/musicbrainzclient.cpp index 264ad97e2b..9179933f49 100644 --- a/src/musicbrainz/musicbrainzclient.cpp +++ b/src/musicbrainz/musicbrainzclient.cpp @@ -14,19 +14,37 @@ #include <QTextStream> #include <QXmlStreamReader> #include <QUrl> +#include <QJsonDocument> #include "musicbrainz/musicbrainzclient.h" #include "util/version.h" #include "defs_urls.h" -const QString MusicBrainzClient::m_TrackUrl = "http://musicbrainz.org/ws/2/recording/"; -const QString MusicBrainzClient::m_DateRegex = "^[12]\\d{3}"; -const int MusicBrainzClient::m_DefaultTimeout = 5000; // msec + +namespace { + +const QString kTrackUrl = "http://musicbrainz.org/ws/2/recording/"; +const QString kDateRegex = "^[12]\\d{3}"; +constexpr int kDefaultTimeout = 5000; // msec +constexpr int kDefaultErrorCode = 0; + +QString decodeText(const QByteArray& data, const QStringRef codecName) { + QTextStream textStream(data); + if (!codecName.isEmpty()) { + textStream.setCodec(QTextCodec::codecForName(codecName.toUtf8())); + } + return textStream.readAll(); +} + +} // anonymous namespace + + + MusicBrainzClient::MusicBrainzClient(QObject* parent) : QObject(parent), m_network(this), - m_timeouts(m_DefaultTimeout, this) { + m_timeouts(kDefaultTimeout, this) { } void MusicBrainzClient::start(int id, const QString& mbid) { @@ -37,7 +55,7 @@ void MusicBrainzClient::start(int id, const QString& mbid) { QUrlQuery query; query.setQueryItems(parameters); - QUrl url(m_TrackUrl + mbid); + QUrl url(kTrackUrl + mbid); url.setQuery(query); qDebug() << "MusicBrainzClient GET request:" << url.toString(); QNetworkRequest req(url); @@ -46,7 +64,7 @@ void MusicBrainzClient::start(int id, const QString& mbid) { // HTTP request headers must be latin1. req.setRawHeader("User-Agent", mixxxMusicBrainzId.toLatin1()); QNetworkReply* reply = m_network.get(req); - connect(reply, SIGNAL(finished()), SLOT(requestFinished())); + connect(reply, &QNetworkReply::finished, this, &MusicBrainzClient::requestFinished); m_requests[reply] = id; m_timeouts.addReply(reply); @@ -67,16 +85,6 @@ void MusicBrainzClient::cancelAll() { } } -namespace { -QString decodeText(const QByteArray& data, const QStringRef codecName) { - QTextStream textStream(data); - if (!codecName.isEmpty()) { - textStream.setCodec(QTextCodec::codecForName(codecName.toUtf8())); - } - return textStream.readAll(); -} -} // anonymous namespace - void MusicBrainzClient::requestFinished() { QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender()); if (!reply) @@ -90,21 +98,27 @@ void MusicBrainzClient::requestFinished() { ResultList ret; int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - qDebug() << "MusicBrainzClient GET reply status:" << status; + QTextStream textReader(reply); + const QByteArray body(reply->readAll()); + QXmlStreamReader reader(body); // MusicBrainz returns 404 when the MBID is not in their database. We treat // a status of 404 the same as a 200 but it will produce an empty list of // results. if (status != 200 && status != 404) { + qDebug() << "MusicBrainzClient POST reply status:" << status << "body:" << body; + QJsonDocument jsonResponse = QJsonDocument::fromJson(body); + QJsonObject jsonObject = jsonResponse.object(); + QString message = jsonObject["error"].toString(); + QStringList propertyNames; + QStringList propertyKeys; + QString strReply = (QString)reply->readAll(); emit(networkError( reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), - "MusicBrainz")); + "MusicBrainz", message, kDefaultErrorCode)); return; } - const QByteArray body(reply->readAll()); - - QXmlStreamReader reader(body); QStringRef codecName; while (!reader.atEnd()) { switch (reader.readNext()) { @@ -206,7 +220,7 @@ MusicBrainzClient::Release MusicBrainzClient::parseRelease(QXmlStreamReader& rea if (name == "title") { ret.m_album = reader.readElementText(); } else if (name == "date") { - QRegExp regex(m_DateRegex); + QRegExp regex(kDateRegex); if (regex.indexIn(reader.readElementText()) == 0) { ret.m_year = regex.cap(0).toInt(); } diff --git a/src/musicbrainz/musicbrainzclient.h b/src/musicbrainz/musicbrainzclient.h index 014f5ba0f5..45552da111 100644 --- a/src/musicbrainz/musicbrainzclient.h +++ b/src/musicbrainz/musicbrainzclient.h @@ -82,7 +82,7 @@ class MusicBrainzClient : public QObject { signals: // Finished signal emitted when fechting songs tags void finished(int id, const MusicBrainzClient::ResultList& result); - void networkError(int, QString); + void networkError(int httpStatus, QString app, QString message, int code); private slots: void requestFinished(); @@ -110,10 +110,6 @@ class MusicBrainzClient : public QObject { static ResultList uniqueResults(const ResultList& results); private: - static const QString m_TrackUrl; - static const QString m_DateRegex; - static const int m_DefaultTimeout; - QNetworkAccessManager m_network; NetworkTimeouts m_timeouts; QMap<QNetworkReply*, int> m_requests; diff --git a/src/musicbrainz/network.cpp b/src/musicbrainz/network.cpp index e1e12dc1bb..ff198b94a8 100644 --- a/src/musicbrainz/network.cpp +++ b/src/musicbrainz/network.cpp @@ -53,8 +53,8 @@ void NetworkTimeouts::addReply(QNetworkReply* reply) { if (m_timers.contains(reply)) return; - connect(reply, SIGNAL(destroyed()), SLOT(replyFinished())); - connect(reply, SIGNAL(finished()), SLOT(replyFinished())); + connect(reply, &QNetworkReply::destroyed, this, &NetworkTimeouts::replyFinished); + connect(reply, &QNetworkReply::finished, this, &NetworkTimeouts::replyFinished); m_timers[reply] = startTimer(m_timeout_msec); } diff --git a/src/musicbrainz/tagfetcher.cpp b/src/musicbrainz/tagfetcher.cpp index 9a7320f158..43fa4b52e9 100644 --- a/src/musicbrainz/tagfetcher.cpp +++ b/src/musicbrainz/tagfetcher.cpp @@ -23,14 +23,14 @@ TagFetcher::TagFetcher(QObject* parent) m_pFingerprintWatcher(NULL), m_AcoustidClient(this), m_MusicbrainzClient(this) { - connect(&m_AcoustidClient, SIGNAL(finished(int,QString)), - this, SLOT(mbidFound(int,QString))); - connect(&m_MusicbrainzClient, SIGNAL(finished(int,MusicBrainzClient::ResultList)), - this, SLOT(tagsFetched(int,MusicBrainzClient::ResultList))); - connect(&m_AcoustidClient, SIGNAL(networkError(int, QString)), - this, SIGNAL(networkError(int, QString))); - connect(&m_MusicbrainzClient, SIGNAL(networkError(int, QString)), - this, SIGNAL(networkError(int, QString))); + connect(&m_AcoustidClient, &AcoustidClient::finished, + this, &TagFetcher::mbidFound); + connect(&m_MusicbrainzClient, &MusicBrainzClient::finished, + this, &TagFetcher::tagsFetched); + connect(&m_AcoustidClient, &AcoustidClient::networkError, + this, &TagFetcher::networkError); + connect(&m_MusicbrainzClient, &MusicBrainzClient::networkError, + this, &TagFetcher::networkError); } QString TagFetcher::getFingerprint(const TrackPointer tio) { @@ -47,12 +47,10 @@ void TagFetcher::startFetch(const TrackPointer track) { QFuture<QString> future = QtConcurrent::mapped(m_tracks, getFingerprint); m_pFingerprintWatcher = new QFutureWatcher<QString>(this); m_pFingerprintWatcher->setFuture(future); - connect(m_pFingerprintWatcher, SIGNAL(resultReadyAt(int)), - SLOT(fingerprintFound(int))); + connect(m_pFingerprintWatcher, &QFutureWatcher<QString>::resultReadyAt, + this, &TagFetcher::fingerprintFound); - foreach (const TrackPointer ptrack, m_tracks) { - emit(fetchProgress(tr("Fingerprinting track"))); - } + emit(fetchProgress(tr("Fingerprinting track"))); } void TagFetcher::cancel() { diff --git a/src/musicbrainz/tagfetcher.h b/src/musicbrainz/tagfetcher.h index b361cb3738..0afe4e27fb 100644 --- a/src/musicbrainz/tagfetcher.h +++ b/src/musicbrainz/tagfetcher.h @@ -36,7 +36,7 @@ class TagFetcher : public QObject { void resultAvailable(const TrackPointer originalTrack, const QList<TrackPointer>& tracksGuessed); void fetchProgress(QString); - void networkError(int,QString); + void networkError(int httpStatus, QString app, QString message, int code); private slots: void fingerprintFound(int index); |