From c0c4da1bc3b2d41e2d95300a7ee03ae8bd71a152 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Wed, 9 Sep 2020 17:04:43 +0200 Subject: [PATCH] Fallback: Parse "artist-title" with a single dash from file name As requested and suggested on Discourse: https://mixxx.discourse.group/t/metadata-from-filename-not-creating-artist-title/19901 --- src/test/trackmetadata_test.cpp | 48 +++++++++++++++++++++++------ src/track/trackinfo.cpp | 53 +++++++++++++++++++-------------- src/track/trackinfo.h | 2 +- 3 files changed, 70 insertions(+), 33 deletions(-) diff --git a/src/test/trackmetadata_test.cpp b/src/test/trackmetadata_test.cpp index aec136ab0c2..51f2e2286c3 100644 --- a/src/test/trackmetadata_test.cpp +++ b/src/test/trackmetadata_test.cpp @@ -14,19 +14,19 @@ TEST_F(TrackMetadataTest, parseArtistTitleFromFileName) { } { mixxx::TrackInfo trackInfo; - trackInfo.parseArtistTitleFromFileName(" only-title ", true); - EXPECT_EQ(QString(), trackInfo.getArtist()); - EXPECT_EQ("only-title", trackInfo.getTitle()); + trackInfo.parseArtistTitleFromFileName(" artist-title ", true); + EXPECT_EQ("artist", trackInfo.getArtist()); + EXPECT_EQ("title", trackInfo.getTitle()); } { mixxx::TrackInfo trackInfo; - trackInfo.parseArtistTitleFromFileName(" only -_title ", true); - EXPECT_EQ(QString(), trackInfo.getArtist()); - EXPECT_EQ("only -_title", trackInfo.getTitle()); + trackInfo.parseArtistTitleFromFileName(" artist -_title ", true); + EXPECT_EQ("artist", trackInfo.getArtist()); + EXPECT_EQ("_title", trackInfo.getTitle()); } { mixxx::TrackInfo trackInfo; - trackInfo.parseArtistTitleFromFileName(" only - title ", false); + trackInfo.parseArtistTitleFromFileName(" only - title.mp3", false); EXPECT_EQ(QString(), trackInfo.getArtist()); EXPECT_EQ("only - title", trackInfo.getTitle()); } @@ -38,9 +38,39 @@ TEST_F(TrackMetadataTest, parseArtistTitleFromFileName) { } { mixxx::TrackInfo trackInfo; - trackInfo.parseArtistTitleFromFileName(" only -\ttitle\t", true); + trackInfo.parseArtistTitleFromFileName(" ar.tist -\tti.tle\t.mp3", true); + EXPECT_EQ("ar.tist", trackInfo.getArtist()); + EXPECT_EQ("ti.tle", trackInfo.getTitle()); + } + { + mixxx::TrackInfo trackInfo; + trackInfo.parseArtistTitleFromFileName(" -artist - -title-.mp3", true); + EXPECT_EQ("-artist", trackInfo.getArtist()); + EXPECT_EQ("-title-", trackInfo.getTitle()); + } + { + mixxx::TrackInfo trackInfo; + trackInfo.parseArtistTitleFromFileName(" -artist ti-tle- ", true); EXPECT_EQ(QString(), trackInfo.getArtist()); - EXPECT_EQ("only -\ttitle", trackInfo.getTitle()); + EXPECT_EQ("-artist ti-tle-", trackInfo.getTitle()); + } + { + mixxx::TrackInfo trackInfo; + trackInfo.parseArtistTitleFromFileName(" artist- title ", true); + EXPECT_EQ("artist", trackInfo.getArtist()); + EXPECT_EQ("title", trackInfo.getTitle()); + } + { + mixxx::TrackInfo trackInfo; + trackInfo.parseArtistTitleFromFileName(" artist- ", true); + EXPECT_EQ("artist", trackInfo.getArtist()); + EXPECT_EQ(QString(), trackInfo.getTitle()); + } + { + mixxx::TrackInfo trackInfo; + trackInfo.parseArtistTitleFromFileName(" -title ", true); + EXPECT_EQ(QString(), trackInfo.getArtist()); + EXPECT_EQ("title", trackInfo.getTitle()); } { mixxx::TrackInfo trackInfo; diff --git a/src/track/trackinfo.cpp b/src/track/trackinfo.cpp index 14f33f2e4d9..3d843634bd0 100644 --- a/src/track/trackinfo.cpp +++ b/src/track/trackinfo.cpp @@ -1,41 +1,48 @@ #include "track/trackinfo.h" - -namespace mixxx { +#include namespace { +const QString kDefaultArtistTitleSeparator = QStringLiteral("_-_"); const QString kArtistTitleSeparatorWithSpaces = QStringLiteral(" - "); -const QString kArtistTitleSeparator = QStringLiteral("_-_"); - -const QChar kFileExtensionSeparator = '.'; +const QChar kFallbackArtistTitleSeparator = QChar('-'); } // anonymous namespace +namespace mixxx { + bool TrackInfo::parseArtistTitleFromFileName( - QString fileName, + const QString& fileName, bool splitArtistTitle) { bool modified = false; - fileName = fileName.trimmed(); - auto titleWithFileType = fileName; + auto title = QFileInfo(fileName).completeBaseName().trimmed(); if (splitArtistTitle) { - fileName.replace(kArtistTitleSeparatorWithSpaces, kArtistTitleSeparator); - if (fileName.count(kArtistTitleSeparator) == 1) { - auto artist = fileName.section(kArtistTitleSeparator, 0, 0).trimmed(); - if (!artist.isEmpty()) { - setArtist(artist); - modified = true; - } - titleWithFileType = fileName.section(kArtistTitleSeparator, 1).trimmed(); + QString artist; + // Preprocessing for disambiguation + auto splitArtist = title; + splitArtist.replace(kArtistTitleSeparatorWithSpaces, kDefaultArtistTitleSeparator); + // Splitting + QString artistTitleSeparator; + if (splitArtist.count(kDefaultArtistTitleSeparator) == 1) { + artistTitleSeparator = kDefaultArtistTitleSeparator; + } else if (splitArtist.count(kFallbackArtistTitleSeparator) == 1) { + artistTitleSeparator = kFallbackArtistTitleSeparator; + } + if (!artistTitleSeparator.isEmpty()) { + const int splitPos = splitArtist.indexOf(artistTitleSeparator); + DEBUG_ASSERT(splitPos >= 0); + DEBUG_ASSERT(splitPos == splitArtist.lastIndexOf(artistTitleSeparator)); + artist = splitArtist.left(splitPos).trimmed(); + const auto rightLen = splitArtist.size() - (splitPos + artistTitleSeparator.size()); + title = splitArtist.right(rightLen).trimmed(); + } + if (!artist.isEmpty() && artist != getArtist()) { + setArtist(artist); + modified = true; } } - auto title = titleWithFileType; - if (titleWithFileType.contains(kFileExtensionSeparator)) { - // Strip file extension starting at the right-most '.' - title = titleWithFileType.section(kFileExtensionSeparator, 0, -2); - } - title = title.trimmed(); - if (!title.isEmpty()) { + if (!title.isEmpty() && title != getTitle()) { setTitle(title); modified = true; } diff --git a/src/track/trackinfo.h b/src/track/trackinfo.h index 3315244ad49..9ab4269390a 100644 --- a/src/track/trackinfo.h +++ b/src/track/trackinfo.h @@ -66,7 +66,7 @@ class TrackInfo final { // Returns true if modified bool parseArtistTitleFromFileName( - QString fileName, + const QString& fileName, bool splitArtistTitle); // Adjusts floating-point properties to match their string representation