Compare commits

...

11 Commits
1.2.2 ... 1.1

Author SHA1 Message Date
Jonas Kvinge
b4683db900 Turn on git revision 2024-09-21 23:11:03 +02:00
Jonas Kvinge
5a90643ba8 Release 1.1.3 2024-09-21 22:12:57 +02:00
Jonas Kvinge
4a1ab2f004 CI: Upload PPA on 1.1 branch 2024-09-21 22:07:15 +02:00
Jonas Kvinge
36be755a78 filterparser: Optimize filter term
Fixes #1536
2024-09-21 21:55:46 +02:00
Jonas Kvinge
ffd8c88b1f FilterParser: Add check for empty column 2024-09-21 21:45:33 +02:00
Jonas Kvinge
84ff163b34 appdata: Update description 2024-09-21 21:31:17 +02:00
Jonas Kvinge
811e625618 GeniusLyricsProvider: Convert client ID and secret from base64
Fixes #1554
2024-09-21 21:31:05 +02:00
Jonas Kvinge
037b0d7dea CI: Fix source upload path 2024-09-21 21:30:44 +02:00
Jonas Kvinge
d578d3c66d GstEngine: Don't set state to play if already playing 2024-09-21 21:30:31 +02:00
Jonas Kvinge
2644dbd5ab GstEngine: Use beginning nanosec on play
Fixes #1549
2024-09-21 21:30:18 +02:00
Jonas Kvinge
245103dc30 SpotifySettingsPage: Fix gst reg lookup leak 2024-09-21 21:29:28 +02:00
10 changed files with 134 additions and 113 deletions

View File

@@ -628,7 +628,7 @@ jobs:
upload-ubuntu-ppa:
name: Upload Ubuntu PPA
if: github.repository == 'strawberrymusicplayer/strawberry' && github.event.pull_request.head.repo.fork == false && (github.event_name == 'release' || (github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/ci')))
if: github.repository == 'strawberrymusicplayer/strawberry' && github.event.pull_request.head.repo.fork == false && (github.event_name == 'release' || (github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/ci' || github.ref == 'refs/heads/1.1')))
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -1548,7 +1548,7 @@ jobs:
upload_path="${{secrets.RELEASES_PATH}}/"
else
distro=$(echo "$i" | cut -d '/' -f 2)
if [ "$(echo "$i" | grep '-' || true)" = "" ]; then
if [ -z "$(echo "${distro}" | grep '-' || true)" ]; then
upload_path="${{secrets.BUILDS_PATH}}/${distro}/"
else
distro_name=$(echo "${distro}" | cut -d '-' -f 1)

View File

@@ -2,6 +2,15 @@ Strawberry Music Player
=======================
ChangeLog
Version 1.1.3 (2024.09.21):
Bugfixes:
* Fixed gstreamer registry lookup leak in Spotify settings.
* Fixed all songs in a CUE sheet starting playback at the zero position (#1549).
* Fixed playback going to pause and back to play on song change.
* Fixed Genius Lyrics login not working (#1554).
* Fixed slow collection filter search.
Version 1.1.2 (2024.09.12):
Bugfixes:

View File

@@ -1,6 +1,6 @@
set(STRAWBERRY_VERSION_MAJOR 1)
set(STRAWBERRY_VERSION_MINOR 1)
set(STRAWBERRY_VERSION_PATCH 2)
set(STRAWBERRY_VERSION_PATCH 3)
#set(STRAWBERRY_VERSION_PRERELEASE rc1)
set(INCLUDE_GIT_REVISION ON)

View File

@@ -19,7 +19,7 @@
<content_rating type="oars-1.1" />
<description>
<p>
Strawberry is a music player and music collection organizer. It is aimed at music collectors and audiophiles. With Strawberry you can play and manage your digital music collection, or stream your favorite radios. It also has unofficial streaming support for Tidal and Qobuz. Strawberry is free software released under GPL. The source code is available on GitHub. It's written in C++ using the Qt toolkit and GStreamer. Strawberry is compatible with both Qt version 5 and 6.
Strawberry is a music player and music collection organizer. It is aimed at music collectors and audiophiles. Strawberry is free software released under GPL. It's written in C++ using the Qt framework and GStreamer.
</p>
<p>Features:</p>
<ul>
@@ -52,6 +52,7 @@
</screenshots>
<update_contact>eclipseo@fedoraproject.org</update_contact>
<releases>
<release version="1.1.3" date="2024-09-21"/>
<release version="1.1.2" date="2024-09-12"/>
<release version="1.1.1" date="2024-07-22"/>
<release version="1.1.0" date="2024-07-14"/>

View File

@@ -259,7 +259,7 @@ bool GstEngine::Play(const bool pause, const quint64 offset_nanosec) {
EnsureInitialized();
if (!current_pipeline_ || current_pipeline_->is_buffering()) return false;
if (!current_pipeline_ || current_pipeline_->is_buffering() || current_pipeline_->state() == GstState::GST_STATE_PLAYING) return false;
if (OldExclusivePipelineActive()) {
qLog(Debug) << "Delaying play because a exclusive pipeline is already active...";
@@ -284,7 +284,7 @@ bool GstEngine::Play(const bool pause, const quint64 offset_nanosec) {
watcher->deleteLater();
PlayDone(ret, pause, offset_nanosec, pipeline_id);
});
QFuture<GstStateChangeReturn> future = current_pipeline_->Play(pause, offset_nanosec);
QFuture<GstStateChangeReturn> future = current_pipeline_->Play(pause, beginning_nanosec_ + offset_nanosec);
watcher->setFuture(future);
return true;

View File

@@ -235,123 +235,125 @@ FilterTree *FilterParser::createSearchTermTreeNode(const QString &column, const
FilterParserSearchTermComparator *cmp = nullptr;
if (Song::kTextSearchColumns.contains(column, Qt::CaseInsensitive)) {
if (prefix == QLatin1Char('=') || prefix == QLatin1String("==")) {
cmp = new FilterParserTextEqComparator(value);
}
else if (prefix == QLatin1String("!=") || prefix == QLatin1String("<>")) {
cmp = new FilterParserTextNeComparator(value);
}
else {
cmp = new FilterParserDefaultComparator(value);
}
}
else if (Song::kIntSearchColumns.contains(column, Qt::CaseInsensitive)) {
bool ok = false;
int number = value.toInt(&ok);
if (ok) {
if (!column.isEmpty()) {
if (Song::kTextSearchColumns.contains(column, Qt::CaseInsensitive)) {
if (prefix == QLatin1Char('=') || prefix == QLatin1String("==")) {
cmp = new FilterParserIntEqComparator(number);
cmp = new FilterParserTextEqComparator(value);
}
else if (prefix == QLatin1String("!=") || prefix == QLatin1String("<>")) {
cmp = new FilterParserIntNeComparator(number);
}
else if (prefix == QLatin1Char('>')) {
cmp = new FilterParserIntGtComparator(number);
}
else if (prefix == QLatin1String(">=")) {
cmp = new FilterParserIntGeComparator(number);
}
else if (prefix == QLatin1Char('<')) {
cmp = new FilterParserIntLtComparator(number);
}
else if (prefix == QLatin1String("<=")) {
cmp = new FilterParserIntLeComparator(number);
cmp = new FilterParserTextNeComparator(value);
}
else {
cmp = new FilterParserIntEqComparator(number);
cmp = new FilterParserTextContainsComparator(value);
}
}
}
else if (Song::kUIntSearchColumns.contains(column, Qt::CaseInsensitive)) {
bool ok = false;
uint number = value.toUInt(&ok);
if (ok) {
else if (Song::kIntSearchColumns.contains(column, Qt::CaseInsensitive)) {
bool ok = false;
int number = value.toInt(&ok);
if (ok) {
if (prefix == QLatin1Char('=') || prefix == QLatin1String("==")) {
cmp = new FilterParserIntEqComparator(number);
}
else if (prefix == QLatin1String("!=") || prefix == QLatin1String("<>")) {
cmp = new FilterParserIntNeComparator(number);
}
else if (prefix == QLatin1Char('>')) {
cmp = new FilterParserIntGtComparator(number);
}
else if (prefix == QLatin1String(">=")) {
cmp = new FilterParserIntGeComparator(number);
}
else if (prefix == QLatin1Char('<')) {
cmp = new FilterParserIntLtComparator(number);
}
else if (prefix == QLatin1String("<=")) {
cmp = new FilterParserIntLeComparator(number);
}
else {
cmp = new FilterParserTextContainsComparator(value);
}
}
}
else if (Song::kUIntSearchColumns.contains(column, Qt::CaseInsensitive)) {
bool ok = false;
uint number = value.toUInt(&ok);
if (ok) {
if (prefix == QLatin1Char('=') || prefix == QLatin1String("==")) {
cmp = new FilterParserUIntEqComparator(number);
}
else if (prefix == QLatin1String("!=") || prefix == QLatin1String("<>")) {
cmp = new FilterParserUIntNeComparator(number);
}
else if (prefix == QLatin1Char('>')) {
cmp = new FilterParserUIntGtComparator(number);
}
else if (prefix == QLatin1String(">=")) {
cmp = new FilterParserUIntGeComparator(number);
}
else if (prefix == QLatin1Char('<')) {
cmp = new FilterParserUIntLtComparator(number);
}
else if (prefix == QLatin1String("<=")) {
cmp = new FilterParserUIntLeComparator(number);
}
else {
cmp = new FilterParserInt64EqComparator(number);
}
}
}
else if (Song::kInt64SearchColumns.contains(column, Qt::CaseInsensitive)) {
qint64 number = 0;
if (column == QLatin1String("length")) {
number = ParseTime(value);
}
else {
number = value.toLongLong();
}
if (prefix == QLatin1Char('=') || prefix == QLatin1String("==")) {
cmp = new FilterParserUIntEqComparator(number);
cmp = new FilterParserInt64EqComparator(number);
}
else if (prefix == QLatin1String("!=") || prefix == QLatin1String("<>")) {
cmp = new FilterParserUIntNeComparator(number);
cmp = new FilterParserInt64NeComparator(number);
}
else if (prefix == QLatin1Char('>')) {
cmp = new FilterParserUIntGtComparator(number);
cmp = new FilterParserInt64GtComparator(number);
}
else if (prefix == QLatin1String(">=")) {
cmp = new FilterParserUIntGeComparator(number);
cmp = new FilterParserInt64GeComparator(number);
}
else if (prefix == QLatin1Char('<')) {
cmp = new FilterParserUIntLtComparator(number);
cmp = new FilterParserInt64LtComparator(number);
}
else if (prefix == QLatin1String("<=")) {
cmp = new FilterParserUIntLeComparator(number);
cmp = new FilterParserInt64LeComparator(number);
}
else {
cmp = new FilterParserUIntEqComparator(number);
cmp = new FilterParserInt64EqComparator(number);
}
}
}
else if (Song::kInt64SearchColumns.contains(column, Qt::CaseInsensitive)) {
qint64 number = 0;
if (column == QLatin1String("length")) {
number = ParseTime(value);
}
else {
number = value.toLongLong();
}
if (prefix == QLatin1Char('=') || prefix == QLatin1String("==")) {
cmp = new FilterParserInt64EqComparator(number);
}
else if (prefix == QLatin1String("!=") || prefix == QLatin1String("<>")) {
cmp = new FilterParserInt64NeComparator(number);
}
else if (prefix == QLatin1Char('>')) {
cmp = new FilterParserInt64GtComparator(number);
}
else if (prefix == QLatin1String(">=")) {
cmp = new FilterParserInt64GeComparator(number);
}
else if (prefix == QLatin1Char('<')) {
cmp = new FilterParserInt64LtComparator(number);
}
else if (prefix == QLatin1String("<=")) {
cmp = new FilterParserInt64LeComparator(number);
}
else {
cmp = new FilterParserInt64EqComparator(number);
}
}
else if (Song::kFloatSearchColumns.contains(column, Qt::CaseInsensitive)) {
const float rating = ParseRating(value);
if (prefix == QLatin1Char('=') || prefix == QLatin1String("==")) {
cmp = new FilterParserFloatEqComparator(rating);
}
else if (prefix == QLatin1String("!=") || prefix == QLatin1String("<>")) {
cmp = new FilterParserFloatNeComparator(rating);
}
else if (prefix == QLatin1Char('>')) {
cmp = new FilterParserFloatGtComparator(rating);
}
else if (prefix == QLatin1String(">=")) {
cmp = new FilterParserFloatGeComparator(rating);
}
else if (prefix == QLatin1Char('<')) {
cmp = new FilterParserFloatLtComparator(rating);
}
else if (prefix == QLatin1String("<=")) {
cmp = new FilterParserFloatLeComparator(rating);
}
else {
cmp = new FilterParserFloatEqComparator(rating);
else if (Song::kFloatSearchColumns.contains(column, Qt::CaseInsensitive)) {
const float rating = ParseRating(value);
if (prefix == QLatin1Char('=') || prefix == QLatin1String("==")) {
cmp = new FilterParserFloatEqComparator(rating);
}
else if (prefix == QLatin1String("!=") || prefix == QLatin1String("<>")) {
cmp = new FilterParserFloatNeComparator(rating);
}
else if (prefix == QLatin1Char('>')) {
cmp = new FilterParserFloatGtComparator(rating);
}
else if (prefix == QLatin1String(">=")) {
cmp = new FilterParserFloatGeComparator(rating);
}
else if (prefix == QLatin1Char('<')) {
cmp = new FilterParserFloatLtComparator(rating);
}
else if (prefix == QLatin1String("<=")) {
cmp = new FilterParserFloatLeComparator(rating);
}
else {
cmp = new FilterParserFloatEqComparator(rating);
}
}
}
@@ -359,7 +361,7 @@ FilterTree *FilterParser::createSearchTermTreeNode(const QString &column, const
return new FilterColumnTerm(column, cmp);
}
return new FilterTerm(Song::kTextSearchColumns, new FilterParserDefaultComparator(value));
return new FilterTerm(new FilterParserTextContainsComparator(value));
}

View File

@@ -38,16 +38,16 @@ class FilterParserSearchTermComparator {
};
// "compares" by checking if the field contains the search term
class FilterParserDefaultComparator : public FilterParserSearchTermComparator {
class FilterParserTextContainsComparator : public FilterParserSearchTermComparator {
public:
explicit FilterParserDefaultComparator(const QString &search_term) : search_term_(search_term) {}
explicit FilterParserTextContainsComparator(const QString &search_term) : search_term_(search_term) {}
bool Matches(const QVariant &value) const override {
return value.toString().contains(search_term_, Qt::CaseInsensitive);
}
private:
QString search_term_;
Q_DISABLE_COPY(FilterParserDefaultComparator)
Q_DISABLE_COPY(FilterParserTextContainsComparator)
};
class FilterParserTextEqComparator : public FilterParserSearchTermComparator {

View File

@@ -67,19 +67,27 @@ class NopFilter : public FilterTree {
// Filter that applies a SearchTermComparator to all fields
class FilterTerm : public FilterTree {
public:
explicit FilterTerm(const QStringList &columns, FilterParserSearchTermComparator *comparator) : columns_(columns), cmp_(comparator) {}
explicit FilterTerm(FilterParserSearchTermComparator *comparator) : cmp_(comparator) {}
FilterType type() const override { return FilterType::Term; }
bool accept(const Song &song) const override {
for (const QString &column : columns_) {
if (cmp_->Matches(DataFromColumn(column, song))) return true;
}
if (cmp_->Matches(song.PrettyTitle())) return true;
if (cmp_->Matches(song.album())) return true;
if (cmp_->Matches(song.artist())) return true;
if (cmp_->Matches(song.albumartist())) return true;
if (cmp_->Matches(song.composer())) return true;
if (cmp_->Matches(song.performer())) return true;
if (cmp_->Matches(song.grouping())) return true;
if (cmp_->Matches(song.genre())) return true;
if (cmp_->Matches(song.comment())) return true;
return false;
}
private:
const QStringList columns_;
QScopedPointer<FilterParserSearchTermComparator> cmp_;
};

View File

@@ -133,7 +133,7 @@ void GeniusLyricsProvider::Authenticate() {
}
QUrlQuery url_query;
url_query.addQueryItem(QStringLiteral("client_id"), QString::fromLatin1(QUrl::toPercentEncoding(QLatin1String(kClientIDB64))));
url_query.addQueryItem(QStringLiteral("client_id"), QString::fromLatin1(QUrl::toPercentEncoding(QString::fromLatin1(QByteArray::fromBase64(kClientIDB64)))));
url_query.addQueryItem(QStringLiteral("redirect_uri"), QString::fromLatin1(QUrl::toPercentEncoding(redirect_url.toString())));
url_query.addQueryItem(QStringLiteral("scope"), QStringLiteral("me"));
url_query.addQueryItem(QStringLiteral("state"), QString::fromLatin1(QUrl::toPercentEncoding(code_challenge_)));
@@ -197,8 +197,8 @@ void GeniusLyricsProvider::RequestAccessToken(const QUrl &url, const QUrl &redir
QUrlQuery new_url_query;
new_url_query.addQueryItem(QStringLiteral("code"), QString::fromLatin1(QUrl::toPercentEncoding(code)));
new_url_query.addQueryItem(QStringLiteral("client_id"), QString::fromLatin1(QUrl::toPercentEncoding(QLatin1String(kClientIDB64))));
new_url_query.addQueryItem(QStringLiteral("client_secret"), QString::fromLatin1(QUrl::toPercentEncoding(QLatin1String(kClientSecretB64))));
new_url_query.addQueryItem(QStringLiteral("client_id"), QString::fromLatin1(QUrl::toPercentEncoding(QString::fromLatin1(QByteArray::fromBase64(kClientIDB64)))));
new_url_query.addQueryItem(QStringLiteral("client_secret"), QString::fromLatin1(QUrl::toPercentEncoding(QString::fromLatin1(QByteArray::fromBase64(kClientSecretB64)))));
new_url_query.addQueryItem(QStringLiteral("redirect_uri"), QString::fromLatin1(QUrl::toPercentEncoding(redirect_url.toString())));
new_url_query.addQueryItem(QStringLiteral("grant_type"), QStringLiteral("authorization_code"));
new_url_query.addQueryItem(QStringLiteral("response_type"), QStringLiteral("code"));

View File

@@ -69,6 +69,7 @@ SpotifySettingsPage::SpotifySettingsPage(SettingsDialog *dialog, QWidget *parent
if (reg) {
GstPluginFeature *spotifyaudiosrc = gst_registry_lookup_feature(reg, "spotifyaudiosrc");
if (spotifyaudiosrc) {
gst_object_unref(spotifyaudiosrc);
ui_->widget_warning->hide();
}
else {