Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ac4dea8f1 | ||
|
|
e8af3e8d3c | ||
|
|
cd05b10168 | ||
|
|
140935bd8c | ||
|
|
ecb122d93c | ||
|
|
c6e08e0039 | ||
|
|
be1e14df81 | ||
|
|
28bca261fb | ||
|
|
2ab5bc1ad2 | ||
|
|
10c57cf6da |
@@ -436,5 +436,5 @@ elseif(NOT HAVE_GSTREAMER)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT SQLITE3_FTS5 AND NOT CMAKE_CROSSCOMPILING)
|
if(NOT SQLITE3_FTS5 AND NOT CMAKE_CROSSCOMPILING)
|
||||||
message(FATAL_ERROR "sqlite3 must be enabled with FTS5. See: https://www.sqlite.org/fts5.html")
|
message(WARNING "sqlite3 must be enabled with FTS5. See: https://www.sqlite.org/fts5.html")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
11
Changelog
11
Changelog
@@ -2,6 +2,17 @@ Strawberry Music Player
|
|||||||
=======================
|
=======================
|
||||||
ChangeLog
|
ChangeLog
|
||||||
|
|
||||||
|
Version 0.6.3:
|
||||||
|
|
||||||
|
* Fixed crash when using internet services.
|
||||||
|
* Fixed musicbrainz tagfetcher only showing 1 result per song.
|
||||||
|
* Fixed collection watcher to unwatch deleted directories.
|
||||||
|
* Added "album - disc" grouping.
|
||||||
|
|
||||||
|
Version 0.6.2:
|
||||||
|
|
||||||
|
* Disabled fatal error for FTS5 cmake test.
|
||||||
|
|
||||||
Version 0.6.1:
|
Version 0.6.1:
|
||||||
|
|
||||||
* Compare artist and album case-insensitive when generating score for album covers.
|
* Compare artist and album case-insensitive when generating score for album covers.
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ if (LSB_RELEASE_EXEC AND RPMBUILD_EXEC)
|
|||||||
set(RPM_DISTRO ${DIST_NAME} CACHE STRING "Suffix of the rpm file")
|
set(RPM_DISTRO ${DIST_NAME} CACHE STRING "Suffix of the rpm file")
|
||||||
endif()
|
endif()
|
||||||
elseif (${DIST_NAME} STREQUAL "mageia")
|
elseif (${DIST_NAME} STREQUAL "mageia")
|
||||||
if (DIST_VERSION)
|
if (DIST_RELEASE)
|
||||||
set(RPM_DISTRO "${DIST_VERSION}" CACHE STRING "Suffix of the rpm file")
|
set(RPM_DISTRO "mga${DIST_RELEASE}" CACHE STRING "Suffix of the rpm file")
|
||||||
else ()
|
else ()
|
||||||
set(RPM_DISTRO ${DIST_NAME} CACHE STRING "Suffix of the rpm file")
|
set(RPM_DISTRO ${DIST_NAME} CACHE STRING "Suffix of the rpm file")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
set(STRAWBERRY_VERSION_MAJOR 0)
|
set(STRAWBERRY_VERSION_MAJOR 0)
|
||||||
set(STRAWBERRY_VERSION_MINOR 6)
|
set(STRAWBERRY_VERSION_MINOR 6)
|
||||||
set(STRAWBERRY_VERSION_PATCH 1)
|
set(STRAWBERRY_VERSION_PATCH 3)
|
||||||
#set(STRAWBERRY_VERSION_PRERELEASE rc1)
|
#set(STRAWBERRY_VERSION_PRERELEASE rc1)
|
||||||
|
|
||||||
set(INCLUDE_GIT_REVISION OFF)
|
set(INCLUDE_GIT_REVISION OFF)
|
||||||
|
|||||||
1
dist/rpm/strawberry.spec.in
vendored
1
dist/rpm/strawberry.spec.in
vendored
@@ -57,6 +57,7 @@ BuildRequires: pkgconfig(Qt5Network)
|
|||||||
BuildRequires: pkgconfig(Qt5Sql)
|
BuildRequires: pkgconfig(Qt5Sql)
|
||||||
BuildRequires: pkgconfig(Qt5X11Extras)
|
BuildRequires: pkgconfig(Qt5X11Extras)
|
||||||
BuildRequires: pkgconfig(Qt5DBus)
|
BuildRequires: pkgconfig(Qt5DBus)
|
||||||
|
BuildRequires: pkgconfig(Qt5Test)
|
||||||
BuildRequires: pkgconfig(gstreamer-1.0)
|
BuildRequires: pkgconfig(gstreamer-1.0)
|
||||||
BuildRequires: pkgconfig(gstreamer-app-1.0)
|
BuildRequires: pkgconfig(gstreamer-app-1.0)
|
||||||
BuildRequires: pkgconfig(gstreamer-audio-1.0)
|
BuildRequires: pkgconfig(gstreamer-audio-1.0)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: strawberry
|
name: strawberry
|
||||||
version: '0.6.1+git'
|
version: '0.6.3+git'
|
||||||
summary: music player and collection organizer
|
summary: music player and collection organizer
|
||||||
description: |
|
description: |
|
||||||
Strawberry is a music player and collection organizer.
|
Strawberry is a music player and collection organizer.
|
||||||
|
|||||||
@@ -153,11 +153,23 @@ void CollectionFilterWidget::UpdateGroupByActions() {
|
|||||||
QActionGroup *CollectionFilterWidget::CreateGroupByActions(QObject *parent) {
|
QActionGroup *CollectionFilterWidget::CreateGroupByActions(QObject *parent) {
|
||||||
|
|
||||||
QActionGroup *ret = new QActionGroup(parent);
|
QActionGroup *ret = new QActionGroup(parent);
|
||||||
|
|
||||||
ret->addAction(CreateGroupByAction(tr("Group by Album artist/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_Album)));
|
ret->addAction(CreateGroupByAction(tr("Group by Album artist/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_Album)));
|
||||||
|
ret->addAction(CreateGroupByAction(tr("Group by Album artist/Album - Disc"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_AlbumDisc)));
|
||||||
|
ret->addAction(CreateGroupByAction(tr("Group by Album artist/Year - Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_YearAlbum)));
|
||||||
|
ret->addAction(CreateGroupByAction(tr("Group by Album artist/Year - Album - Disc"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_YearAlbumDisc)));
|
||||||
|
|
||||||
ret->addAction(CreateGroupByAction(tr("Group by Artist/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_Album)));
|
ret->addAction(CreateGroupByAction(tr("Group by Artist/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_Album)));
|
||||||
ret->addAction(CreateGroupByAction(tr("Group by Genre/Artist/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Genre, CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_Album)));
|
ret->addAction(CreateGroupByAction(tr("Group by Artist/Album - Disc"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_AlbumDisc)));
|
||||||
ret->addAction(CreateGroupByAction(tr("Group by Artist"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist)));
|
|
||||||
ret->addAction(CreateGroupByAction(tr("Group by Artist/Year - Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_YearAlbum)));
|
ret->addAction(CreateGroupByAction(tr("Group by Artist/Year - Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_YearAlbum)));
|
||||||
|
ret->addAction(CreateGroupByAction(tr("Group by Artist/Year - Album - Disc"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_YearAlbumDisc)));
|
||||||
|
|
||||||
|
ret->addAction(CreateGroupByAction(tr("Group by Genre/Album artist/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Genre, CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_Album)));
|
||||||
|
ret->addAction(CreateGroupByAction(tr("Group by Genre/Artist/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Genre, CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_Album)));
|
||||||
|
|
||||||
|
ret->addAction(CreateGroupByAction(tr("Group by Album Artist"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist)));
|
||||||
|
ret->addAction(CreateGroupByAction(tr("Group by Artist"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist)));
|
||||||
|
|
||||||
ret->addAction(CreateGroupByAction(tr("Group by Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Album)));
|
ret->addAction(CreateGroupByAction(tr("Group by Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Album)));
|
||||||
ret->addAction(CreateGroupByAction(tr("Group by Genre/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Genre, CollectionModel::GroupBy_Album)));
|
ret->addAction(CreateGroupByAction(tr("Group by Genre/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Genre, CollectionModel::GroupBy_Album)));
|
||||||
|
|
||||||
|
|||||||
@@ -261,6 +261,12 @@ void CollectionModel::SongsDiscovered(const SongList &songs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case GroupBy_AlbumDisc:
|
||||||
|
key = PrettyAlbumDisc(song.album(), qMax(0, song.disc()));
|
||||||
|
break;
|
||||||
|
case GroupBy_YearAlbumDisc:
|
||||||
|
key = PrettyYearAlbumDisc(qMax(0, song.year()), song.album(), qMax(0, song.disc()));
|
||||||
|
break;
|
||||||
case GroupBy_None:
|
case GroupBy_None:
|
||||||
qLog(Error) << "GroupBy_None";
|
qLog(Error) << "GroupBy_None";
|
||||||
break;
|
break;
|
||||||
@@ -323,6 +329,7 @@ QString CollectionModel::DividerKey(GroupBy type, CollectionItem *item) const {
|
|||||||
case GroupBy_AlbumArtist:
|
case GroupBy_AlbumArtist:
|
||||||
case GroupBy_Artist:
|
case GroupBy_Artist:
|
||||||
case GroupBy_Album:
|
case GroupBy_Album:
|
||||||
|
case GroupBy_AlbumDisc:
|
||||||
case GroupBy_Composer:
|
case GroupBy_Composer:
|
||||||
case GroupBy_Performer:
|
case GroupBy_Performer:
|
||||||
case GroupBy_Grouping:
|
case GroupBy_Grouping:
|
||||||
@@ -343,6 +350,7 @@ QString CollectionModel::DividerKey(GroupBy type, CollectionItem *item) const {
|
|||||||
return SortTextForNumber(item->sort_text.toInt() / 10 * 10);
|
return SortTextForNumber(item->sort_text.toInt() / 10 * 10);
|
||||||
|
|
||||||
case GroupBy_YearAlbum:
|
case GroupBy_YearAlbum:
|
||||||
|
case GroupBy_YearAlbumDisc:
|
||||||
return SortTextForNumber(item->metadata.year());
|
return SortTextForNumber(item->metadata.year());
|
||||||
|
|
||||||
case GroupBy_OriginalYearAlbum:
|
case GroupBy_OriginalYearAlbum:
|
||||||
@@ -370,14 +378,15 @@ QString CollectionModel::DividerDisplayText(GroupBy type, const QString &key) co
|
|||||||
// Pretty display text for the dividers.
|
// Pretty display text for the dividers.
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GroupBy_Album:
|
case GroupBy_AlbumArtist:
|
||||||
case GroupBy_Artist:
|
case GroupBy_Artist:
|
||||||
|
case GroupBy_Album:
|
||||||
|
case GroupBy_AlbumDisc:
|
||||||
case GroupBy_Composer:
|
case GroupBy_Composer:
|
||||||
case GroupBy_Performer:
|
case GroupBy_Performer:
|
||||||
case GroupBy_Disc:
|
case GroupBy_Disc:
|
||||||
case GroupBy_Grouping:
|
case GroupBy_Grouping:
|
||||||
case GroupBy_Genre:
|
case GroupBy_Genre:
|
||||||
case GroupBy_AlbumArtist:
|
|
||||||
case GroupBy_FileType:
|
case GroupBy_FileType:
|
||||||
case GroupBy_Format:
|
case GroupBy_Format:
|
||||||
if (key == "0") return "0-9";
|
if (key == "0") return "0-9";
|
||||||
@@ -385,6 +394,7 @@ QString CollectionModel::DividerDisplayText(GroupBy type, const QString &key) co
|
|||||||
|
|
||||||
case GroupBy_YearAlbum:
|
case GroupBy_YearAlbum:
|
||||||
case GroupBy_OriginalYearAlbum:
|
case GroupBy_OriginalYearAlbum:
|
||||||
|
case GroupBy_YearAlbumDisc:
|
||||||
if (key == "0000") return tr("Unknown");
|
if (key == "0000") return tr("Unknown");
|
||||||
return key.toUpper();
|
return key.toUpper();
|
||||||
|
|
||||||
@@ -618,7 +628,11 @@ QVariant CollectionModel::data(const QModelIndex &idx, int role) const {
|
|||||||
bool is_album_node = false;
|
bool is_album_node = false;
|
||||||
if (role == Qt::DecorationRole && item->type == CollectionItem::Type_Container) {
|
if (role == Qt::DecorationRole && item->type == CollectionItem::Type_Container) {
|
||||||
GroupBy container_type = group_by_[item->container_level];
|
GroupBy container_type = group_by_[item->container_level];
|
||||||
is_album_node = container_type == GroupBy_Album || container_type == GroupBy_YearAlbum || container_type == GroupBy_OriginalYearAlbum;
|
is_album_node = container_type == GroupBy_Album ||
|
||||||
|
container_type == GroupBy_AlbumDisc ||
|
||||||
|
container_type == GroupBy_YearAlbum ||
|
||||||
|
container_type == GroupBy_YearAlbumDisc ||
|
||||||
|
container_type == GroupBy_OriginalYearAlbum;
|
||||||
}
|
}
|
||||||
if (is_album_node) {
|
if (is_album_node) {
|
||||||
// It has const behaviour some of the time - that's ok right?
|
// It has const behaviour some of the time - that's ok right?
|
||||||
@@ -646,8 +660,10 @@ QVariant CollectionModel::data(const CollectionItem *item, int role) const {
|
|||||||
case CollectionItem::Type_Container:
|
case CollectionItem::Type_Container:
|
||||||
switch (container_type) {
|
switch (container_type) {
|
||||||
case GroupBy_Album:
|
case GroupBy_Album:
|
||||||
|
case GroupBy_AlbumDisc:
|
||||||
case GroupBy_YearAlbum:
|
case GroupBy_YearAlbum:
|
||||||
case GroupBy_OriginalYearAlbum:
|
case GroupBy_OriginalYearAlbum:
|
||||||
|
case GroupBy_YearAlbumDisc:
|
||||||
return album_icon_;
|
return album_icon_;
|
||||||
case GroupBy_Artist:
|
case GroupBy_Artist:
|
||||||
case GroupBy_AlbumArtist:
|
case GroupBy_AlbumArtist:
|
||||||
@@ -916,6 +932,12 @@ void CollectionModel::InitQuery(GroupBy type, CollectionQuery *q) {
|
|||||||
case GroupBy_Format:
|
case GroupBy_Format:
|
||||||
q->SetColumnSpec("DISTINCT filetype, samplerate, bitdepth");
|
q->SetColumnSpec("DISTINCT filetype, samplerate, bitdepth");
|
||||||
break;
|
break;
|
||||||
|
case GroupBy_AlbumDisc:
|
||||||
|
q->SetColumnSpec("DISTINCT album, disc");
|
||||||
|
break;
|
||||||
|
case GroupBy_YearAlbumDisc:
|
||||||
|
q->SetColumnSpec("DISTINCT year, album, disc");
|
||||||
|
break;
|
||||||
case GroupBy_None:
|
case GroupBy_None:
|
||||||
q->SetColumnSpec("%songs_table.ROWID, " + Song::kColumnSpec);
|
q->SetColumnSpec("%songs_table.ROWID, " + Song::kColumnSpec);
|
||||||
break;
|
break;
|
||||||
@@ -1000,6 +1022,15 @@ void CollectionModel::FilterQuery(GroupBy type, CollectionItem *item, Collection
|
|||||||
q->AddWhere("samplerate", item->metadata.samplerate());
|
q->AddWhere("samplerate", item->metadata.samplerate());
|
||||||
q->AddWhere("bitdepth", item->metadata.bitdepth());
|
q->AddWhere("bitdepth", item->metadata.bitdepth());
|
||||||
break;
|
break;
|
||||||
|
case GroupBy_AlbumDisc:
|
||||||
|
q->AddWhere("album", item->metadata.album());
|
||||||
|
q->AddWhere("disc", item->metadata.disc());
|
||||||
|
break;
|
||||||
|
case GroupBy_YearAlbumDisc:
|
||||||
|
q->AddWhere("year", item->metadata.year());
|
||||||
|
q->AddWhere("album", item->metadata.album());
|
||||||
|
q->AddWhere("disc", item->metadata.disc());
|
||||||
|
break;
|
||||||
case GroupBy_None:
|
case GroupBy_None:
|
||||||
qLog(Error) << "Unknown GroupBy type" << type << "used in filter";
|
qLog(Error) << "Unknown GroupBy type" << type << "used in filter";
|
||||||
break;
|
break;
|
||||||
@@ -1123,6 +1154,24 @@ CollectionItem *CollectionModel::ItemFromQuery(GroupBy type, bool signal, bool c
|
|||||||
item->sort_text = SortTextForNumber(bitrate) + " ";
|
item->sort_text = SortTextForNumber(bitrate) + " ";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GroupBy_AlbumDisc:{
|
||||||
|
item->metadata.set_album(row.value(0).toString());
|
||||||
|
item->metadata.set_disc(row.value(1).toInt());
|
||||||
|
item->key = PrettyAlbumDisc(item->metadata.album(), item->metadata.disc());
|
||||||
|
int disc = qMax(0, row.value(1).toInt());
|
||||||
|
item->sort_text = item->metadata.album() + SortTextForNumber(disc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GroupBy_YearAlbumDisc:{
|
||||||
|
item->metadata.set_year(row.value(0).toInt());
|
||||||
|
item->metadata.set_album(row.value(1).toString());
|
||||||
|
item->metadata.set_disc(row.value(2).toInt());
|
||||||
|
item->key = PrettyYearAlbumDisc(item->metadata.year(), item->metadata.album(), item->metadata.disc());
|
||||||
|
int year = qMax(0, row.value(0).toInt());
|
||||||
|
int disc = qMax(0, row.value(2).toInt());
|
||||||
|
item->sort_text = SortTextForNumber(year) + item->metadata.album() + SortTextForNumber(disc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case GroupBy_None:
|
case GroupBy_None:
|
||||||
item->metadata.InitFromQuery(row, true);
|
item->metadata.InitFromQuery(row, true);
|
||||||
item->key = item->metadata.title();
|
item->key = item->metadata.title();
|
||||||
@@ -1239,6 +1288,24 @@ CollectionItem *CollectionModel::ItemFromSong(GroupBy type, bool signal, bool cr
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GroupBy_AlbumDisc:{
|
||||||
|
item->metadata.set_album(s.album());
|
||||||
|
item->metadata.set_disc(s.disc());
|
||||||
|
item->key = PrettyAlbumDisc(s.album(), s.disc());
|
||||||
|
int disc = qMax(0, s.disc());
|
||||||
|
item->sort_text = s.album() + SortTextForNumber(disc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GroupBy_YearAlbumDisc:{
|
||||||
|
item->metadata.set_year(s.year());
|
||||||
|
item->metadata.set_album(s.album());
|
||||||
|
item->metadata.set_disc(s.disc());
|
||||||
|
item->key = PrettyYearAlbumDisc(s.year(), s.album(), s.disc());
|
||||||
|
int year = qMax(0, s.year());
|
||||||
|
int disc = qMax(0, s.disc());
|
||||||
|
item->sort_text = SortTextForNumber(year) + s.album() + SortTextForNumber(disc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case GroupBy_None:
|
case GroupBy_None:
|
||||||
item->metadata = s;
|
item->metadata = s;
|
||||||
item->key = s.title();
|
item->key = s.title();
|
||||||
@@ -1289,13 +1356,33 @@ QString CollectionModel::TextOrUnknown(const QString &text) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CollectionModel::PrettyYearAlbum(int year, const QString &album) {
|
QString CollectionModel::PrettyYearAlbum(const int year, const QString &album) {
|
||||||
|
|
||||||
if (year <= 0) return TextOrUnknown(album);
|
if (year <= 0) return TextOrUnknown(album);
|
||||||
return QString::number(year) + " - " + TextOrUnknown(album);
|
return QString::number(year) + " - " + TextOrUnknown(album);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString CollectionModel::PrettyAlbumDisc(const QString &album, const int disc) {
|
||||||
|
|
||||||
|
if (disc <= 0 || album.contains(QRegExp(Song::kAlbumRemoveDisc))) return TextOrUnknown(album);
|
||||||
|
else return TextOrUnknown(album) + " - (Disc " + QString::number(disc) + ")";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CollectionModel::PrettyYearAlbumDisc(const int year, const QString &album, const int disc) {
|
||||||
|
|
||||||
|
QString str;
|
||||||
|
|
||||||
|
if (year <= 0) str = TextOrUnknown(album);
|
||||||
|
else str = QString::number(year) + " - " + TextOrUnknown(album);
|
||||||
|
|
||||||
|
if (!album.contains(QRegExp(Song::kAlbumRemoveDisc)) && disc > 0) str += " - (Disc " + QString::number(disc) + ")";
|
||||||
|
|
||||||
|
return str;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QString CollectionModel::SortText(QString text) {
|
QString CollectionModel::SortText(QString text) {
|
||||||
|
|
||||||
if (text.isEmpty()) {
|
if (text.isEmpty()) {
|
||||||
|
|||||||
@@ -100,7 +100,9 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
|||||||
GroupBy_OriginalYear = 14,
|
GroupBy_OriginalYear = 14,
|
||||||
GroupBy_Samplerate = 15,
|
GroupBy_Samplerate = 15,
|
||||||
GroupBy_Bitdepth = 16,
|
GroupBy_Bitdepth = 16,
|
||||||
GroupBy_Format = 17
|
GroupBy_Format = 17,
|
||||||
|
GroupBy_AlbumDisc = 18,
|
||||||
|
GroupBy_YearAlbumDisc = 19
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Grouping {
|
struct Grouping {
|
||||||
@@ -161,7 +163,9 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
|||||||
|
|
||||||
// Utility functions for manipulating text
|
// Utility functions for manipulating text
|
||||||
static QString TextOrUnknown(const QString &text);
|
static QString TextOrUnknown(const QString &text);
|
||||||
static QString PrettyYearAlbum(int year, const QString &album);
|
static QString PrettyYearAlbum(const int year, const QString &album);
|
||||||
|
static QString PrettyAlbumDisc(const QString &album, const int disc);
|
||||||
|
static QString PrettyYearAlbumDisc(const int year, const QString &album, const int disc);
|
||||||
static QString SortText(QString text);
|
static QString SortText(QString text);
|
||||||
static QString SortTextForNumber(int year);
|
static QString SortTextForNumber(int year);
|
||||||
static QString SortTextForArtist(QString artist);
|
static QString SortTextForArtist(QString artist);
|
||||||
|
|||||||
@@ -195,13 +195,21 @@ void CollectionWatcher::ScanTransaction::CommitNewOrUpdatedSongs() {
|
|||||||
touched_subdirs.clear();
|
touched_subdirs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const Subdirectory &subdir : deleted_subdirs) {
|
||||||
|
if (watcher_->watched_dirs_.contains(dir_)) {
|
||||||
|
watcher_->RemoveWatch(watcher_->watched_dirs_[dir_], subdir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deleted_subdirs.clear();
|
||||||
|
|
||||||
if (watcher_->monitor_) {
|
if (watcher_->monitor_) {
|
||||||
// Watch the new subdirectories
|
// Watch the new subdirectories
|
||||||
for (const Subdirectory &subdir : new_subdirs) {
|
for (const Subdirectory &subdir : new_subdirs) {
|
||||||
watcher_->AddWatch(watcher_->watched_dirs_[dir_], subdir.path);
|
if (watcher_->watched_dirs_.contains(dir_)) {
|
||||||
|
watcher_->AddWatch(watcher_->watched_dirs_[dir_], subdir.path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new_subdirs.clear();
|
new_subdirs.clear();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -329,10 +337,10 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const Subdirectory
|
|||||||
// If a directory is moved then only its parent gets a changed notification, so we need to look and see if any of our children don't exist any more.
|
// If a directory is moved then only its parent gets a changed notification, so we need to look and see if any of our children don't exist any more.
|
||||||
// If one has been removed, "rescan" it to get the deleted songs
|
// If one has been removed, "rescan" it to get the deleted songs
|
||||||
SubdirectoryList previous_subdirs = t->GetImmediateSubdirs(path);
|
SubdirectoryList previous_subdirs = t->GetImmediateSubdirs(path);
|
||||||
for (const Subdirectory &subdir : previous_subdirs) {
|
for (const Subdirectory &prev_subdir : previous_subdirs) {
|
||||||
if (!QFile::exists(subdir.path) && subdir.path != path) {
|
if (!QFile::exists(prev_subdir.path) && prev_subdir.path != path) {
|
||||||
t->AddToProgressMax(1);
|
t->AddToProgressMax(1);
|
||||||
ScanSubdirectory(subdir.path, subdir, t, true);
|
ScanSubdirectory(prev_subdir.path, prev_subdir, t, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,6 +474,10 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const Subdirectory
|
|||||||
else
|
else
|
||||||
t->touched_subdirs << updated_subdir;
|
t->touched_subdirs << updated_subdir;
|
||||||
|
|
||||||
|
if (updated_subdir.mtime == 0) { // Subdirectory deleted, mark it for removal from the watcher.
|
||||||
|
t->deleted_subdirs << updated_subdir;
|
||||||
|
}
|
||||||
|
|
||||||
t->AddToProgress(1);
|
t->AddToProgress(1);
|
||||||
|
|
||||||
if (live_scanning_) t->CommitNewOrUpdatedSongs();
|
if (live_scanning_) t->CommitNewOrUpdatedSongs();
|
||||||
@@ -640,6 +652,17 @@ void CollectionWatcher::AddWatch(const Directory &dir, const QString &path) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CollectionWatcher::RemoveWatch(const Directory &dir, const Subdirectory &subdir) {
|
||||||
|
|
||||||
|
for (const QString &subdir_path : subdir_mapping_.keys(dir)) {
|
||||||
|
if (subdir_path != subdir.path) continue;
|
||||||
|
fs_watcher_->RemovePath(subdir_path);
|
||||||
|
subdir_mapping_.remove(subdir_path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void CollectionWatcher::RemoveDirectory(const Directory &dir) {
|
void CollectionWatcher::RemoveDirectory(const Directory &dir) {
|
||||||
|
|
||||||
rescan_queue_.remove(dir.id);
|
rescan_queue_.remove(dir.id);
|
||||||
@@ -687,7 +710,7 @@ void CollectionWatcher::DirectoryChanged(const QString &subdir) {
|
|||||||
void CollectionWatcher::RescanPathsNow() {
|
void CollectionWatcher::RescanPathsNow() {
|
||||||
|
|
||||||
for (int dir : rescan_queue_.keys()) {
|
for (int dir : rescan_queue_.keys()) {
|
||||||
if (stop_requested_) return;
|
if (stop_requested_) break;
|
||||||
ScanTransaction transaction(this, dir, false, false, prevent_delete_);
|
ScanTransaction transaction(this, dir, false, false, prevent_delete_);
|
||||||
transaction.AddToProgressMax(rescan_queue_[dir].count());
|
transaction.AddToProgressMax(rescan_queue_[dir].count());
|
||||||
|
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ signals:
|
|||||||
SongList touched_songs;
|
SongList touched_songs;
|
||||||
SubdirectoryList new_subdirs;
|
SubdirectoryList new_subdirs;
|
||||||
SubdirectoryList touched_subdirs;
|
SubdirectoryList touched_subdirs;
|
||||||
|
SubdirectoryList deleted_subdirs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ScanTransaction(const ScanTransaction&) {}
|
ScanTransaction(const ScanTransaction&) {}
|
||||||
@@ -161,6 +162,7 @@ signals:
|
|||||||
QString PickBestImage(const QStringList &images);
|
QString PickBestImage(const QStringList &images);
|
||||||
QUrl ImageForSong(const QString &path, QMap<QString, QStringList> &album_art);
|
QUrl ImageForSong(const QString &path, QMap<QString, QStringList> &album_art);
|
||||||
void AddWatch(const Directory &dir, const QString &path);
|
void AddWatch(const Directory &dir, const QString &path);
|
||||||
|
void RemoveWatch(const Directory &dir, const Subdirectory &subdir);
|
||||||
uint GetMtimeForCue(const QString &cue_path);
|
uint GetMtimeForCue(const QString &cue_path);
|
||||||
void PerformScan(bool incremental, bool ignore_mtimes);
|
void PerformScan(bool incremental, bool ignore_mtimes);
|
||||||
|
|
||||||
|
|||||||
@@ -85,20 +85,22 @@ GroupByDialog::GroupByDialog(QWidget *parent) : QDialog(parent), ui_(new Ui_Grou
|
|||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Artist, 1));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Artist, 1));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_AlbumArtist, 2));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_AlbumArtist, 2));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Album, 3));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Album, 3));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Disc, 4));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_AlbumDisc, 4));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Format, 5));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Disc, 5));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Genre, 6));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Format, 6));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_OriginalYear, 7));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Genre, 7));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Year, 8));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Year, 8));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_OriginalYearAlbum, 9));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_YearAlbum, 9));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_YearAlbum, 10));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_YearAlbumDisc, 10));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Composer, 11));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_OriginalYear, 11));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Performer, 12));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_OriginalYearAlbum, 12));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Grouping, 13));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Composer, 13));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_FileType, 14));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Performer, 14));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Samplerate, 15));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Grouping, 15));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Bitdepth, 16));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_FileType, 16));
|
||||||
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Bitrate, 17));
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Samplerate, 17));
|
||||||
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Bitdepth, 18));
|
||||||
|
p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Bitrate, 19));
|
||||||
|
|
||||||
connect(ui_->buttonbox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), SLOT(Reset()));
|
connect(ui_->buttonbox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), SLOT(Reset()));
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,11 @@
|
|||||||
<string>Album</string>
|
<string>Album</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Album - Disc</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Disc</string>
|
<string>Disc</string>
|
||||||
@@ -78,11 +83,6 @@
|
|||||||
<string>Genre</string>
|
<string>Genre</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Original year</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Year</string>
|
<string>Year</string>
|
||||||
@@ -90,12 +90,22 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Original year - Album</string>
|
<string>Year - Album</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Year - Album</string>
|
<string>Year - Album - Disc</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Original year</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Original year - Album</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@@ -164,6 +174,11 @@
|
|||||||
<string>Album</string>
|
<string>Album</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Album - Disc</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Disc</string>
|
<string>Disc</string>
|
||||||
@@ -179,11 +194,6 @@
|
|||||||
<string>Genre</string>
|
<string>Genre</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Original year</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Year</string>
|
<string>Year</string>
|
||||||
@@ -191,12 +201,22 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Original year - Album</string>
|
<string>Year - Album</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Year - Album</string>
|
<string>Year - Album - Disc</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Original year</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Original year - Album</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@@ -265,6 +285,11 @@
|
|||||||
<string>Album</string>
|
<string>Album</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Album - Disc</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Disc</string>
|
<string>Disc</string>
|
||||||
@@ -280,11 +305,6 @@
|
|||||||
<string>Genre</string>
|
<string>Genre</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Original year</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Year</string>
|
<string>Year</string>
|
||||||
@@ -292,12 +312,22 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Original year - Album</string>
|
<string>Year - Album</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Year - Album</string>
|
<string>Year - Album - Disc</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Original year</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Original year - Album</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|||||||
@@ -77,29 +77,44 @@ QString SavedGroupingManager::GroupByToString(const CollectionModel::GroupBy &g)
|
|||||||
case CollectionModel::GroupBy_None: {
|
case CollectionModel::GroupBy_None: {
|
||||||
return tr("None");
|
return tr("None");
|
||||||
}
|
}
|
||||||
case CollectionModel::GroupBy_AlbumArtist: {
|
|
||||||
return tr("Album artist");
|
|
||||||
}
|
|
||||||
case CollectionModel::GroupBy_Artist: {
|
case CollectionModel::GroupBy_Artist: {
|
||||||
return tr("Artist");
|
return tr("Artist");
|
||||||
}
|
}
|
||||||
|
case CollectionModel::GroupBy_AlbumArtist: {
|
||||||
|
return tr("Album artist");
|
||||||
|
}
|
||||||
case CollectionModel::GroupBy_Album: {
|
case CollectionModel::GroupBy_Album: {
|
||||||
return tr("Album");
|
return tr("Album");
|
||||||
}
|
}
|
||||||
case CollectionModel::GroupBy_YearAlbum: {
|
case CollectionModel::GroupBy_AlbumDisc: {
|
||||||
return tr("Year - Album");
|
return tr("Album - Disc");
|
||||||
}
|
}
|
||||||
case CollectionModel::GroupBy_Year: {
|
case CollectionModel::GroupBy_Disc: {
|
||||||
return tr("Year");
|
return tr("Disc");
|
||||||
}
|
}
|
||||||
case CollectionModel::GroupBy_Composer: {
|
case CollectionModel::GroupBy_Format: {
|
||||||
return tr("Composer");
|
return tr("Format");
|
||||||
}
|
}
|
||||||
case CollectionModel::GroupBy_Genre: {
|
case CollectionModel::GroupBy_Genre: {
|
||||||
return tr("Genre");
|
return tr("Genre");
|
||||||
}
|
}
|
||||||
case CollectionModel::GroupBy_FileType: {
|
case CollectionModel::GroupBy_Year: {
|
||||||
return tr("File type");
|
return tr("Year");
|
||||||
|
}
|
||||||
|
case CollectionModel::GroupBy_YearAlbum: {
|
||||||
|
return tr("Year - Album");
|
||||||
|
}
|
||||||
|
case CollectionModel::GroupBy_YearAlbumDisc: {
|
||||||
|
return tr("Year - Album - Disc");
|
||||||
|
}
|
||||||
|
case CollectionModel::GroupBy_OriginalYear: {
|
||||||
|
return tr("Original year");
|
||||||
|
}
|
||||||
|
case CollectionModel::GroupBy_OriginalYearAlbum: {
|
||||||
|
return tr("Original year - Album");
|
||||||
|
}
|
||||||
|
case CollectionModel::GroupBy_Composer: {
|
||||||
|
return tr("Composer");
|
||||||
}
|
}
|
||||||
case CollectionModel::GroupBy_Performer: {
|
case CollectionModel::GroupBy_Performer: {
|
||||||
return tr("Performer");
|
return tr("Performer");
|
||||||
@@ -107,6 +122,9 @@ QString SavedGroupingManager::GroupByToString(const CollectionModel::GroupBy &g)
|
|||||||
case CollectionModel::GroupBy_Grouping: {
|
case CollectionModel::GroupBy_Grouping: {
|
||||||
return tr("Grouping");
|
return tr("Grouping");
|
||||||
}
|
}
|
||||||
|
case CollectionModel::GroupBy_FileType: {
|
||||||
|
return tr("File type");
|
||||||
|
}
|
||||||
case CollectionModel::GroupBy_Samplerate: {
|
case CollectionModel::GroupBy_Samplerate: {
|
||||||
return tr("Sample rate");
|
return tr("Sample rate");
|
||||||
}
|
}
|
||||||
@@ -116,18 +134,6 @@ QString SavedGroupingManager::GroupByToString(const CollectionModel::GroupBy &g)
|
|||||||
case CollectionModel::GroupBy_Bitrate: {
|
case CollectionModel::GroupBy_Bitrate: {
|
||||||
return tr("Bitrate");
|
return tr("Bitrate");
|
||||||
}
|
}
|
||||||
case CollectionModel::GroupBy_Disc: {
|
|
||||||
return tr("Disc");
|
|
||||||
}
|
|
||||||
case CollectionModel::GroupBy_OriginalYearAlbum: {
|
|
||||||
return tr("Original year - Album");
|
|
||||||
}
|
|
||||||
case CollectionModel::GroupBy_OriginalYear: {
|
|
||||||
return tr("Original year");
|
|
||||||
}
|
|
||||||
case CollectionModel::GroupBy_Format: {
|
|
||||||
return tr("Format");
|
|
||||||
}
|
|
||||||
default: { return tr("Unknown"); }
|
default: { return tr("Unknown"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ QStandardItem *InternetSearchModel::BuildContainers(const Song &s, QStandardItem
|
|||||||
QString display_text;
|
QString display_text;
|
||||||
QString sort_text;
|
QString sort_text;
|
||||||
QString unique_tag;
|
QString unique_tag;
|
||||||
int year = 0;
|
|
||||||
|
|
||||||
switch (group_by_[level]) {
|
switch (group_by_[level]) {
|
||||||
|
|
||||||
@@ -114,33 +113,37 @@ QStandardItem *InternetSearchModel::BuildContainers(const Song &s, QStandardItem
|
|||||||
has_artist_icon = true;
|
has_artist_icon = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CollectionModel::GroupBy_YearAlbum:
|
case CollectionModel::GroupBy_YearAlbum:{
|
||||||
year = qMax(0, s.year());
|
int year = qMax(0, s.year());
|
||||||
display_text = CollectionModel::PrettyYearAlbum(year, s.album());
|
display_text = CollectionModel::PrettyYearAlbum(year, s.album());
|
||||||
sort_text = CollectionModel::SortTextForNumber(year) + s.album();
|
sort_text = CollectionModel::SortTextForNumber(year) + s.album();
|
||||||
unique_tag = s.album_id();
|
unique_tag = s.album_id();
|
||||||
has_album_icon = true;
|
has_album_icon = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CollectionModel::GroupBy_OriginalYearAlbum:
|
case CollectionModel::GroupBy_OriginalYearAlbum:{
|
||||||
year = qMax(0, s.effective_originalyear());
|
int year = qMax(0, s.effective_originalyear());
|
||||||
display_text = CollectionModel::PrettyYearAlbum(year, s.album());
|
display_text = CollectionModel::PrettyYearAlbum(year, s.album());
|
||||||
sort_text = CollectionModel::SortTextForNumber(year) + s.album();
|
sort_text = CollectionModel::SortTextForNumber(year) + s.album();
|
||||||
unique_tag = s.album_id();
|
unique_tag = s.album_id();
|
||||||
has_album_icon = true;
|
has_album_icon = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CollectionModel::GroupBy_Year:
|
case CollectionModel::GroupBy_Year:{
|
||||||
year = qMax(0, s.year());
|
int year = qMax(0, s.year());
|
||||||
display_text = QString::number(year);
|
display_text = QString::number(year);
|
||||||
sort_text = CollectionModel::SortTextForNumber(year) + " ";
|
sort_text = CollectionModel::SortTextForNumber(year) + " ";
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CollectionModel::GroupBy_OriginalYear:
|
case CollectionModel::GroupBy_OriginalYear:{
|
||||||
year = qMax(0, s.effective_originalyear());
|
int year = qMax(0, s.effective_originalyear());
|
||||||
display_text = QString::number(year);
|
display_text = QString::number(year);
|
||||||
sort_text = CollectionModel::SortTextForNumber(year) + " ";
|
sort_text = CollectionModel::SortTextForNumber(year) + " ";
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CollectionModel::GroupBy_Composer:
|
case CollectionModel::GroupBy_Composer:
|
||||||
display_text = CollectionModel::TextOrUnknown(s.composer());
|
display_text = CollectionModel::TextOrUnknown(s.composer());
|
||||||
@@ -214,6 +217,23 @@ QStandardItem *InternetSearchModel::BuildContainers(const Song &s, QStandardItem
|
|||||||
sort_text = display_text;
|
sort_text = display_text;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CollectionModel::GroupBy_AlbumDisc:{
|
||||||
|
int disc = qMax(0, s.disc());
|
||||||
|
display_text = CollectionModel::PrettyAlbumDisc(s.album(), disc);
|
||||||
|
sort_text = s.album() + CollectionModel::SortTextForNumber(disc);
|
||||||
|
unique_tag = s.album_id();
|
||||||
|
has_album_icon = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CollectionModel::GroupBy_YearAlbumDisc:{
|
||||||
|
int year = qMax(0, s.year());
|
||||||
|
int disc = qMax(0, s.disc());
|
||||||
|
display_text = CollectionModel::PrettyYearAlbumDisc(year, s.album(), disc);
|
||||||
|
sort_text = CollectionModel::SortTextForNumber(year) + s.album() + CollectionModel::SortTextForNumber(disc);
|
||||||
|
unique_tag = s.album_id();
|
||||||
|
has_album_icon = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CollectionModel::GroupBy_None:
|
case CollectionModel::GroupBy_None:
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ QByteArray MusicBrainzClient::GetReplyData(QNetworkReply *reply, QString &error)
|
|||||||
else {
|
else {
|
||||||
if (reply->error() != QNetworkReply::NoError && reply->error() < 200) {
|
if (reply->error() != QNetworkReply::NoError && reply->error() < 200) {
|
||||||
// This is a network error, there is nothing more to do.
|
// This is a network error, there is nothing more to do.
|
||||||
error = Error(QString("%1 (%2)").arg(reply->errorString()).arg(reply->error()));
|
Error(QString("%1 (%2)").arg(reply->errorString()).arg(reply->error()));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// See if there is Json data containing "error" - then use that instead.
|
// See if there is Json data containing "error" - then use that instead.
|
||||||
@@ -99,10 +99,11 @@ QByteArray MusicBrainzClient::GetReplyData(QNetworkReply *reply, QString &error)
|
|||||||
error = QString("%1 (%2)").arg(reply->errorString()).arg(reply->error());
|
error = QString("%1 (%2)").arg(reply->errorString()).arg(reply->error());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error = Error(QString("Received HTTP code %1").arg(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()));
|
error = QString("Received HTTP code %1").arg(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt());
|
||||||
}
|
}
|
||||||
|
Error(error, data);
|
||||||
}
|
}
|
||||||
error = Error(error);
|
else Error(error);
|
||||||
}
|
}
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
@@ -136,7 +137,7 @@ void MusicBrainzClient::Start(const int id, const QStringList &mbid_list) {
|
|||||||
++request_number;
|
++request_number;
|
||||||
if (request_number > kMaxRequestPerTrack) break;
|
if (request_number > kMaxRequestPerTrack) break;
|
||||||
Request request(id, mbid, request_number);
|
Request request(id, mbid, request_number);
|
||||||
requests_pending_.enqueue(request);
|
requests_pending_.insert(id, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!timer_flush_requests_->isActive()) {
|
if (!timer_flush_requests_->isActive()) {
|
||||||
@@ -166,7 +167,7 @@ void MusicBrainzClient::FlushRequests() {
|
|||||||
|
|
||||||
if (!requests_.isEmpty() || requests_pending_.isEmpty()) return;
|
if (!requests_.isEmpty() || requests_pending_.isEmpty()) return;
|
||||||
|
|
||||||
Request request = requests_pending_.dequeue();
|
Request request = requests_pending_.take(requests_pending_.firstKey());
|
||||||
|
|
||||||
const ParamList params = ParamList() << Param("inc", "artists+releases+media");
|
const ParamList params = ParamList() << Param("inc", "artists+releases+media");
|
||||||
|
|
||||||
@@ -216,7 +217,7 @@ void MusicBrainzClient::RequestFinished(QNetworkReply *reply, const int id, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No more pending requests for this id: emit the results we have.
|
// No more pending requests for this id: emit the results we have.
|
||||||
if (!requests_.contains(id)) {
|
if (!requests_.contains(id) && !requests_pending_.contains(id)) {
|
||||||
// Merge the results we have
|
// Merge the results we have
|
||||||
ResultList ret;
|
ResultList ret;
|
||||||
QList<PendingResults> result_list_list = pending_results_.take(id);
|
QList<PendingResults> result_list_list = pending_results_.take(id);
|
||||||
@@ -493,13 +494,12 @@ MusicBrainzClient::ResultList MusicBrainzClient::UniqueResults(const ResultList&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MusicBrainzClient::Error(QString error, QVariant debug) {
|
void MusicBrainzClient::Error(const QString &error, QVariant debug) {
|
||||||
|
|
||||||
qLog(Error) << "MusicBrainz:" << error;
|
qLog(Error) << "MusicBrainz:" << error;
|
||||||
if (debug.isValid()) qLog(Debug) << debug;
|
if (debug.isValid()) qLog(Debug) << debug;
|
||||||
|
|
||||||
return error;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QMultiMap>
|
#include <QMultiMap>
|
||||||
#include <QQueue>
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
@@ -199,7 +198,7 @@ class MusicBrainzClient : public QObject {
|
|||||||
static void ParseArtist(QXmlStreamReader* reader, QString* artist);
|
static void ParseArtist(QXmlStreamReader* reader, QString* artist);
|
||||||
static Release ParseRelease(QXmlStreamReader* reader);
|
static Release ParseRelease(QXmlStreamReader* reader);
|
||||||
static ResultList UniqueResults(const ResultList& results, UniqueResultsSortOption opt = SortResults);
|
static ResultList UniqueResults(const ResultList& results, UniqueResultsSortOption opt = SortResults);
|
||||||
QString Error(QString error, QVariant debug = QVariant());
|
void Error(const QString &error, QVariant debug = QVariant());
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -212,7 +211,7 @@ class MusicBrainzClient : public QObject {
|
|||||||
|
|
||||||
QNetworkAccessManager* network_;
|
QNetworkAccessManager* network_;
|
||||||
NetworkTimeouts* timeouts_;
|
NetworkTimeouts* timeouts_;
|
||||||
QQueue<Request> requests_pending_;
|
QMultiMap<int, Request> requests_pending_;
|
||||||
QMultiMap<int, QNetworkReply*> requests_;
|
QMultiMap<int, QNetworkReply*> requests_;
|
||||||
// Results we received so far, kept here until all the replies are finished
|
// Results we received so far, kept here until all the replies are finished
|
||||||
QMap<int, QList<PendingResults>> pending_results_;
|
QMap<int, QList<PendingResults>> pending_results_;
|
||||||
|
|||||||
@@ -47,16 +47,7 @@ QobuzBaseRequest::QobuzBaseRequest(QobuzService *service, NetworkAccessManager *
|
|||||||
network_(network)
|
network_(network)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
QobuzBaseRequest::~QobuzBaseRequest() {
|
QobuzBaseRequest::~QobuzBaseRequest() {}
|
||||||
|
|
||||||
while (!replies_.isEmpty()) {
|
|
||||||
QNetworkReply *reply = replies_.takeFirst();
|
|
||||||
disconnect(reply, 0, this, 0);
|
|
||||||
if (reply->isRunning()) reply->abort();
|
|
||||||
reply->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkReply *QobuzBaseRequest::CreateRequest(const QString &ressource_name, const QList<Param> ¶ms_provided) {
|
QNetworkReply *QobuzBaseRequest::CreateRequest(const QString &ressource_name, const QList<Param> ¶ms_provided) {
|
||||||
|
|
||||||
@@ -78,7 +69,6 @@ QNetworkReply *QobuzBaseRequest::CreateRequest(const QString &ressource_name, co
|
|||||||
|
|
||||||
QNetworkReply *reply = network_->get(req);
|
QNetworkReply *reply = network_->get(req);
|
||||||
connect(reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(HandleSSLErrors(QList<QSslError>)));
|
connect(reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(HandleSSLErrors(QList<QSslError>)));
|
||||||
replies_ << reply;
|
|
||||||
|
|
||||||
//qLog(Debug) << "Qobuz: Sending request" << url;
|
//qLog(Debug) << "Qobuz: Sending request" << url;
|
||||||
|
|
||||||
@@ -96,11 +86,6 @@ void QobuzBaseRequest::HandleSSLErrors(QList<QSslError> ssl_errors) {
|
|||||||
|
|
||||||
QByteArray QobuzBaseRequest::GetReplyData(QNetworkReply *reply) {
|
QByteArray QobuzBaseRequest::GetReplyData(QNetworkReply *reply) {
|
||||||
|
|
||||||
if (replies_.contains(reply)) {
|
|
||||||
replies_.removeAll(reply);
|
|
||||||
reply->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
|
|
||||||
if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200) {
|
if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200) {
|
||||||
|
|||||||
@@ -105,7 +105,6 @@ class QobuzBaseRequest : public QObject {
|
|||||||
|
|
||||||
QobuzService *service_;
|
QobuzService *service_;
|
||||||
NetworkAccessManager *network_;
|
NetworkAccessManager *network_;
|
||||||
QList<QNetworkReply*> replies_;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class QobuzFavoriteRequest : public QobuzBaseRequest {
|
|||||||
|
|
||||||
QobuzService *service_;
|
QobuzService *service_;
|
||||||
NetworkAccessManager *network_;
|
NetworkAccessManager *network_;
|
||||||
QList <QNetworkReply*> replies_;
|
QList<QNetworkReply*> replies_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,13 @@ QobuzRequest::QobuzRequest(QobuzService *service, QobuzUrlHandler *url_handler,
|
|||||||
|
|
||||||
QobuzRequest::~QobuzRequest() {
|
QobuzRequest::~QobuzRequest() {
|
||||||
|
|
||||||
|
while (!replies_.isEmpty()) {
|
||||||
|
QNetworkReply *reply = replies_.takeFirst();
|
||||||
|
disconnect(reply, 0, this, 0);
|
||||||
|
if (reply->isRunning()) reply->abort();
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
while (!album_cover_replies_.isEmpty()) {
|
while (!album_cover_replies_.isEmpty()) {
|
||||||
QNetworkReply *reply = album_cover_replies_.takeFirst();
|
QNetworkReply *reply = album_cover_replies_.takeFirst();
|
||||||
disconnect(reply, 0, this, 0);
|
disconnect(reply, 0, this, 0);
|
||||||
@@ -158,6 +165,7 @@ void QobuzRequest::FlushArtistsRequests() {
|
|||||||
reply = CreateRequest("artist/search", params);
|
reply = CreateRequest("artist/search", params);
|
||||||
}
|
}
|
||||||
if (!reply) continue;
|
if (!reply) continue;
|
||||||
|
replies_ << reply;
|
||||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(ArtistsReplyReceived(QNetworkReply*, const int, const int)), reply, request.limit, request.offset);
|
NewClosure(reply, SIGNAL(finished()), this, SLOT(ArtistsReplyReceived(QNetworkReply*, const int, const int)), reply, request.limit, request.offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -205,6 +213,7 @@ void QobuzRequest::FlushAlbumsRequests() {
|
|||||||
reply = CreateRequest("album/search", params);
|
reply = CreateRequest("album/search", params);
|
||||||
}
|
}
|
||||||
if (!reply) continue;
|
if (!reply) continue;
|
||||||
|
replies_ << reply;
|
||||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(AlbumsReplyReceived(QNetworkReply*, const int, const int)), reply, request.limit, request.offset);
|
NewClosure(reply, SIGNAL(finished()), this, SLOT(AlbumsReplyReceived(QNetworkReply*, const int, const int)), reply, request.limit, request.offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -252,6 +261,7 @@ void QobuzRequest::FlushSongsRequests() {
|
|||||||
reply = CreateRequest("track/search", params);
|
reply = CreateRequest("track/search", params);
|
||||||
}
|
}
|
||||||
if (!reply) continue;
|
if (!reply) continue;
|
||||||
|
replies_ << reply;
|
||||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(SongsReplyReceived(QNetworkReply*, const int, const int)), reply, request.limit, request.offset);
|
NewClosure(reply, SIGNAL(finished()), this, SLOT(SongsReplyReceived(QNetworkReply*, const int, const int)), reply, request.limit, request.offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -302,6 +312,10 @@ void QobuzRequest::AddSongsSearchRequest(const int offset) {
|
|||||||
|
|
||||||
void QobuzRequest::ArtistsReplyReceived(QNetworkReply *reply, const int limit_requested, const int offset_requested) {
|
void QobuzRequest::ArtistsReplyReceived(QNetworkReply *reply, const int limit_requested, const int offset_requested) {
|
||||||
|
|
||||||
|
if (!replies_.contains(reply)) return;
|
||||||
|
replies_.removeAll(reply);
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
QByteArray data = GetReplyData(reply);
|
QByteArray data = GetReplyData(reply);
|
||||||
|
|
||||||
--artists_requests_active_;
|
--artists_requests_active_;
|
||||||
@@ -479,6 +493,7 @@ void QobuzRequest::FlushArtistAlbumsRequests() {
|
|||||||
|
|
||||||
if (request.offset > 0) params << Param("offset", QString::number(request.offset));
|
if (request.offset > 0) params << Param("offset", QString::number(request.offset));
|
||||||
QNetworkReply *reply = CreateRequest(QString("artist/get"), params);
|
QNetworkReply *reply = CreateRequest(QString("artist/get"), params);
|
||||||
|
replies_ << reply;
|
||||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(ArtistAlbumsReplyReceived(QNetworkReply*, const qint64, const int)), reply, request.artist_id, request.offset);
|
NewClosure(reply, SIGNAL(finished()), this, SLOT(ArtistAlbumsReplyReceived(QNetworkReply*, const qint64, const int)), reply, request.artist_id, request.offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -497,6 +512,10 @@ void QobuzRequest::ArtistAlbumsReplyReceived(QNetworkReply *reply, const qint64
|
|||||||
|
|
||||||
void QobuzRequest::AlbumsReceived(QNetworkReply *reply, const qint64 artist_id_requested, const int limit_requested, const int offset_requested) {
|
void QobuzRequest::AlbumsReceived(QNetworkReply *reply, const qint64 artist_id_requested, const int limit_requested, const int offset_requested) {
|
||||||
|
|
||||||
|
if (!replies_.contains(reply)) return;
|
||||||
|
replies_.removeAll(reply);
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
QByteArray data = GetReplyData(reply);
|
QByteArray data = GetReplyData(reply);
|
||||||
|
|
||||||
if (finished_) return;
|
if (finished_) return;
|
||||||
@@ -707,6 +726,7 @@ void QobuzRequest::FlushAlbumSongsRequests() {
|
|||||||
ParamList params = ParamList() << Param("album_id", request.album_id);
|
ParamList params = ParamList() << Param("album_id", request.album_id);
|
||||||
if (request.offset > 0) params << Param("offset", QString::number(request.offset));
|
if (request.offset > 0) params << Param("offset", QString::number(request.offset));
|
||||||
QNetworkReply *reply = CreateRequest(QString("album/get"), params);
|
QNetworkReply *reply = CreateRequest(QString("album/get"), params);
|
||||||
|
replies_ << reply;
|
||||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(AlbumSongsReplyReceived(QNetworkReply*, const qint64, const QString&, const int, const QString&, const QString&)), reply, request.artist_id, request.album_id, request.offset, request.album_artist, request.album);
|
NewClosure(reply, SIGNAL(finished()), this, SLOT(AlbumSongsReplyReceived(QNetworkReply*, const qint64, const QString&, const int, const QString&, const QString&)), reply, request.artist_id, request.album_id, request.offset, request.album_artist, request.album);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -726,6 +746,10 @@ void QobuzRequest::AlbumSongsReplyReceived(QNetworkReply *reply, const qint64 ar
|
|||||||
|
|
||||||
void QobuzRequest::SongsReceived(QNetworkReply *reply, const qint64 artist_id_requested, const QString &album_id_requested, const int limit_requested, const int offset_requested, const QString &album_artist_requested, const QString &album_requested) {
|
void QobuzRequest::SongsReceived(QNetworkReply *reply, const qint64 artist_id_requested, const QString &album_id_requested, const int limit_requested, const int offset_requested, const QString &album_artist_requested, const QString &album_requested) {
|
||||||
|
|
||||||
|
if (!replies_.contains(reply)) return;
|
||||||
|
replies_.removeAll(reply);
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
QByteArray data = GetReplyData(reply);
|
QByteArray data = GetReplyData(reply);
|
||||||
|
|
||||||
if (finished_) return;
|
if (finished_) return;
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ class QobuzRequest : public QobuzBaseRequest {
|
|||||||
SongList songs_;
|
SongList songs_;
|
||||||
QStringList errors_;
|
QStringList errors_;
|
||||||
bool no_results_;
|
bool no_results_;
|
||||||
|
QList<QNetworkReply*> replies_;
|
||||||
QList<QNetworkReply*> album_cover_replies_;
|
QList<QNetworkReply*> album_cover_replies_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -46,16 +46,7 @@ SubsonicBaseRequest::SubsonicBaseRequest(SubsonicService *service, NetworkAccess
|
|||||||
network_(network)
|
network_(network)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SubsonicBaseRequest::~SubsonicBaseRequest() {
|
SubsonicBaseRequest::~SubsonicBaseRequest() {}
|
||||||
|
|
||||||
while (!replies_.isEmpty()) {
|
|
||||||
QNetworkReply *reply = replies_.takeFirst();
|
|
||||||
disconnect(reply, 0, this, 0);
|
|
||||||
if (reply->isRunning()) reply->abort();
|
|
||||||
reply->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QUrl SubsonicBaseRequest::CreateUrl(const QString &ressource_name, const QList<Param> ¶ms_provided) {
|
QUrl SubsonicBaseRequest::CreateUrl(const QString &ressource_name, const QList<Param> ¶ms_provided) {
|
||||||
|
|
||||||
@@ -101,7 +92,6 @@ QNetworkReply *SubsonicBaseRequest::CreateGetRequest(const QString &ressource_na
|
|||||||
|
|
||||||
QNetworkReply *reply = network_->get(req);
|
QNetworkReply *reply = network_->get(req);
|
||||||
connect(reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(HandleSSLErrors(QList<QSslError>)));
|
connect(reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(HandleSSLErrors(QList<QSslError>)));
|
||||||
replies_ << reply;
|
|
||||||
|
|
||||||
//qLog(Debug) << "Subsonic: Sending request" << url;
|
//qLog(Debug) << "Subsonic: Sending request" << url;
|
||||||
|
|
||||||
@@ -119,11 +109,6 @@ void SubsonicBaseRequest::HandleSSLErrors(QList<QSslError> ssl_errors) {
|
|||||||
|
|
||||||
QByteArray SubsonicBaseRequest::GetReplyData(QNetworkReply *reply) {
|
QByteArray SubsonicBaseRequest::GetReplyData(QNetworkReply *reply) {
|
||||||
|
|
||||||
if (replies_.contains(reply)) {
|
|
||||||
replies_.removeAll(reply);
|
|
||||||
reply->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
|
|
||||||
if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200) {
|
if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200) {
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ class SubsonicBaseRequest : public QObject {
|
|||||||
|
|
||||||
SubsonicService *service_;
|
SubsonicService *service_;
|
||||||
NetworkAccessManager *network_;
|
NetworkAccessManager *network_;
|
||||||
QList<QNetworkReply*> replies_;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,13 @@ SubsonicRequest::SubsonicRequest(SubsonicService *service, SubsonicUrlHandler *u
|
|||||||
|
|
||||||
SubsonicRequest::~SubsonicRequest() {
|
SubsonicRequest::~SubsonicRequest() {
|
||||||
|
|
||||||
|
while (!replies_.isEmpty()) {
|
||||||
|
QNetworkReply *reply = replies_.takeFirst();
|
||||||
|
disconnect(reply, 0, this, 0);
|
||||||
|
if (reply->isRunning()) reply->abort();
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
while (!album_cover_replies_.isEmpty()) {
|
while (!album_cover_replies_.isEmpty()) {
|
||||||
QNetworkReply *reply = album_cover_replies_.takeFirst();
|
QNetworkReply *reply = album_cover_replies_.takeFirst();
|
||||||
disconnect(reply, 0, this, 0);
|
disconnect(reply, 0, this, 0);
|
||||||
@@ -99,6 +106,7 @@ void SubsonicRequest::Reset() {
|
|||||||
songs_.clear();
|
songs_.clear();
|
||||||
errors_.clear();
|
errors_.clear();
|
||||||
no_results_ = false;
|
no_results_ = false;
|
||||||
|
replies_.clear();
|
||||||
album_cover_replies_.clear();
|
album_cover_replies_.clear();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -134,6 +142,7 @@ void SubsonicRequest::FlushAlbumsRequests() {
|
|||||||
|
|
||||||
QNetworkReply *reply;
|
QNetworkReply *reply;
|
||||||
reply = CreateGetRequest(QString("getAlbumList2"), params);
|
reply = CreateGetRequest(QString("getAlbumList2"), params);
|
||||||
|
replies_ << reply;
|
||||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(AlbumsReplyReceived(QNetworkReply*, int)), reply, request.offset);
|
NewClosure(reply, SIGNAL(finished()), this, SLOT(AlbumsReplyReceived(QNetworkReply*, int)), reply, request.offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -142,6 +151,10 @@ void SubsonicRequest::FlushAlbumsRequests() {
|
|||||||
|
|
||||||
void SubsonicRequest::AlbumsReplyReceived(QNetworkReply *reply, const int offset_requested) {
|
void SubsonicRequest::AlbumsReplyReceived(QNetworkReply *reply, const int offset_requested) {
|
||||||
|
|
||||||
|
if (!replies_.contains(reply)) return;
|
||||||
|
replies_.removeAll(reply);
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
--albums_requests_active_;
|
--albums_requests_active_;
|
||||||
|
|
||||||
QByteArray data = GetReplyData(reply);
|
QByteArray data = GetReplyData(reply);
|
||||||
@@ -318,6 +331,7 @@ void SubsonicRequest::FlushAlbumSongsRequests() {
|
|||||||
++album_songs_requests_active_;
|
++album_songs_requests_active_;
|
||||||
ParamList params = ParamList() << Param("id", QString::number(request.album_id));
|
ParamList params = ParamList() << Param("id", QString::number(request.album_id));
|
||||||
QNetworkReply *reply = CreateGetRequest(QString("getAlbum"), params);
|
QNetworkReply *reply = CreateGetRequest(QString("getAlbum"), params);
|
||||||
|
replies_ << reply;
|
||||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(AlbumSongsReplyReceived(QNetworkReply*, const qint64, const qint64, const QString&)), reply, request.artist_id, request.album_id, request.album_artist);
|
NewClosure(reply, SIGNAL(finished()), this, SLOT(AlbumSongsReplyReceived(QNetworkReply*, const qint64, const qint64, const QString&)), reply, request.artist_id, request.album_id, request.album_artist);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -326,6 +340,10 @@ void SubsonicRequest::FlushAlbumSongsRequests() {
|
|||||||
|
|
||||||
void SubsonicRequest::AlbumSongsReplyReceived(QNetworkReply *reply, const qint64 artist_id, const qint64 album_id, const QString &album_artist) {
|
void SubsonicRequest::AlbumSongsReplyReceived(QNetworkReply *reply, const qint64 artist_id, const qint64 album_id, const QString &album_artist) {
|
||||||
|
|
||||||
|
if (!replies_.contains(reply)) return;
|
||||||
|
replies_.removeAll(reply);
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
--album_songs_requests_active_;
|
--album_songs_requests_active_;
|
||||||
++album_songs_received_;
|
++album_songs_received_;
|
||||||
|
|
||||||
@@ -719,4 +737,3 @@ void SubsonicRequest::Warn(const QString &error, const QVariant &debug) {
|
|||||||
if (debug.isValid()) qLog(Debug) << debug;
|
if (debug.isValid()) qLog(Debug) << debug;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ class SubsonicRequest : public SubsonicBaseRequest {
|
|||||||
SongList songs_;
|
SongList songs_;
|
||||||
QStringList errors_;
|
QStringList errors_;
|
||||||
bool no_results_;
|
bool no_results_;
|
||||||
|
QList<QNetworkReply*> replies_;
|
||||||
QList<QNetworkReply*> album_cover_replies_;
|
QList<QNetworkReply*> album_cover_replies_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -48,16 +48,7 @@ TidalBaseRequest::TidalBaseRequest(TidalService *service, NetworkAccessManager *
|
|||||||
network_(network)
|
network_(network)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
TidalBaseRequest::~TidalBaseRequest() {
|
TidalBaseRequest::~TidalBaseRequest() {}
|
||||||
|
|
||||||
while (!replies_.isEmpty()) {
|
|
||||||
QNetworkReply *reply = replies_.takeFirst();
|
|
||||||
disconnect(reply, 0, this, 0);
|
|
||||||
if (reply->isRunning()) reply->abort();
|
|
||||||
reply->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkReply *TidalBaseRequest::CreateRequest(const QString &ressource_name, const QList<Param> ¶ms_provided) {
|
QNetworkReply *TidalBaseRequest::CreateRequest(const QString &ressource_name, const QList<Param> ¶ms_provided) {
|
||||||
|
|
||||||
@@ -79,7 +70,6 @@ QNetworkReply *TidalBaseRequest::CreateRequest(const QString &ressource_name, co
|
|||||||
|
|
||||||
QNetworkReply *reply = network_->get(req);
|
QNetworkReply *reply = network_->get(req);
|
||||||
connect(reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(HandleSSLErrors(QList<QSslError>)));
|
connect(reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(HandleSSLErrors(QList<QSslError>)));
|
||||||
replies_ << reply;
|
|
||||||
|
|
||||||
//qLog(Debug) << "Tidal: Sending request" << url;
|
//qLog(Debug) << "Tidal: Sending request" << url;
|
||||||
|
|
||||||
@@ -97,11 +87,6 @@ void TidalBaseRequest::HandleSSLErrors(QList<QSslError> ssl_errors) {
|
|||||||
|
|
||||||
QByteArray TidalBaseRequest::GetReplyData(QNetworkReply *reply, const bool send_login) {
|
QByteArray TidalBaseRequest::GetReplyData(QNetworkReply *reply, const bool send_login) {
|
||||||
|
|
||||||
if (replies_.contains(reply)) {
|
|
||||||
replies_.removeAll(reply);
|
|
||||||
reply->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
|
|
||||||
if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200) {
|
if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 200) {
|
||||||
|
|||||||
@@ -112,7 +112,6 @@ class TidalBaseRequest : public QObject {
|
|||||||
|
|
||||||
TidalService *service_;
|
TidalService *service_;
|
||||||
NetworkAccessManager *network_;
|
NetworkAccessManager *network_;
|
||||||
QList<QNetworkReply*> replies_;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,13 @@ TidalRequest::TidalRequest(TidalService *service, TidalUrlHandler *url_handler,
|
|||||||
|
|
||||||
TidalRequest::~TidalRequest() {
|
TidalRequest::~TidalRequest() {
|
||||||
|
|
||||||
|
while (!replies_.isEmpty()) {
|
||||||
|
QNetworkReply *reply = replies_.takeFirst();
|
||||||
|
disconnect(reply, 0, this, 0);
|
||||||
|
if (reply->isRunning()) reply->abort();
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
while (!album_cover_replies_.isEmpty()) {
|
while (!album_cover_replies_.isEmpty()) {
|
||||||
QNetworkReply *reply = album_cover_replies_.takeFirst();
|
QNetworkReply *reply = album_cover_replies_.takeFirst();
|
||||||
disconnect(reply, 0, this, 0);
|
disconnect(reply, 0, this, 0);
|
||||||
@@ -177,6 +184,8 @@ void TidalRequest::FlushArtistsRequests() {
|
|||||||
if (type_ == QueryType_SearchArtists) {
|
if (type_ == QueryType_SearchArtists) {
|
||||||
reply = CreateRequest("search/artists", parameters);
|
reply = CreateRequest("search/artists", parameters);
|
||||||
}
|
}
|
||||||
|
if (!reply) continue;
|
||||||
|
replies_ << reply;
|
||||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(ArtistsReplyReceived(QNetworkReply*, const int, const int)), reply, request.limit, request.offset);
|
NewClosure(reply, SIGNAL(finished()), this, SLOT(ArtistsReplyReceived(QNetworkReply*, const int, const int)), reply, request.limit, request.offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -219,6 +228,8 @@ void TidalRequest::FlushAlbumsRequests() {
|
|||||||
if (type_ == QueryType_SearchAlbums) {
|
if (type_ == QueryType_SearchAlbums) {
|
||||||
reply = CreateRequest("search/albums", parameters);
|
reply = CreateRequest("search/albums", parameters);
|
||||||
}
|
}
|
||||||
|
if (!reply) continue;
|
||||||
|
replies_ << reply;
|
||||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(AlbumsReplyReceived(QNetworkReply*, const int, const int)), reply, request.limit, request.offset);
|
NewClosure(reply, SIGNAL(finished()), this, SLOT(AlbumsReplyReceived(QNetworkReply*, const int, const int)), reply, request.limit, request.offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -261,6 +272,8 @@ void TidalRequest::FlushSongsRequests() {
|
|||||||
if (type_ == QueryType_SearchSongs) {
|
if (type_ == QueryType_SearchSongs) {
|
||||||
reply = CreateRequest("search/tracks", parameters);
|
reply = CreateRequest("search/tracks", parameters);
|
||||||
}
|
}
|
||||||
|
if (!reply) continue;
|
||||||
|
replies_ << reply;
|
||||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(SongsReplyReceived(QNetworkReply*, const int, const int)), reply, request.limit, request.offset);
|
NewClosure(reply, SIGNAL(finished()), this, SLOT(SongsReplyReceived(QNetworkReply*, const int, const int)), reply, request.limit, request.offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -311,6 +324,10 @@ void TidalRequest::AddSongsSearchRequest(const int offset) {
|
|||||||
|
|
||||||
void TidalRequest::ArtistsReplyReceived(QNetworkReply *reply, const int limit_requested, const int offset_requested) {
|
void TidalRequest::ArtistsReplyReceived(QNetworkReply *reply, const int limit_requested, const int offset_requested) {
|
||||||
|
|
||||||
|
if (!replies_.contains(reply)) return;
|
||||||
|
replies_.removeAll(reply);
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
QByteArray data = GetReplyData(reply, (offset_requested == 0));
|
QByteArray data = GetReplyData(reply, (offset_requested == 0));
|
||||||
|
|
||||||
--artists_requests_active_;
|
--artists_requests_active_;
|
||||||
@@ -474,6 +491,7 @@ void TidalRequest::FlushArtistAlbumsRequests() {
|
|||||||
if (request.offset > 0) parameters << Param("offset", QString::number(request.offset));
|
if (request.offset > 0) parameters << Param("offset", QString::number(request.offset));
|
||||||
QNetworkReply *reply = CreateRequest(QString("artists/%1/albums").arg(request.artist_id), parameters);
|
QNetworkReply *reply = CreateRequest(QString("artists/%1/albums").arg(request.artist_id), parameters);
|
||||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(ArtistAlbumsReplyReceived(QNetworkReply*, const qint64, const int)), reply, request.artist_id, request.offset);
|
NewClosure(reply, SIGNAL(finished()), this, SLOT(ArtistAlbumsReplyReceived(QNetworkReply*, const qint64, const int)), reply, request.artist_id, request.offset);
|
||||||
|
replies_ << reply;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,6 +509,10 @@ void TidalRequest::ArtistAlbumsReplyReceived(QNetworkReply *reply, const qint64
|
|||||||
|
|
||||||
void TidalRequest::AlbumsReceived(QNetworkReply *reply, const qint64 artist_id_requested, const int limit_requested, const int offset_requested, const bool auto_login) {
|
void TidalRequest::AlbumsReceived(QNetworkReply *reply, const qint64 artist_id_requested, const int limit_requested, const int offset_requested, const bool auto_login) {
|
||||||
|
|
||||||
|
if (!replies_.contains(reply)) return;
|
||||||
|
replies_.removeAll(reply);
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
QByteArray data = GetReplyData(reply, auto_login);
|
QByteArray data = GetReplyData(reply, auto_login);
|
||||||
|
|
||||||
if (finished_) return;
|
if (finished_) return;
|
||||||
@@ -717,6 +739,7 @@ void TidalRequest::FlushAlbumSongsRequests() {
|
|||||||
ParamList parameters;
|
ParamList parameters;
|
||||||
if (request.offset > 0) parameters << Param("offset", QString::number(request.offset));
|
if (request.offset > 0) parameters << Param("offset", QString::number(request.offset));
|
||||||
QNetworkReply *reply = CreateRequest(QString("albums/%1/tracks").arg(request.album_id), parameters);
|
QNetworkReply *reply = CreateRequest(QString("albums/%1/tracks").arg(request.album_id), parameters);
|
||||||
|
replies_ << reply;
|
||||||
NewClosure(reply, SIGNAL(finished()), this, SLOT(AlbumSongsReplyReceived(QNetworkReply*, const qint64, const qint64, const int, const QString&)), reply, request.artist_id, request.album_id, request.offset, request.album_artist);
|
NewClosure(reply, SIGNAL(finished()), this, SLOT(AlbumSongsReplyReceived(QNetworkReply*, const qint64, const qint64, const int, const QString&)), reply, request.artist_id, request.album_id, request.offset, request.album_artist);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -736,6 +759,10 @@ void TidalRequest::AlbumSongsReplyReceived(QNetworkReply *reply, const qint64 ar
|
|||||||
|
|
||||||
void TidalRequest::SongsReceived(QNetworkReply *reply, const qint64 artist_id, const qint64 album_id, const int limit_requested, const int offset_requested, const bool auto_login, const QString &album_artist) {
|
void TidalRequest::SongsReceived(QNetworkReply *reply, const qint64 artist_id, const qint64 album_id, const int limit_requested, const int offset_requested, const bool auto_login, const QString &album_artist) {
|
||||||
|
|
||||||
|
if (!replies_.contains(reply)) return;
|
||||||
|
replies_.removeAll(reply);
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
QByteArray data = GetReplyData(reply, auto_login);
|
QByteArray data = GetReplyData(reply, auto_login);
|
||||||
|
|
||||||
if (finished_) return;
|
if (finished_) return;
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ class TidalRequest : public TidalBaseRequest {
|
|||||||
QStringList errors_;
|
QStringList errors_;
|
||||||
bool need_login_;
|
bool need_login_;
|
||||||
bool no_results_;
|
bool no_results_;
|
||||||
|
QList<QNetworkReply*> replies_;
|
||||||
QList<QNetworkReply*> album_cover_replies_;
|
QList<QNetworkReply*> album_cover_replies_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user