From 7795b9edaf31edd125360a16f49e4410b850fa44 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Wed, 20 Nov 2019 19:34:57 +0100 Subject: [PATCH] Dont replace metadata when loading playlists --- src/core/songloader.cpp | 2 +- src/core/utilities.cpp | 20 +++++++++++++++ src/core/utilities.h | 1 + src/playlistparsers/asxparser.cpp | 41 +++++++++++++----------------- src/playlistparsers/m3uparser.cpp | 2 ++ src/playlistparsers/parserbase.cpp | 2 +- src/playlistparsers/xmlparser.cpp | 1 - src/playlistparsers/xspfparser.cpp | 13 ++++++---- 8 files changed, 51 insertions(+), 31 deletions(-) diff --git a/src/core/songloader.cpp b/src/core/songloader.cpp index fb4efdab6..191de7b37 100644 --- a/src/core/songloader.cpp +++ b/src/core/songloader.cpp @@ -228,7 +228,7 @@ SongLoader::Result SongLoader::LoadLocal(const QString &filename) { if (collection_->ExecQuery(&query) && query.Next()) { // We may have many results when the file has many sections do { - Song song(Song::Source_LocalFile); + Song song(Song::Source_Collection); song.InitFromQuery(query, true); if (song.is_valid()) { diff --git a/src/core/utilities.cpp b/src/core/utilities.cpp index 05edaff87..60a8a878f 100644 --- a/src/core/utilities.cpp +++ b/src/core/utilities.cpp @@ -514,6 +514,26 @@ bool ParseUntilElement(QXmlStreamReader *reader, const QString &name) { } +bool ParseUntilElementCI(QXmlStreamReader *reader, const QString &name) { + + while (!reader->atEnd()) { + QXmlStreamReader::TokenType type = reader->readNext(); + switch (type) { + case QXmlStreamReader::StartElement:{ + QString element = reader->name().toString().toLower(); + if (element == name) { + return true; + } + break; + } + default: + break; + } + } + return false; + +} + QDateTime ParseRFC822DateTime(const QString &text) { QRegExp regexp("(\\d{1,2}) (\\w{3,12}) (\\d+) (\\d{1,2}):(\\d{1,2}):(\\d{1,2})"); diff --git a/src/core/utilities.h b/src/core/utilities.h index 870652b2d..54717eca9 100644 --- a/src/core/utilities.h +++ b/src/core/utilities.h @@ -96,6 +96,7 @@ void ConsumeCurrentElement(QXmlStreamReader *reader); // Advances the stream reader until it finds an element with the given name. // Returns false if the end of the document was reached before finding a matching element. bool ParseUntilElement(QXmlStreamReader *reader, const QString &name); +bool ParseUntilElementCI(QXmlStreamReader *reader, const QString &name); // Parses a string containing an RFC822 time and date. QDateTime ParseRFC822DateTime(const QString &text); diff --git a/src/playlistparsers/asxparser.cpp b/src/playlistparsers/asxparser.cpp index c657fb11e..6a08a2de8 100644 --- a/src/playlistparsers/asxparser.cpp +++ b/src/playlistparsers/asxparser.cpp @@ -46,21 +46,9 @@ SongList ASXParser::Load(QIODevice *device, const QString &playlist_path, const // We have to load everything first so we can munge the "XML". QByteArray data = device->readAll(); - // (thanks Amarok...) - // ASX looks a lot like xml, but doesn't require tags to be case sensitive, - // meaning we have to accept things like: ... - // We use a dirty way to achieve this: we make all tags lower case - QRegExp ex("(<[/]?[^>]*[A-Z]+[^>]*>)"); - ex.setCaseSensitivity(Qt::CaseInsensitive); - int index = 0; - while ((index = ex.indexIn(data, index)) != -1) { - data.replace(ex.cap(1).toLocal8Bit(), ex.cap(1).toLower().toLocal8Bit()); - index += ex.matchedLength(); - } - // Some playlists have unescaped & characters in URLs :( - ex.setPattern("(href\\s*=\\s*\")([^\"]+)\""); - index = 0; + QRegExp ex("(href\\s*=\\s*\")([^\"]+)\""); + int index = 0; while ((index = ex.indexIn(data, index)) != -1) { QString url = ex.cap(2); url.replace(QRegExp("&(?!amp;|quot;|apos;|lt;|gt;)"), "&"); @@ -76,16 +64,17 @@ SongList ASXParser::Load(QIODevice *device, const QString &playlist_path, const SongList ret; QXmlStreamReader reader(&buffer); - if (!Utilities::ParseUntilElement(&reader, "asx")) { + if (!Utilities::ParseUntilElementCI(&reader, "asx")) { return ret; } - while (!reader.atEnd() && Utilities::ParseUntilElement(&reader, "entry")) { + while (!reader.atEnd() && Utilities::ParseUntilElementCI(&reader, "entry")) { Song song = ParseTrack(&reader, dir); if (song.is_valid()) { ret << song; } } + return ret; } @@ -99,18 +88,21 @@ Song ASXParser::ParseTrack(QXmlStreamReader *reader, const QDir &dir) const { switch (type) { case QXmlStreamReader::StartElement: { - QStringRef name = reader->name(); + QString name = reader->name().toString().toLower(); if (name == "ref") { ref = reader->attributes().value("href").toString(); - } else if (name == "title") { + } + else if (name == "title") { title = reader->readElementText(); - } else if (name == "author") { + } + else if (name == "author") { artist = reader->readElementText(); } break; } case QXmlStreamReader::EndElement: { - if (reader->name() == "entry") { + QString name = reader->name().toString().toLower(); + if (name == "entry") { goto return_song; } break; @@ -124,9 +116,12 @@ return_song: Song song = LoadSong(ref, 0, dir); // Override metadata with what was in the playlist - song.set_title(title); - song.set_artist(artist); - song.set_album(album); + if (song.source() != Song::Source_Collection) { + if (!title.isEmpty()) song.set_title(title); + if (!artist.isEmpty()) song.set_artist(artist); + if (!album.isEmpty()) song.set_album(album); + } + return song; } diff --git a/src/playlistparsers/m3uparser.cpp b/src/playlistparsers/m3uparser.cpp index e67146f73..f2fc7fb91 100644 --- a/src/playlistparsers/m3uparser.cpp +++ b/src/playlistparsers/m3uparser.cpp @@ -121,6 +121,7 @@ bool M3UParser::ParseMetadata(const QString &line, M3UParser::Metadata *metadata metadata->artist = list[0].trimmed(); metadata->title = list[1].trimmed(); return true; + } void M3UParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, Playlist::Path path_type) const { @@ -146,6 +147,7 @@ void M3UParser::Save(const SongList &songs, QIODevice *device, const QDir &dir, device->write(URLOrFilename(song.url(), dir, path_type).toUtf8()); device->write("\n"); } + } bool M3UParser::TryMagic(const QByteArray &data) const { diff --git a/src/playlistparsers/parserbase.cpp b/src/playlistparsers/parserbase.cpp index 22724d8c7..27118ffe4 100644 --- a/src/playlistparsers/parserbase.cpp +++ b/src/playlistparsers/parserbase.cpp @@ -93,7 +93,7 @@ void ParserBase::LoadSong(const QString &filename_or_url, qint64 beginning, cons Song ParserBase::LoadSong(const QString &filename_or_url, qint64 beginning, const QDir &dir) const { - Song song; + Song song(Song::Source_LocalFile); LoadSong(filename_or_url, beginning, dir, &song); return song; diff --git a/src/playlistparsers/xmlparser.cpp b/src/playlistparsers/xmlparser.cpp index cb43f8d83..bddeaa7a8 100644 --- a/src/playlistparsers/xmlparser.cpp +++ b/src/playlistparsers/xmlparser.cpp @@ -27,4 +27,3 @@ class CollectionBackendInterface; XMLParser::XMLParser(CollectionBackendInterface *collection, QObject *parent) : ParserBase(collection, parent) {} - diff --git a/src/playlistparsers/xspfparser.cpp b/src/playlistparsers/xspfparser.cpp index 22b46c8b0..de59592f5 100644 --- a/src/playlistparsers/xspfparser.cpp +++ b/src/playlistparsers/xspfparser.cpp @@ -124,11 +124,14 @@ return_song: Song song = LoadSong(location, 0, dir); // Override metadata with what was in the playlist - song.set_title(title); - song.set_artist(artist); - song.set_album(album); - song.set_length_nanosec(nanosec); - song.set_track(track_num); + if (song.source() != Song::Source_Collection) { + if (!title.isEmpty()) song.set_title(title); + if (!artist.isEmpty()) song.set_artist(artist); + if (!album.isEmpty()) song.set_album(album); + if (nanosec > 0) song.set_length_nanosec(nanosec); + if (track_num > 0) song.set_track(track_num); + } + return song; }