mirror of
https://github.com/clementine-player/Clementine
synced 2024-12-18 12:28:31 +01:00
Implement playlist saving for XSPF.
This commit is contained in:
parent
a59f5a3887
commit
1b76ead951
@ -16,8 +16,10 @@
|
||||
|
||||
#include "xspfparser.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QFile>
|
||||
#include <QIODevice>
|
||||
#include <QRegExp>
|
||||
#include <QUrl>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
@ -137,5 +139,52 @@ Song XSPFParser::ParseTrack(QXmlStreamReader* reader) const {
|
||||
}
|
||||
|
||||
void XSPFParser::Save(const SongList &songs, QIODevice *device, const QDir &dir) const {
|
||||
QDomDocument doc;
|
||||
QDomElement root = doc.createElement("playlist");
|
||||
doc.appendChild(root);
|
||||
QDomElement track_list = doc.createElement("trackList");
|
||||
root.appendChild(track_list);
|
||||
foreach (const Song& song, songs) {
|
||||
QString url;
|
||||
if (song.filetype() == Song::Type_Stream) {
|
||||
url = song.filename();
|
||||
} else {
|
||||
url = QUrl::fromLocalFile(MakeRelativeTo(song.filename(), dir)).toString();
|
||||
}
|
||||
if (url.isEmpty()) {
|
||||
continue; // Skip empty items like Last.fm streams.
|
||||
}
|
||||
QDomElement track = doc.createElement("track");
|
||||
track_list.appendChild(track);
|
||||
MaybeAppendElementWithText("location", url, &doc, &track);
|
||||
MaybeAppendElementWithText("creator", song.artist(), &doc, &track);
|
||||
MaybeAppendElementWithText("album", song.album(), &doc, &track);
|
||||
MaybeAppendElementWithText("title", song.title(), &doc, &track);
|
||||
if (song.length() != -1) {
|
||||
MaybeAppendElementWithText("duration", QString::number(song.length() * 1000), &doc, &track);
|
||||
}
|
||||
QString art = song.art_manual().isEmpty() ? song.art_automatic() : song.art_manual();
|
||||
// Ignore images that are in our resource bundle.
|
||||
if (!art.startsWith(":") && !art.isEmpty()) {
|
||||
// Convert local files to URLs.
|
||||
if (!art.contains(QRegExp("^\\w+://"))) {
|
||||
art = QUrl::fromLocalFile(MakeRelativeTo(art, dir)).toString();
|
||||
}
|
||||
MaybeAppendElementWithText("image", art, &doc, &track);
|
||||
}
|
||||
}
|
||||
|
||||
device->write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
device->write(doc.toByteArray(2));
|
||||
}
|
||||
|
||||
void XSPFParser::MaybeAppendElementWithText(
|
||||
const QString& element_name, const QString& text, QDomDocument* doc, QDomNode* parent) const {
|
||||
if (text.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QDomElement element = doc->createElement(element_name);
|
||||
QDomText t = doc->createTextNode(text);
|
||||
element.appendChild(t);
|
||||
parent->appendChild(element);
|
||||
}
|
||||
|
@ -21,6 +21,9 @@
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
class QDomDocument;
|
||||
class QDomNode;
|
||||
|
||||
class XSPFParser : public ParserBase {
|
||||
Q_OBJECT
|
||||
|
||||
@ -37,6 +40,8 @@ class XSPFParser : public ParserBase {
|
||||
bool ParseUntilElement(QXmlStreamReader* reader, const QString& element) const;
|
||||
void IgnoreElement(QXmlStreamReader* reader) const;
|
||||
Song ParseTrack(QXmlStreamReader* reader) const;
|
||||
void MaybeAppendElementWithText(
|
||||
const QString& element, const QString& text, QDomDocument* doc, QDomNode* parent) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -15,12 +15,15 @@
|
||||
*/
|
||||
|
||||
#include "test_utils.h"
|
||||
#include "gmock/gmock-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "playlistparsers/xspfparser.h"
|
||||
|
||||
#include <QBuffer>
|
||||
|
||||
using ::testing::HasSubstr;
|
||||
|
||||
class XSPFParserTest : public ::testing::Test {
|
||||
|
||||
};
|
||||
@ -89,3 +92,24 @@ TEST_F(XSPFParserTest, IgnoresInvalidLength) {
|
||||
ASSERT_EQ(1, songs.length());
|
||||
EXPECT_EQ(-1, songs[0].length());
|
||||
}
|
||||
|
||||
TEST_F(XSPFParserTest, SavesSong) {
|
||||
QByteArray data;
|
||||
QBuffer buffer(&data);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
XSPFParser parser;
|
||||
Song one;
|
||||
one.set_filename("http://www.example.com/foo.mp3");
|
||||
one.set_filetype(Song::Type_Stream);
|
||||
one.set_title("foo");
|
||||
one.set_length(123);
|
||||
one.set_artist("bar");
|
||||
SongList songs;
|
||||
songs << one;
|
||||
|
||||
parser.Save(songs, &buffer);
|
||||
EXPECT_THAT(data.constData(), HasSubstr("<location>http://www.example.com/foo.mp3</location>"));
|
||||
EXPECT_THAT(data.constData(), HasSubstr("<duration>123000</duration>"));
|
||||
EXPECT_THAT(data.constData(), HasSubstr("<title>foo</title>"));
|
||||
EXPECT_THAT(data.constData(), HasSubstr("<creator>bar</creator>"));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user