diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cc8fb13f3..72dc7e2a8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -252,6 +252,7 @@ set(SOURCES playlistparsers/parserbase.cpp playlistparsers/playlistparser.cpp playlistparsers/plsparser.cpp + playlistparsers/wplparser.cpp playlistparsers/xmlparser.cpp playlistparsers/xspfparser.cpp diff --git a/src/playlistparsers/parserbase.h b/src/playlistparsers/parserbase.h index 793a42951..cf141a5b3 100644 --- a/src/playlistparsers/parserbase.h +++ b/src/playlistparsers/parserbase.h @@ -29,7 +29,7 @@ class ParserBase : public QObject { Q_OBJECT public: - ParserBase(LibraryBackendInterface* library, QObject *parent = 0); + ParserBase(LibraryBackendInterface* library, QObject* parent = 0); virtual QString name() const = 0; virtual QStringList file_extensions() const = 0; diff --git a/src/playlistparsers/playlistparser.cpp b/src/playlistparsers/playlistparser.cpp index e6e626357..5b2f59dab 100644 --- a/src/playlistparsers/playlistparser.cpp +++ b/src/playlistparsers/playlistparser.cpp @@ -21,6 +21,7 @@ #include "m3uparser.h" #include "playlistparser.h" #include "plsparser.h" +#include "wplparser.h" #include "xspfparser.h" #include "core/logging.h" @@ -38,6 +39,7 @@ PlaylistParser::PlaylistParser(LibraryBackendInterface* library, QObject *parent parsers_ << new ASXParser(library, this); parsers_ << new AsxIniParser(library, this); parsers_ << new CueParser(library, this); + parsers_ << new WplParser(library, this); } QStringList PlaylistParser::file_extensions() const { diff --git a/src/playlistparsers/wplparser.cpp b/src/playlistparsers/wplparser.cpp new file mode 100644 index 000000000..6edeecd30 --- /dev/null +++ b/src/playlistparsers/wplparser.cpp @@ -0,0 +1,113 @@ +/* This file is part of Clementine. + Copyright 2013, David Sansome + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#include "wplparser.h" +#include "core/utilities.h" +#include "version.h" + +#include + +WplParser::WplParser(LibraryBackendInterface* library, QObject* parent) + : XMLParser(library, parent) +{ +} + +bool WplParser::TryMagic(const QByteArray& data) const { + return data.contains(""); +} + +SongList WplParser::Load(QIODevice* device, const QString& playlist_path, + const QDir& dir) const { + SongList ret; + + QXmlStreamReader reader(device); + if (!Utilities::ParseUntilElement(&reader, "smil") || + !Utilities::ParseUntilElement(&reader, "body")) { + return ret; + } + + while (!reader.atEnd() && Utilities::ParseUntilElement(&reader, "seq")) { + ParseSeq(dir, &reader, &ret); + } + return ret; +} + +void WplParser::ParseSeq(const QDir& dir, QXmlStreamReader* reader, + SongList* songs) const { + while (!reader->atEnd()) { + QXmlStreamReader::TokenType type = reader->readNext(); + switch (type) { + case QXmlStreamReader::StartElement: { + QStringRef name = reader->name(); + if (name == "media") { + QStringRef src = reader->attributes().value("src"); + if (!src.isEmpty()) { + Song song = LoadSong(src.toString(), 0, dir); + if (song.is_valid()) { + songs->append(song); + } + } + } else { + Utilities::ConsumeCurrentElement(reader); + } + break; + } + case QXmlStreamReader::EndElement: { + if (reader->name() == "seq") { + return; + } + break; + } + default: + break; + } + } +} + +void WplParser::Save(const SongList& songs, QIODevice* device, + const QDir& dir) const { + QXmlStreamWriter writer(device); + writer.writeProcessingInstruction("wpl", "version=\"1.0\""); + + StreamElement smil("smil", &writer); + + { + StreamElement head("head", &writer); + WriteMeta("Generator", "Clementine -- " CLEMENTINE_VERSION_DISPLAY, &writer); + WriteMeta("ItemCount", QString::number(songs.count()), &writer); + } + + { + StreamElement body("body", &writer); + { + StreamElement seq("seq", &writer); + foreach (const Song& song, songs) { + writer.writeStartElement("media"); + writer.writeAttribute("src", URLOrRelativeFilename(song.url(), dir)); + writer.writeEndElement(); + } + } + } +} + +void WplParser::WriteMeta(const QString& name, const QString& content, + QXmlStreamWriter* writer) const { + writer->writeStartElement("meta"); + writer->writeAttribute("name", name); + writer->writeAttribute("content", content); + writer->writeEndElement(); +} diff --git a/src/playlistparsers/wplparser.h b/src/playlistparsers/wplparser.h new file mode 100644 index 000000000..54d02d5ca --- /dev/null +++ b/src/playlistparsers/wplparser.h @@ -0,0 +1,44 @@ +/* This file is part of Clementine. + Copyright 2013, David Sansome + + Clementine is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Clementine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Clementine. If not, see . +*/ + +#ifndef WPLPARSER_H +#define WPLPARSER_H + +#include "xmlparser.h" + +class WplParser : public XMLParser { + public: + WplParser(LibraryBackendInterface* library, QObject* parent = 0); + + QString name() const { return "WPL"; } + QStringList file_extensions() const { return QStringList() << "wpl"; } + QString mime_type() const { return "application/vnd.ms-wpl"; } + + bool TryMagic(const QByteArray& data) const; + + SongList Load(QIODevice* device, const QString& playlist_path, + const QDir& dir) const; + void Save(const SongList& songs, QIODevice* device, const QDir& dir) const; + +private: + void ParseSeq(const QDir& dir, QXmlStreamReader* reader, + SongList* songs) const; + void WriteMeta(const QString& name, const QString& content, + QXmlStreamWriter* writer) const; +}; + +#endif // WPLPARSER_H