Disable automatic conversions from 8-bit strings
This commit is contained in:
@@ -55,7 +55,7 @@ class AudioScrobbler : public QObject {
|
||||
SharedPtr<ScrobblerService> ServiceByName(const QString &name);
|
||||
template<typename T>
|
||||
SharedPtr<T> Service() {
|
||||
return std::static_pointer_cast<T>(ServiceByName(T::kName));
|
||||
return std::static_pointer_cast<T>(ServiceByName(QLatin1String(T::kName)));
|
||||
}
|
||||
|
||||
void ReloadSettings();
|
||||
|
||||
@@ -41,13 +41,16 @@
|
||||
#include "core/logging.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
#include "lastfmimport.h"
|
||||
|
||||
#include "scrobblingapi20.h"
|
||||
#include "lastfmscrobbler.h"
|
||||
|
||||
const int LastFMImport::kRequestsDelay = 2000;
|
||||
namespace {
|
||||
constexpr int kRequestsDelay = 2000;
|
||||
}
|
||||
|
||||
LastFMImport::LastFMImport(SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: QObject(parent),
|
||||
@@ -94,7 +97,7 @@ void LastFMImport::AbortAll() {
|
||||
|
||||
void LastFMImport::ReloadSettings() {
|
||||
|
||||
QSettings s;
|
||||
Settings s;
|
||||
s.beginGroup(LastFMScrobbler::kSettingsGroup);
|
||||
username_ = s.value("username").toString();
|
||||
s.endGroup();
|
||||
@@ -104,24 +107,24 @@ void LastFMImport::ReloadSettings() {
|
||||
QNetworkReply *LastFMImport::CreateRequest(const ParamList &request_params) {
|
||||
|
||||
ParamList params = ParamList()
|
||||
<< Param("api_key", ScrobblingAPI20::kApiKey)
|
||||
<< Param("user", username_)
|
||||
<< Param("lang", QLocale().name().left(2).toLower())
|
||||
<< Param("format", "json")
|
||||
<< Param(QStringLiteral("api_key"), QLatin1String(ScrobblingAPI20::kApiKey))
|
||||
<< Param(QStringLiteral("user"), username_)
|
||||
<< Param(QStringLiteral("lang"), QLocale().name().left(2).toLower())
|
||||
<< Param(QStringLiteral("format"), QStringLiteral("json"))
|
||||
<< request_params;
|
||||
|
||||
std::sort(params.begin(), params.end());
|
||||
|
||||
QUrlQuery url_query;
|
||||
for (const Param ¶m : params) {
|
||||
url_query.addQueryItem(QUrl::toPercentEncoding(param.first), QUrl::toPercentEncoding(param.second));
|
||||
url_query.addQueryItem(QString::fromLatin1(QUrl::toPercentEncoding(param.first)), QString::fromLatin1(QUrl::toPercentEncoding(param.second)));
|
||||
}
|
||||
|
||||
QUrl url(LastFMScrobbler::kApiUrl);
|
||||
QUrl url(QString::fromLatin1(LastFMScrobbler::kApiUrl));
|
||||
url.setQuery(url_query);
|
||||
QNetworkRequest req(url);
|
||||
req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded"));
|
||||
|
||||
QNetworkReply *reply = network_->get(req);
|
||||
replies_ << reply;
|
||||
@@ -251,15 +254,15 @@ void LastFMImport::AddGetRecentTracksRequest(const int page) {
|
||||
|
||||
void LastFMImport::SendGetRecentTracksRequest(GetRecentTracksRequest request) {
|
||||
|
||||
ParamList params = ParamList() << Param("method", "user.getRecentTracks");
|
||||
ParamList params = ParamList() << Param(QStringLiteral("method"), QStringLiteral("user.getRecentTracks"));
|
||||
|
||||
if (request.page == 0) {
|
||||
params << Param("page", "1");
|
||||
params << Param("limit", "1");
|
||||
params << Param(QStringLiteral("page"), QStringLiteral("1"));
|
||||
params << Param(QStringLiteral("limit"), QStringLiteral("1"));
|
||||
}
|
||||
else {
|
||||
params << Param("page", QString::number(request.page));
|
||||
params << Param("limit", "500");
|
||||
params << Param(QStringLiteral("page"), QString::number(request.page));
|
||||
params << Param(QStringLiteral("limit"), QStringLiteral("500"));
|
||||
}
|
||||
|
||||
QNetworkReply *reply = CreateRequest(params);
|
||||
@@ -414,15 +417,15 @@ void LastFMImport::AddGetTopTracksRequest(const int page) {
|
||||
|
||||
void LastFMImport::SendGetTopTracksRequest(GetTopTracksRequest request) {
|
||||
|
||||
ParamList params = ParamList() << Param("method", "user.getTopTracks");
|
||||
ParamList params = ParamList() << Param(QStringLiteral("method"), QStringLiteral("user.getTopTracks"));
|
||||
|
||||
if (request.page == 0) {
|
||||
params << Param("page", "1");
|
||||
params << Param("limit", "1");
|
||||
params << Param(QStringLiteral("page"), QStringLiteral("1"));
|
||||
params << Param(QStringLiteral("limit"), QStringLiteral("1"));
|
||||
}
|
||||
else {
|
||||
params << Param("page", QString::number(request.page));
|
||||
params << Param("limit", "500");
|
||||
params << Param(QStringLiteral("page"), QString::number(request.page));
|
||||
params << Param(QStringLiteral("limit"), QStringLiteral("500"));
|
||||
}
|
||||
|
||||
QNetworkReply *reply = CreateRequest(params);
|
||||
|
||||
@@ -94,8 +94,6 @@ class LastFMImport : public QObject {
|
||||
void GetTopTracksRequestFinished(QNetworkReply *reply, const int page);
|
||||
|
||||
private:
|
||||
static const int kRequestsDelay;
|
||||
|
||||
SharedPtr<NetworkAccessManager> network_;
|
||||
QTimer *timer_flush_requests_;
|
||||
|
||||
|
||||
@@ -29,9 +29,12 @@
|
||||
|
||||
const char *LastFMScrobbler::kName = "Last.fm";
|
||||
const char *LastFMScrobbler::kSettingsGroup = "LastFM";
|
||||
const char *LastFMScrobbler::kAuthUrl = "https://www.last.fm/api/auth/";
|
||||
const char *LastFMScrobbler::kApiUrl = "https://ws.audioscrobbler.com/2.0/";
|
||||
const char *LastFMScrobbler::kCacheFile = "lastfmscrobbler.cache";
|
||||
|
||||
namespace {
|
||||
constexpr char kAuthUrl[] = "https://www.last.fm/api/auth/";
|
||||
constexpr char kCacheFile[] = "lastfmscrobbler.cache";
|
||||
} // namespace
|
||||
|
||||
LastFMScrobbler::LastFMScrobbler(SharedPtr<ScrobblerSettings> settings, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: ScrobblingAPI20(kName, kSettingsGroup, kAuthUrl, kApiUrl, true, kCacheFile, settings, network, parent) {}
|
||||
: ScrobblingAPI20(QLatin1String(kName), QLatin1String(kSettingsGroup), QLatin1String(kAuthUrl), QLatin1String(kApiUrl), true, QLatin1String(kCacheFile), settings, network, parent) {}
|
||||
|
||||
@@ -40,10 +40,6 @@ class LastFMScrobbler : public ScrobblingAPI20 {
|
||||
static const char *kName;
|
||||
static const char *kSettingsGroup;
|
||||
static const char *kApiUrl;
|
||||
|
||||
private:
|
||||
static const char *kAuthUrl;
|
||||
static const char *kCacheFile;
|
||||
};
|
||||
|
||||
#endif // LASTFMSCROBBLER_H
|
||||
|
||||
@@ -35,4 +35,4 @@ const char *LibreFMScrobbler::kApiUrl = "https://libre.fm/2.0/";
|
||||
const char *LibreFMScrobbler::kCacheFile = "librefmscrobbler.cache";
|
||||
|
||||
LibreFMScrobbler::LibreFMScrobbler(SharedPtr<ScrobblerSettings> settings, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: ScrobblingAPI20(kName, kSettingsGroup, kAuthUrl, kApiUrl, false, kCacheFile, settings, network, parent) {}
|
||||
: ScrobblingAPI20(QLatin1String(kName), QLatin1String(kSettingsGroup), QLatin1String(kAuthUrl), QLatin1String(kApiUrl), false, QLatin1String(kCacheFile), settings, network, parent) {}
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "core/song.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/settings.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "internet/localredirectserver.h"
|
||||
#include "settings/scrobblersettingspage.h"
|
||||
@@ -57,19 +58,22 @@
|
||||
|
||||
const char *ListenBrainzScrobbler::kName = "ListenBrainz";
|
||||
const char *ListenBrainzScrobbler::kSettingsGroup = "ListenBrainz";
|
||||
const char *ListenBrainzScrobbler::kOAuthAuthorizeUrl = "https://musicbrainz.org/oauth2/authorize";
|
||||
const char *ListenBrainzScrobbler::kOAuthAccessTokenUrl = "https://musicbrainz.org/oauth2/token";
|
||||
const char *ListenBrainzScrobbler::kOAuthRedirectUrl = "http://localhost";
|
||||
const char *ListenBrainzScrobbler::kApiUrl = "https://api.listenbrainz.org";
|
||||
const char *ListenBrainzScrobbler::kClientIDB64 = "b2VBVU53cVNRZXIwZXIwOUZpcWkwUQ==";
|
||||
const char *ListenBrainzScrobbler::kClientSecretB64 = "Uk9GZ2hrZVEzRjNvUHlFaHFpeVdQQQ==";
|
||||
const char *ListenBrainzScrobbler::kCacheFile = "listenbrainzscrobbler.cache";
|
||||
const int ListenBrainzScrobbler::kScrobblesPerRequest = 10;
|
||||
|
||||
namespace {
|
||||
constexpr char kOAuthAuthorizeUrl[] = "https://musicbrainz.org/oauth2/authorize";
|
||||
constexpr char kOAuthAccessTokenUrl[] = "https://musicbrainz.org/oauth2/token";
|
||||
constexpr char kOAuthRedirectUrl[] = "http://localhost";
|
||||
constexpr char kApiUrl[] = "https://api.listenbrainz.org";
|
||||
constexpr char kClientIDB64[] = "b2VBVU53cVNRZXIwZXIwOUZpcWkwUQ==";
|
||||
constexpr char kClientSecretB64[] = "Uk9GZ2hrZVEzRjNvUHlFaHFpeVdQQQ==";
|
||||
constexpr char kCacheFile[] = "listenbrainzscrobbler.cache";
|
||||
constexpr int kScrobblesPerRequest = 10;
|
||||
} // namespace
|
||||
|
||||
ListenBrainzScrobbler::ListenBrainzScrobbler(SharedPtr<ScrobblerSettings> settings, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: ScrobblerService(kName, settings, parent),
|
||||
: ScrobblerService(QLatin1String(kName), settings, parent),
|
||||
network_(network),
|
||||
cache_(new ScrobblerCache(kCacheFile, this)),
|
||||
cache_(new ScrobblerCache(QLatin1String(kCacheFile), this)),
|
||||
server_(nullptr),
|
||||
enabled_(false),
|
||||
expires_in_(-1),
|
||||
@@ -110,7 +114,7 @@ ListenBrainzScrobbler::~ListenBrainzScrobbler() {
|
||||
|
||||
void ListenBrainzScrobbler::ReloadSettings() {
|
||||
|
||||
QSettings s;
|
||||
Settings s;
|
||||
s.beginGroup(kSettingsGroup);
|
||||
enabled_ = s.value("enabled", false).toBool();
|
||||
user_token_ = s.value("user_token").toString();
|
||||
@@ -124,7 +128,7 @@ void ListenBrainzScrobbler::ReloadSettings() {
|
||||
|
||||
void ListenBrainzScrobbler::LoadSession() {
|
||||
|
||||
QSettings s;
|
||||
Settings s;
|
||||
s.beginGroup(kSettingsGroup);
|
||||
access_token_ = s.value("access_token").toString();
|
||||
expires_in_ = s.value("expires_in", -1).toInt();
|
||||
@@ -150,13 +154,13 @@ void ListenBrainzScrobbler::Logout() {
|
||||
expires_in_ = -1;
|
||||
login_time_ = 0;
|
||||
|
||||
QSettings settings;
|
||||
settings.beginGroup(kSettingsGroup);
|
||||
settings.remove("access_token");
|
||||
settings.remove("expires_in");
|
||||
settings.remove("token_type");
|
||||
settings.remove("refresh_token");
|
||||
settings.endGroup();
|
||||
Settings s;
|
||||
s.beginGroup(kSettingsGroup);
|
||||
s.remove("access_token");
|
||||
s.remove("expires_in");
|
||||
s.remove("token_type");
|
||||
s.remove("refresh_token");
|
||||
s.endGroup();
|
||||
|
||||
}
|
||||
|
||||
@@ -173,15 +177,15 @@ void ListenBrainzScrobbler::Authenticate() {
|
||||
QObject::connect(server_, &LocalRedirectServer::Finished, this, &ListenBrainzScrobbler::RedirectArrived);
|
||||
}
|
||||
|
||||
QUrl redirect_url(kOAuthRedirectUrl);
|
||||
QUrl redirect_url(QString::fromLatin1(kOAuthRedirectUrl));
|
||||
redirect_url.setPort(server_->url().port());
|
||||
|
||||
QUrlQuery url_query;
|
||||
url_query.addQueryItem(QStringLiteral("response_type"), QStringLiteral("code"));
|
||||
url_query.addQueryItem(QStringLiteral("client_id"), QByteArray::fromBase64(kClientIDB64));
|
||||
url_query.addQueryItem(QStringLiteral("client_id"), QString::fromLatin1(QByteArray::fromBase64(kClientIDB64)));
|
||||
url_query.addQueryItem(QStringLiteral("redirect_uri"), redirect_url.toString());
|
||||
url_query.addQueryItem(QStringLiteral("scope"), QStringLiteral("profile;email;tag;rating;collection;submit_isrc;submit_barcode"));
|
||||
QUrl url(kOAuthAuthorizeUrl);
|
||||
QUrl url(QString::fromLatin1(kOAuthAuthorizeUrl));
|
||||
url.setQuery(url_query);
|
||||
|
||||
bool result = QDesktopServices::openUrl(url);
|
||||
@@ -268,17 +272,17 @@ void ListenBrainzScrobbler::RequestAccessToken(const QUrl &redirect_url, const Q
|
||||
|
||||
refresh_login_timer_.stop();
|
||||
|
||||
ParamList params = ParamList() << Param("client_id", QByteArray::fromBase64(kClientIDB64))
|
||||
<< Param("client_secret", QByteArray::fromBase64(kClientSecretB64));
|
||||
ParamList params = ParamList() << Param(QStringLiteral("client_id"), QString::fromLatin1(QByteArray::fromBase64(kClientIDB64)))
|
||||
<< Param(QStringLiteral("client_secret"), QString::fromLatin1(QByteArray::fromBase64(kClientSecretB64)));
|
||||
|
||||
if (!code.isEmpty() && !redirect_url.isEmpty()) {
|
||||
params << Param("grant_type", "authorization_code");
|
||||
params << Param("code", code);
|
||||
params << Param("redirect_uri", redirect_url.toString());
|
||||
params << Param(QStringLiteral("grant_type"), QStringLiteral("authorization_code"));
|
||||
params << Param(QStringLiteral("code"), code);
|
||||
params << Param(QStringLiteral("redirect_uri"), redirect_url.toString());
|
||||
}
|
||||
else if (!refresh_token_.isEmpty() && enabled_) {
|
||||
params << Param("grant_type", "refresh_token");
|
||||
params << Param("refresh_token", refresh_token_);
|
||||
params << Param(QStringLiteral("grant_type"), QStringLiteral("refresh_token"));
|
||||
params << Param(QStringLiteral("refresh_token"), refresh_token_);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
@@ -286,14 +290,14 @@ void ListenBrainzScrobbler::RequestAccessToken(const QUrl &redirect_url, const Q
|
||||
|
||||
QUrlQuery url_query;
|
||||
for (const Param ¶m : params) {
|
||||
url_query.addQueryItem(QUrl::toPercentEncoding(param.first), QUrl::toPercentEncoding(param.second));
|
||||
url_query.addQueryItem(QString::fromLatin1(QUrl::toPercentEncoding(param.first)), QString::fromLatin1(QUrl::toPercentEncoding(param.second)));
|
||||
}
|
||||
|
||||
QUrl session_url(kOAuthAccessTokenUrl);
|
||||
QUrl session_url(QString::fromLatin1(kOAuthAccessTokenUrl));
|
||||
|
||||
QNetworkRequest req(session_url);
|
||||
req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded"));
|
||||
QByteArray query = url_query.toString(QUrl::FullyEncoded).toUtf8();
|
||||
QNetworkReply *reply = network_->post(req, query);
|
||||
replies_ << reply;
|
||||
@@ -328,7 +332,7 @@ void ListenBrainzScrobbler::AuthenticateReplyFinished(QNetworkReply *reply) {
|
||||
}
|
||||
login_time_ = QDateTime::currentDateTime().toSecsSinceEpoch();
|
||||
|
||||
QSettings s;
|
||||
Settings s;
|
||||
s.beginGroup(kSettingsGroup);
|
||||
s.setValue("access_token", access_token_);
|
||||
s.setValue("expires_in", expires_in_);
|
||||
@@ -354,7 +358,7 @@ QNetworkReply *ListenBrainzScrobbler::CreateRequest(const QUrl &url, const QJson
|
||||
|
||||
QNetworkRequest req(url);
|
||||
req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
|
||||
req.setRawHeader("Authorization", QStringLiteral("Token %1").arg(user_token_).toUtf8());
|
||||
QNetworkReply *reply = network_->post(req, json_doc.toJson());
|
||||
replies_ << reply;
|
||||
@@ -398,13 +402,13 @@ QJsonObject ListenBrainzScrobbler::JsonTrackMetadata(const ScrobbleMetadata &met
|
||||
|
||||
QStringList artist_mbids_list;
|
||||
if (!metadata.musicbrainz_album_artist_id.isEmpty()) {
|
||||
artist_mbids_list << metadata.musicbrainz_album_artist_id.split('/');
|
||||
artist_mbids_list << metadata.musicbrainz_album_artist_id.split(QLatin1Char('/'));
|
||||
}
|
||||
if (!metadata.musicbrainz_artist_id.isEmpty()) {
|
||||
artist_mbids_list << metadata.musicbrainz_artist_id.split('/');
|
||||
artist_mbids_list << metadata.musicbrainz_artist_id.split(QLatin1Char('/'));
|
||||
}
|
||||
if (!metadata.musicbrainz_original_artist_id.isEmpty()) {
|
||||
artist_mbids_list << metadata.musicbrainz_original_artist_id.split('/');
|
||||
artist_mbids_list << metadata.musicbrainz_original_artist_id.split(QLatin1Char('/'));
|
||||
}
|
||||
if (!artist_mbids_list.isEmpty()) {
|
||||
QJsonArray artist_mbids_array;
|
||||
@@ -456,11 +460,11 @@ void ListenBrainzScrobbler::UpdateNowPlaying(const Song &song) {
|
||||
QJsonArray array_payload;
|
||||
array_payload.append(object_listen);
|
||||
QJsonObject object;
|
||||
object.insert(QStringLiteral("listen_type"), "playing_now");
|
||||
object.insert(QStringLiteral("listen_type"), QStringLiteral("playing_now"));
|
||||
object.insert(QStringLiteral("payload"), array_payload);
|
||||
QJsonDocument doc(object);
|
||||
|
||||
QUrl url(QStringLiteral("%1/1/submit-listens").arg(kApiUrl));
|
||||
QUrl url(QStringLiteral("%1/1/submit-listens").arg(QLatin1String(kApiUrl)));
|
||||
QNetworkReply *reply = CreateRequest(url, doc);
|
||||
QObject::connect(reply, &QNetworkReply::finished, this, [this, reply]() { UpdateNowPlayingRequestFinished(reply); });
|
||||
|
||||
@@ -559,11 +563,11 @@ void ListenBrainzScrobbler::Submit() {
|
||||
submitted_ = true;
|
||||
|
||||
QJsonObject object;
|
||||
object.insert(QStringLiteral("listen_type"), "import");
|
||||
object.insert(QStringLiteral("listen_type"), QStringLiteral("import"));
|
||||
object.insert(QStringLiteral("payload"), array);
|
||||
QJsonDocument doc(object);
|
||||
|
||||
QUrl url(QStringLiteral("%1/1/submit-listens").arg(kApiUrl));
|
||||
QUrl url(QStringLiteral("%1/1/submit-listens").arg(QLatin1String(kApiUrl)));
|
||||
QNetworkReply *reply = CreateRequest(url, doc);
|
||||
QObject::connect(reply, &QNetworkReply::finished, this, [this, reply, cache_items_sent]() { ScrobbleRequestFinished(reply, cache_items_sent); });
|
||||
|
||||
@@ -633,7 +637,7 @@ void ListenBrainzScrobbler::Love() {
|
||||
object.insert(QStringLiteral("recording_mbid"), song_playing_.musicbrainz_recording_id());
|
||||
object.insert(QStringLiteral("score"), 1);
|
||||
|
||||
QUrl url(QStringLiteral("%1/1/feedback/recording-feedback").arg(kApiUrl));
|
||||
QUrl url(QStringLiteral("%1/1/feedback/recording-feedback").arg(QLatin1String(kApiUrl)));
|
||||
QNetworkReply *reply = CreateRequest(url, QJsonDocument(object));
|
||||
QObject::connect(reply, &QNetworkReply::finished, this, [this, reply]() { LoveRequestFinished(reply); });
|
||||
|
||||
|
||||
@@ -101,15 +101,6 @@ class ListenBrainzScrobbler : public ScrobblerService {
|
||||
void StartSubmit(const bool initial = false) override;
|
||||
void CheckScrobblePrevSong();
|
||||
|
||||
static const char *kOAuthAuthorizeUrl;
|
||||
static const char *kOAuthAccessTokenUrl;
|
||||
static const char *kOAuthRedirectUrl;
|
||||
static const char *kApiUrl;
|
||||
static const char *kClientIDB64;
|
||||
static const char *kClientSecretB64;
|
||||
static const char *kCacheFile;
|
||||
static const int kScrobblesPerRequest;
|
||||
|
||||
SharedPtr<NetworkAccessManager> network_;
|
||||
ScrobblerCache *cache_;
|
||||
LocalRedirectServer *server_;
|
||||
|
||||
@@ -47,7 +47,7 @@ using namespace std::chrono_literals;
|
||||
ScrobblerCache::ScrobblerCache(const QString &filename, QObject *parent)
|
||||
: QObject(parent),
|
||||
timer_flush_(new QTimer(this)),
|
||||
filename_(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/" + filename),
|
||||
filename_(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1Char('/') + filename),
|
||||
loaded_(false) {
|
||||
|
||||
ReadCache();
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/song.h"
|
||||
#include "core/settings.h"
|
||||
#include "settings/settingsdialog.h"
|
||||
#include "settings/scrobblersettingspage.h"
|
||||
#include "scrobblersettings.h"
|
||||
@@ -47,7 +48,7 @@ ScrobblerSettings::ScrobblerSettings(Application *app, QObject *parent)
|
||||
|
||||
void ScrobblerSettings::ReloadSettings() {
|
||||
|
||||
QSettings s;
|
||||
Settings s;
|
||||
s.beginGroup(ScrobblerSettingsPage::kSettingsGroup);
|
||||
enabled_ = s.value("enabled", false).toBool();
|
||||
offline_ = s.value("offline", false).toBool();
|
||||
@@ -92,7 +93,7 @@ void ScrobblerSettings::ToggleScrobbling() {
|
||||
bool enabled_old_ = enabled_;
|
||||
enabled_ = !enabled_;
|
||||
|
||||
QSettings s;
|
||||
Settings s;
|
||||
s.beginGroup(ScrobblerSettingsPage::kSettingsGroup);
|
||||
s.setValue("enabled", enabled_);
|
||||
s.endGroup();
|
||||
@@ -106,7 +107,7 @@ void ScrobblerSettings::ToggleOffline() {
|
||||
bool offline_old_ = offline_;
|
||||
offline_ = !offline_;
|
||||
|
||||
QSettings s;
|
||||
Settings s;
|
||||
s.beginGroup(ScrobblerSettingsPage::kSettingsGroup);
|
||||
s.setValue("offline", offline_);
|
||||
s.endGroup();
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "core/networkaccessmanager.h"
|
||||
#include "core/song.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/settings.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "internet/localredirectserver.h"
|
||||
#include "settings/scrobblersettingspage.h"
|
||||
@@ -60,8 +61,11 @@
|
||||
#include "scrobblemetadata.h"
|
||||
|
||||
const char *ScrobblingAPI20::kApiKey = "211990b4c96782c05d1536e7219eb56e";
|
||||
const char *ScrobblingAPI20::kSecret = "80fd738f49596e9709b1bf9319c444a8";
|
||||
const int ScrobblingAPI20::kScrobblesPerRequest = 50;
|
||||
|
||||
namespace {
|
||||
constexpr char kSecret[] = "80fd738f49596e9709b1bf9319c444a8";
|
||||
constexpr int kScrobblesPerRequest = 50;
|
||||
}
|
||||
|
||||
ScrobblingAPI20::ScrobblingAPI20(const QString &name, const QString &settings_group, const QString &auth_url, const QString &api_url, const bool batch, const QString &cache_file, SharedPtr<ScrobblerSettings> settings, SharedPtr<NetworkAccessManager> network, QObject *parent)
|
||||
: ScrobblerService(name, settings, parent),
|
||||
@@ -108,7 +112,7 @@ ScrobblingAPI20::~ScrobblingAPI20() {
|
||||
|
||||
void ScrobblingAPI20::ReloadSettings() {
|
||||
|
||||
QSettings s;
|
||||
Settings s;
|
||||
|
||||
s.beginGroup(settings_group_);
|
||||
enabled_ = s.value("enabled", false).toBool();
|
||||
@@ -122,7 +126,7 @@ void ScrobblingAPI20::ReloadSettings() {
|
||||
|
||||
void ScrobblingAPI20::LoadSession() {
|
||||
|
||||
QSettings s;
|
||||
Settings s;
|
||||
s.beginGroup(settings_group_);
|
||||
subscriber_ = s.value("subscriber", false).toBool();
|
||||
username_ = s.value("username").toString();
|
||||
@@ -137,7 +141,7 @@ void ScrobblingAPI20::Logout() {
|
||||
username_.clear();
|
||||
session_key_.clear();
|
||||
|
||||
QSettings settings;
|
||||
Settings settings;
|
||||
settings.beginGroup(settings_group_);
|
||||
settings.remove("subscriber");
|
||||
settings.remove("username");
|
||||
@@ -202,7 +206,7 @@ void ScrobblingAPI20::Authenticate() {
|
||||
}
|
||||
|
||||
QUrlQuery url_query;
|
||||
url_query.addQueryItem(QStringLiteral("api_key"), kApiKey);
|
||||
url_query.addQueryItem(QStringLiteral("api_key"), QLatin1String(kApiKey));
|
||||
url_query.addQueryItem(QStringLiteral("cb"), server_->url().toString());
|
||||
QUrl url(auth_url_);
|
||||
url.setQuery(url_query);
|
||||
@@ -211,7 +215,7 @@ void ScrobblingAPI20::Authenticate() {
|
||||
messagebox.setTextFormat(Qt::RichText);
|
||||
int result = messagebox.exec();
|
||||
switch (result) {
|
||||
case QMessageBox::Open: {
|
||||
case QMessageBox::Open:{
|
||||
bool openurl_result = QDesktopServices::openUrl(url);
|
||||
if (openurl_result) {
|
||||
break;
|
||||
@@ -246,7 +250,7 @@ void ScrobblingAPI20::RedirectArrived() {
|
||||
if (url.isValid()) {
|
||||
QUrlQuery url_query(url);
|
||||
if (url_query.hasQueryItem(QStringLiteral("token"))) {
|
||||
QString token = url_query.queryItemValue(QStringLiteral("token")).toUtf8();
|
||||
QString token = url_query.queryItemValue(QStringLiteral("token"));
|
||||
RequestSession(token);
|
||||
}
|
||||
else {
|
||||
@@ -271,18 +275,18 @@ void ScrobblingAPI20::RequestSession(const QString &token) {
|
||||
|
||||
QUrl session_url(api_url_);
|
||||
QUrlQuery session_url_query;
|
||||
session_url_query.addQueryItem(QStringLiteral("api_key"), kApiKey);
|
||||
session_url_query.addQueryItem(QStringLiteral("api_key"), QLatin1String(kApiKey));
|
||||
session_url_query.addQueryItem(QStringLiteral("method"), QStringLiteral("auth.getSession"));
|
||||
session_url_query.addQueryItem(QStringLiteral("token"), token);
|
||||
QString data_to_sign;
|
||||
for (const Param ¶m : session_url_query.queryItems()) {
|
||||
data_to_sign += param.first + param.second;
|
||||
}
|
||||
data_to_sign += kSecret;
|
||||
data_to_sign += QLatin1String(kSecret);
|
||||
QByteArray const digest = QCryptographicHash::hash(data_to_sign.toUtf8(), QCryptographicHash::Md5);
|
||||
QString signature = QString::fromLatin1(digest.toHex()).rightJustified(32, '0').toLower();
|
||||
const QString signature = QString::fromLatin1(digest.toHex()).rightJustified(32, QLatin1Char('0')).toLower();
|
||||
session_url_query.addQueryItem(QStringLiteral("api_sig"), signature);
|
||||
session_url_query.addQueryItem(QUrl::toPercentEncoding(QStringLiteral("format")), QUrl::toPercentEncoding(QStringLiteral("json")));
|
||||
session_url_query.addQueryItem(QString::fromLatin1(QUrl::toPercentEncoding(QStringLiteral("format"))), QString::fromLatin1(QUrl::toPercentEncoding(QStringLiteral("json"))));
|
||||
session_url.setQuery(session_url_query);
|
||||
|
||||
QNetworkRequest req(session_url);
|
||||
@@ -331,7 +335,7 @@ void ScrobblingAPI20::AuthenticateReplyFinished(QNetworkReply *reply) {
|
||||
username_ = json_obj[QStringLiteral("name")].toString();
|
||||
session_key_ = json_obj[QStringLiteral("key")].toString();
|
||||
|
||||
QSettings s;
|
||||
Settings s;
|
||||
s.beginGroup(settings_group_);
|
||||
s.setValue("subscriber", subscriber_);
|
||||
s.setValue("username", username_);
|
||||
@@ -347,9 +351,9 @@ void ScrobblingAPI20::AuthenticateReplyFinished(QNetworkReply *reply) {
|
||||
QNetworkReply *ScrobblingAPI20::CreateRequest(const ParamList &request_params) {
|
||||
|
||||
ParamList params = ParamList()
|
||||
<< Param("api_key", kApiKey)
|
||||
<< Param("sk", session_key_)
|
||||
<< Param("lang", QLocale().name().left(2).toLower())
|
||||
<< Param(QStringLiteral("api_key"), QLatin1String(kApiKey))
|
||||
<< Param(QStringLiteral("sk"), session_key_)
|
||||
<< Param(QStringLiteral("lang"), QLocale().name().left(2).toLower())
|
||||
<< request_params;
|
||||
|
||||
std::sort(params.begin(), params.end());
|
||||
@@ -358,21 +362,21 @@ QNetworkReply *ScrobblingAPI20::CreateRequest(const ParamList &request_params) {
|
||||
QString data_to_sign;
|
||||
for (const Param ¶m : params) {
|
||||
EncodedParam encoded_param(QUrl::toPercentEncoding(param.first), QUrl::toPercentEncoding(param.second));
|
||||
url_query.addQueryItem(encoded_param.first, encoded_param.second);
|
||||
url_query.addQueryItem(QString::fromLatin1(encoded_param.first), QString::fromLatin1(encoded_param.second));
|
||||
data_to_sign += param.first + param.second;
|
||||
}
|
||||
data_to_sign += kSecret;
|
||||
data_to_sign += QLatin1String(kSecret);
|
||||
|
||||
QByteArray const digest = QCryptographicHash::hash(data_to_sign.toUtf8(), QCryptographicHash::Md5);
|
||||
QString signature = QString::fromLatin1(digest.toHex()).rightJustified(32, '0').toLower();
|
||||
const QString signature = QString::fromLatin1(digest.toHex()).rightJustified(32, QLatin1Char('0')).toLower();
|
||||
|
||||
url_query.addQueryItem(QStringLiteral("api_sig"), QUrl::toPercentEncoding(signature));
|
||||
url_query.addQueryItem(QStringLiteral("format"), QUrl::toPercentEncoding(QStringLiteral("json")));
|
||||
url_query.addQueryItem(QStringLiteral("api_sig"), QString::fromLatin1(QUrl::toPercentEncoding(signature)));
|
||||
url_query.addQueryItem(QStringLiteral("format"), QStringLiteral("json"));
|
||||
|
||||
QUrl url(api_url_);
|
||||
QNetworkRequest req(url);
|
||||
req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded"));
|
||||
QByteArray query = url_query.toString(QUrl::FullyEncoded).toUtf8();
|
||||
QNetworkReply *reply = network_->post(req, query);
|
||||
replies_ << reply;
|
||||
@@ -394,16 +398,16 @@ void ScrobblingAPI20::UpdateNowPlaying(const Song &song) {
|
||||
if (!authenticated() || !song.is_metadata_good() || settings_->offline()) return;
|
||||
|
||||
ParamList params = ParamList()
|
||||
<< Param("method", "track.updateNowPlaying")
|
||||
<< Param("artist", prefer_albumartist_ ? song.effective_albumartist() : song.artist())
|
||||
<< Param("track", StripTitle(song.title()));
|
||||
<< Param(QStringLiteral("method"), QStringLiteral("track.updateNowPlaying"))
|
||||
<< Param(QStringLiteral("artist"), prefer_albumartist_ ? song.effective_albumartist() : song.artist())
|
||||
<< Param(QStringLiteral("track"), StripTitle(song.title()));
|
||||
|
||||
if (!song.album().isEmpty()) {
|
||||
params << Param("album", StripAlbum(song.album()));
|
||||
params << Param(QStringLiteral("album"), StripAlbum(song.album()));
|
||||
}
|
||||
|
||||
if (!prefer_albumartist_ && !song.albumartist().isEmpty()) {
|
||||
params << Param("albumArtist", song.albumartist());
|
||||
params << Param(QStringLiteral("albumArtist"), song.albumartist());
|
||||
}
|
||||
|
||||
QNetworkReply *reply = CreateRequest(params);
|
||||
@@ -486,7 +490,7 @@ void ScrobblingAPI20::Submit() {
|
||||
|
||||
qLog(Debug) << name_ << "Submitting scrobbles.";
|
||||
|
||||
ParamList params = ParamList() << Param("method", "track.scrobble");
|
||||
ParamList params = ParamList() << Param(QStringLiteral("method"), QStringLiteral("track.scrobble"));
|
||||
|
||||
int i = 0;
|
||||
ScrobblerCacheItemPtrList all_cache_items = cache_->List();
|
||||
@@ -688,20 +692,20 @@ void ScrobblingAPI20::ScrobbleRequestFinished(QNetworkReply *reply, ScrobblerCac
|
||||
void ScrobblingAPI20::SendSingleScrobble(ScrobblerCacheItemPtr item) {
|
||||
|
||||
ParamList params = ParamList()
|
||||
<< Param("method", "track.scrobble")
|
||||
<< Param("artist", prefer_albumartist_ ? item->metadata.effective_albumartist() : item->metadata.artist)
|
||||
<< Param("track", StripTitle(item->metadata.title))
|
||||
<< Param("timestamp", QString::number(item->timestamp))
|
||||
<< Param("duration", QString::number(item->metadata.length_nanosec / kNsecPerSec));
|
||||
<< Param(QStringLiteral("method"), QStringLiteral("track.scrobble"))
|
||||
<< Param(QStringLiteral("artist"), prefer_albumartist_ ? item->metadata.effective_albumartist() : item->metadata.artist)
|
||||
<< Param(QStringLiteral("track"), StripTitle(item->metadata.title))
|
||||
<< Param(QStringLiteral("timestamp"), QString::number(item->timestamp))
|
||||
<< Param(QStringLiteral("duration"), QString::number(item->metadata.length_nanosec / kNsecPerSec));
|
||||
|
||||
if (!item->metadata.album.isEmpty()) {
|
||||
params << Param("album", StripAlbum(item->metadata.album));
|
||||
params << Param(QStringLiteral("album"), StripAlbum(item->metadata.album));
|
||||
}
|
||||
if (!prefer_albumartist_ && !item->metadata.albumartist.isEmpty()) {
|
||||
params << Param("albumArtist", item->metadata.albumartist);
|
||||
params << Param(QStringLiteral("albumArtist"), item->metadata.albumartist);
|
||||
}
|
||||
if (item->metadata.track > 0) {
|
||||
params << Param("trackNumber", QString::number(item->metadata.track));
|
||||
params << Param(QStringLiteral("trackNumber"), QString::number(item->metadata.track));
|
||||
}
|
||||
|
||||
QNetworkReply *reply = CreateRequest(params);
|
||||
@@ -825,16 +829,16 @@ void ScrobblingAPI20::Love() {
|
||||
qLog(Debug) << name_ << "Sending love for song" << song_playing_.artist() << song_playing_.album() << song_playing_.title();
|
||||
|
||||
ParamList params = ParamList()
|
||||
<< Param("method", "track.love")
|
||||
<< Param("artist", prefer_albumartist_ ? song_playing_.effective_albumartist() : song_playing_.artist())
|
||||
<< Param("track", song_playing_.title());
|
||||
<< Param(QStringLiteral("method"), QStringLiteral("track.love"))
|
||||
<< Param(QStringLiteral("artist"), prefer_albumartist_ ? song_playing_.effective_albumartist() : song_playing_.artist())
|
||||
<< Param(QStringLiteral("track"), song_playing_.title());
|
||||
|
||||
if (!song_playing_.album().isEmpty()) {
|
||||
params << Param("album", song_playing_.album());
|
||||
params << Param(QStringLiteral("album"), song_playing_.album());
|
||||
}
|
||||
|
||||
if (!prefer_albumartist_ && !song_playing_.albumartist().isEmpty()) {
|
||||
params << Param("albumArtist", song_playing_.albumartist());
|
||||
params << Param(QStringLiteral("albumArtist"), song_playing_.albumartist());
|
||||
}
|
||||
|
||||
QNetworkReply *reply = CreateRequest(params);
|
||||
|
||||
@@ -120,9 +120,6 @@ class ScrobblingAPI20 : public ScrobblerService {
|
||||
RateLimitExceeded = 29,
|
||||
};
|
||||
|
||||
static const char *kSecret;
|
||||
static const int kScrobblesPerRequest;
|
||||
|
||||
QNetworkReply *CreateRequest(const ParamList &request_params);
|
||||
ReplyResult GetJsonObject(QNetworkReply *reply, QJsonObject &json_obj, QString &error_description);
|
||||
|
||||
|
||||
@@ -40,10 +40,12 @@
|
||||
#include "scrobblerservice.h"
|
||||
#include "subsonicscrobbler.h"
|
||||
|
||||
const char *SubsonicScrobbler::kName = "Subsonic";
|
||||
namespace {
|
||||
constexpr char kName[] = "Subsonic";
|
||||
}
|
||||
|
||||
SubsonicScrobbler::SubsonicScrobbler(SharedPtr<ScrobblerSettings> settings, Application *app, QObject *parent)
|
||||
: ScrobblerService(kName, settings, parent),
|
||||
: ScrobblerService(QLatin1String(kName), settings, parent),
|
||||
app_(app),
|
||||
service_(nullptr),
|
||||
enabled_(false),
|
||||
@@ -58,7 +60,7 @@ SubsonicScrobbler::SubsonicScrobbler(SharedPtr<ScrobblerSettings> settings, Appl
|
||||
|
||||
void SubsonicScrobbler::ReloadSettings() {
|
||||
|
||||
QSettings s;
|
||||
Settings s;
|
||||
s.beginGroup(SubsonicSettingsPage::kSettingsGroup);
|
||||
enabled_ = s.value("serversidescrobbling", false).toBool();
|
||||
s.endGroup();
|
||||
|
||||
@@ -44,8 +44,6 @@ class SubsonicScrobbler : public ScrobblerService {
|
||||
public:
|
||||
explicit SubsonicScrobbler(SharedPtr<ScrobblerSettings> settings, Application *app, QObject *parent = nullptr);
|
||||
|
||||
static const char *kName;
|
||||
|
||||
void ReloadSettings() override;
|
||||
|
||||
bool enabled() const override { return enabled_; }
|
||||
|
||||
Reference in New Issue
Block a user