Refactor subsonic, tidal and qobuz code
This commit is contained in:
@@ -64,8 +64,7 @@ QUrl SubsonicBaseRequest::CreateUrl(const QString &ressource_name, const QList<P
|
||||
|
||||
QUrlQuery url_query;
|
||||
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(QUrl::toPercentEncoding(param.first), QUrl::toPercentEncoding(param.second));
|
||||
}
|
||||
|
||||
QUrl url(server_url());
|
||||
|
||||
@@ -45,14 +45,12 @@ class SubsonicBaseRequest : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SubsonicBaseRequest(SubsonicService *service, QObject *parent);
|
||||
explicit SubsonicBaseRequest(SubsonicService *service, QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
typedef QPair<QString, QString> Param;
|
||||
typedef QList<Param> ParamList;
|
||||
|
||||
typedef QPair<QByteArray, QByteArray> EncodedParam;
|
||||
typedef QList<EncodedParam> EncodedParamList;
|
||||
|
||||
QUrl CreateUrl(const QString &ressource_name, const QList<Param> ¶ms_provided) const;
|
||||
QNetworkReply *CreateGetRequest(const QString &ressource_name, const QList<Param> ¶ms_provided);
|
||||
QByteArray GetReplyData(QNetworkReply *reply);
|
||||
|
||||
@@ -456,12 +456,12 @@ void SubsonicRequest::AlbumSongsReplyReceived(QNetworkReply *reply, const QStrin
|
||||
songs << song;
|
||||
}
|
||||
|
||||
for (Song &song : songs) {
|
||||
for (Song song : songs) {
|
||||
if (compilation) song.set_compilation_detected(true);
|
||||
if (!multidisc) {
|
||||
song.set_disc(0);
|
||||
}
|
||||
songs_ << song;
|
||||
songs_.insert(song.song_id(), song);
|
||||
}
|
||||
|
||||
SongsFinishCheck();
|
||||
@@ -680,7 +680,7 @@ QString SubsonicRequest::ParseSong(Song &song, const QJsonObject &json_obj, cons
|
||||
|
||||
void SubsonicRequest::GetAlbumCovers() {
|
||||
|
||||
for (Song &song : songs_) {
|
||||
for (const Song &song : songs_) {
|
||||
if (!song.art_automatic().isEmpty()) AddAlbumCoverRequest(song);
|
||||
}
|
||||
FlushAlbumCoverRequests();
|
||||
@@ -692,15 +692,17 @@ void SubsonicRequest::GetAlbumCovers() {
|
||||
|
||||
}
|
||||
|
||||
void SubsonicRequest::AddAlbumCoverRequest(Song &song) {
|
||||
void SubsonicRequest::AddAlbumCoverRequest(const Song &song) {
|
||||
|
||||
QUrl cover_url(song.art_automatic());
|
||||
QUrlQuery cover_url_query(cover_url);
|
||||
|
||||
if (!cover_url.isValid()) return;
|
||||
if (!cover_url.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (album_covers_requests_sent_.contains(cover_url)) {
|
||||
album_covers_requests_sent_.insert(cover_url, &song);
|
||||
if (album_covers_requests_sent_.contains(song.art_automatic())) {
|
||||
album_covers_requests_sent_.insert(song.art_automatic(), song.song_id());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -714,7 +716,7 @@ void SubsonicRequest::AddAlbumCoverRequest(Song &song) {
|
||||
request.filename = cover_path + "/" + cover_url_query.queryItemValue("id") + ".jpg";
|
||||
if (request.filename.isEmpty()) return;
|
||||
|
||||
album_covers_requests_sent_.insert(cover_url, &song);
|
||||
album_covers_requests_sent_.insert(song.art_automatic(), song.song_id());
|
||||
++album_covers_requested_;
|
||||
|
||||
album_cover_requests_queue_.enqueue(request);
|
||||
@@ -820,8 +822,10 @@ void SubsonicRequest::AlbumCoverReceived(QNetworkReply *reply, const QUrl &url,
|
||||
if (image.loadFromData(data, format)) {
|
||||
if (image.save(filename, format)) {
|
||||
while (album_covers_requests_sent_.contains(url)) {
|
||||
Song *song = album_covers_requests_sent_.take(url);
|
||||
song->set_art_automatic(QUrl::fromLocalFile(filename));
|
||||
const QString song_id = album_covers_requests_sent_.take(url);
|
||||
if (songs_.contains(song_id)) {
|
||||
songs_[song_id].set_art_automatic(QUrl::fromLocalFile(filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -840,8 +844,9 @@ void SubsonicRequest::AlbumCoverReceived(QNetworkReply *reply, const QUrl &url,
|
||||
|
||||
void SubsonicRequest::AlbumCoverFinishCheck() {
|
||||
|
||||
if (!album_cover_requests_queue_.isEmpty() && album_covers_requests_active_ < kMaxConcurrentAlbumCoverRequests)
|
||||
if (!album_cover_requests_queue_.isEmpty() && album_covers_requests_active_ < kMaxConcurrentAlbumCoverRequests) {
|
||||
FlushAlbumCoverRequests();
|
||||
}
|
||||
|
||||
FinishCheck();
|
||||
|
||||
@@ -868,9 +873,9 @@ void SubsonicRequest::FinishCheck() {
|
||||
}
|
||||
else {
|
||||
if (songs_.isEmpty() && errors_.isEmpty())
|
||||
emit Results(songs_, tr("Unknown error"));
|
||||
emit Results(songs_.values(), tr("Unknown error"));
|
||||
else
|
||||
emit Results(songs_, ErrorsToHTML(errors_));
|
||||
emit Results(songs_.values(), ErrorsToHTML(errors_));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class SubsonicRequest : public SubsonicBaseRequest {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SubsonicRequest(SubsonicService *service, SubsonicUrlHandler *url_handler, Application *app, QObject *parent);
|
||||
explicit SubsonicRequest(SubsonicService *service, SubsonicUrlHandler *url_handler, Application *app, QObject *parent = nullptr);
|
||||
~SubsonicRequest() override;
|
||||
|
||||
void ReloadSettings();
|
||||
@@ -72,8 +72,6 @@ class SubsonicRequest : public SubsonicBaseRequest {
|
||||
void AlbumCoverReceived(QNetworkReply *reply, const QUrl &url, const QString &filename);
|
||||
|
||||
private:
|
||||
typedef QPair<QString, QString> Param;
|
||||
typedef QList<Param> ParamList;
|
||||
|
||||
struct Request {
|
||||
explicit Request() : offset(0), size(0) {}
|
||||
@@ -103,7 +101,7 @@ class SubsonicRequest : public SubsonicBaseRequest {
|
||||
QString ParseSong(Song &song, const QJsonObject &json_obj, const QString &artist_id_requested = QString(), const QString &album_id_requested = QString(), const QString &album_artist = QString(), const qint64 album_created = 0);
|
||||
|
||||
void GetAlbumCovers();
|
||||
void AddAlbumCoverRequest(Song &song);
|
||||
void AddAlbumCoverRequest(const Song &song);
|
||||
void FlushAlbumCoverRequests();
|
||||
void AlbumCoverFinishCheck();
|
||||
|
||||
@@ -128,7 +126,7 @@ class SubsonicRequest : public SubsonicBaseRequest {
|
||||
QQueue<AlbumCoverRequest> album_cover_requests_queue_;
|
||||
|
||||
QHash<QString, Request> album_songs_requests_pending_;
|
||||
QMultiMap<QUrl, Song*> album_covers_requests_sent_;
|
||||
QMultiMap<QUrl, QString> album_covers_requests_sent_;
|
||||
|
||||
int albums_requests_active_;
|
||||
|
||||
@@ -140,7 +138,7 @@ class SubsonicRequest : public SubsonicBaseRequest {
|
||||
int album_covers_requested_;
|
||||
int album_covers_received_;
|
||||
|
||||
SongList songs_;
|
||||
QMap<QString, Song> songs_;
|
||||
QStringList errors_;
|
||||
bool no_results_;
|
||||
QList<QNetworkReply*> replies_;
|
||||
|
||||
@@ -45,7 +45,7 @@ class SubsonicScrobbleRequest : public SubsonicBaseRequest {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SubsonicScrobbleRequest(SubsonicService *service, SubsonicUrlHandler *url_handler, Application *app, QObject *parent);
|
||||
explicit SubsonicScrobbleRequest(SubsonicService *service, SubsonicUrlHandler *url_handler, Application *app, QObject *parent = nullptr);
|
||||
~SubsonicScrobbleRequest() override;
|
||||
|
||||
void CreateScrobbleRequest(const QString &song_id, const bool submission, const QDateTime &start_time);
|
||||
@@ -54,8 +54,6 @@ class SubsonicScrobbleRequest : public SubsonicBaseRequest {
|
||||
void ScrobbleReplyReceived(QNetworkReply *reply);
|
||||
|
||||
private:
|
||||
typedef QPair<QString, QString> Param;
|
||||
typedef QList<Param> ParamList;
|
||||
|
||||
struct Request {
|
||||
explicit Request() : submission(false) {}
|
||||
|
||||
@@ -68,7 +68,6 @@ const int SubsonicService::kMaxRedirects = 3;
|
||||
SubsonicService::SubsonicService(Application *app, QObject *parent)
|
||||
: InternetService(Song::Source_Subsonic, "Subsonic", "subsonic", SubsonicSettingsPage::kSettingsGroup, SettingsDialog::Page_Subsonic, app, parent),
|
||||
app_(app),
|
||||
network_(new QNetworkAccessManager),
|
||||
url_handler_(new SubsonicUrlHandler(app, this)),
|
||||
collection_backend_(nullptr),
|
||||
collection_model_(nullptr),
|
||||
@@ -76,12 +75,7 @@ SubsonicService::SubsonicService(Application *app, QObject *parent)
|
||||
http2_(true),
|
||||
verify_certificate_(false),
|
||||
download_album_covers_(true),
|
||||
ping_redirects_(0)
|
||||
{
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
||||
network_->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
#endif
|
||||
ping_redirects_(0) {
|
||||
|
||||
app->player()->RegisterUrlHandler(url_handler_);
|
||||
|
||||
@@ -153,8 +147,11 @@ void SubsonicService::SendPing() {
|
||||
|
||||
void SubsonicService::SendPingWithCredentials(QUrl url, const QString &username, const QString &password, const bool redirect) {
|
||||
|
||||
if (!redirect) {
|
||||
if (!network_ || !redirect) {
|
||||
network_ = std::make_unique<QNetworkAccessManager>();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
|
||||
network_->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
#endif
|
||||
ping_redirects_ = 0;
|
||||
}
|
||||
|
||||
@@ -166,10 +163,7 @@ void SubsonicService::SendPingWithCredentials(QUrl url, const QString &username,
|
||||
|
||||
QUrlQuery url_query(url.query());
|
||||
for (const Param ¶m : params) {
|
||||
EncodedParam encoded_param(QUrl::toPercentEncoding(param.first), QUrl::toPercentEncoding(param.second));
|
||||
if (!url_query.hasQueryItem(encoded_param.first)) {
|
||||
url_query.addQueryItem(encoded_param.first, encoded_param.second);
|
||||
}
|
||||
url_query.addQueryItem(QUrl::toPercentEncoding(param.first), QUrl::toPercentEncoding(param.second));
|
||||
}
|
||||
|
||||
if (!redirect) {
|
||||
@@ -394,8 +388,8 @@ void SubsonicService::Scrobble(const QString &song_id, const bool submission, co
|
||||
}
|
||||
|
||||
if (!scrobble_request_) {
|
||||
// we're doing requests every 30-240s the whole time, so keep reusing this instance
|
||||
scrobble_request_.reset(new SubsonicScrobbleRequest(this, url_handler_, app_, this));
|
||||
// We're doing requests every 30-240s the whole time, so keep reusing this instance
|
||||
scrobble_request_ = std::make_shared<SubsonicScrobbleRequest>(this, url_handler_, app_);
|
||||
}
|
||||
|
||||
scrobble_request_->CreateScrobbleRequest(song_id, submission, time);
|
||||
@@ -425,7 +419,7 @@ void SubsonicService::GetSongs() {
|
||||
}
|
||||
|
||||
ResetSongsRequest();
|
||||
songs_request_.reset(new SubsonicRequest(this, url_handler_, app_, this));
|
||||
songs_request_ = std::make_shared<SubsonicRequest>(this, url_handler_, app_);
|
||||
QObject::connect(songs_request_.get(), &SubsonicRequest::Results, this, &SubsonicService::SongsResultsReceived);
|
||||
QObject::connect(songs_request_.get(), &SubsonicRequest::UpdateStatus, this, &SubsonicService::SongsUpdateStatus);
|
||||
QObject::connect(songs_request_.get(), &SubsonicRequest::ProgressSetMaximum, this, &SubsonicService::SongsProgressSetMaximum);
|
||||
|
||||
@@ -100,9 +100,6 @@ class SubsonicService : public InternetService {
|
||||
typedef QPair<QString, QString> Param;
|
||||
typedef QList<Param> ParamList;
|
||||
|
||||
typedef QPair<QByteArray, QByteArray> EncodedParam;
|
||||
typedef QList<EncodedParam> EncodedParamList;
|
||||
|
||||
void PingError(const QString &error = QString(), const QVariant &debug = QVariant());
|
||||
|
||||
static const char *kClientName;
|
||||
|
||||
@@ -54,8 +54,7 @@ UrlHandler::LoadResult SubsonicUrlHandler::StartLoading(const QUrl &url) {
|
||||
|
||||
QUrlQuery url_query;
|
||||
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(QUrl::toPercentEncoding(param.first), QUrl::toPercentEncoding(param.second));
|
||||
}
|
||||
|
||||
QUrl stream_url(server_url());
|
||||
|
||||
@@ -52,9 +52,6 @@ class SubsonicUrlHandler : public UrlHandler {
|
||||
typedef QPair<QString, QString> Param;
|
||||
typedef QList<Param> ParamList;
|
||||
|
||||
typedef QPair<QByteArray, QByteArray> EncodedParam;
|
||||
typedef QList<EncodedParam> EncodedParamList;
|
||||
|
||||
SubsonicService *service_;
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user