aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/PlayListFormats
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/PlayListFormats')
-rw-r--r--src/plugins/PlayListFormats/m3u/m3uplaylistformat.cpp49
-rw-r--r--src/plugins/PlayListFormats/m3u/m3uplaylistformat.h4
-rw-r--r--src/plugins/PlayListFormats/pls/plsplaylistformat.cpp113
-rw-r--r--src/plugins/PlayListFormats/pls/plsplaylistformat.h4
-rw-r--r--src/plugins/PlayListFormats/xspf/xspfplaylistformat.cpp67
-rw-r--r--src/plugins/PlayListFormats/xspf/xspfplaylistformat.h4
6 files changed, 176 insertions, 65 deletions
diff --git a/src/plugins/PlayListFormats/m3u/m3uplaylistformat.cpp b/src/plugins/PlayListFormats/m3u/m3uplaylistformat.cpp
index 87bd2eaf8..783f3c518 100644
--- a/src/plugins/PlayListFormats/m3u/m3uplaylistformat.cpp
+++ b/src/plugins/PlayListFormats/m3u/m3uplaylistformat.cpp
@@ -32,34 +32,57 @@ const PlayListFormatProperties M3UPlaylistFormat::properties() const
return p;
}
-QStringList M3UPlaylistFormat::decode(const QString & contents)
+QList<PlayListTrack *> M3UPlaylistFormat::decode(const QByteArray &contents)
{
- QStringList out;
- QStringList splitted = contents.split("\n");
+ QList<PlayListTrack*> out;
+ QStringList splitted = QString::fromUtf8(contents).split("\n");
if(splitted.isEmpty())
- return QStringList();
+ return out;
+
+ QRegExp extInfRegExp("#EXTINF:(-{0,1}\\d+),(.*) - (.*)");
+ int length = 0;
+ QString artist, title;
+ bool hasExtInf = false;
foreach(QString str, splitted)
{
- str = str.trimmed ();
- if (str.startsWith("#EXTM3U") || str.startsWith("#EXTINF:") || str.isEmpty())
- continue;//TODO: Let's skip it for now..
- else if (str.startsWith("#") || str.isEmpty())
+ str = str.trimmed();
+ if(str.startsWith("#EXTM3U") || str.isEmpty())
continue;
- else
- out << str;
+
+ if(extInfRegExp.indexIn(str) > -1)
+ {
+ length = extInfRegExp.cap(1).toInt();
+ artist = extInfRegExp.cap(2);
+ title = extInfRegExp.cap(3);
+ hasExtInf = true;
+ }
+
+ if(str.startsWith("#"))
+ continue;
+
+ out << new PlayListTrack();
+ out.last()->insert(Qmmp::URL, str);
+
+ if(hasExtInf)
+ {
+ out.last()->setLength(length);
+ out.last()->insert(Qmmp::ARTIST, artist);
+ out.last()->insert(Qmmp::TITLE, title);
+ hasExtInf = false;
+ }
}
return out;
}
-QString M3UPlaylistFormat::encode(const QList<PlayListTrack*> & contents, const QString &path)
+QByteArray M3UPlaylistFormat::encode(const QList<PlayListTrack*> &contents, const QString &path)
{
QStringList out;
out << QString("#EXTM3U");
MetaDataFormatter formatter("%if(%p,%p - %t,%t)%if(%p|%t,,%f)");
QString m3uDir = QFileInfo(path).canonicalPath();
- foreach(PlayListTrack* f,contents)
+ foreach(PlayListTrack* f, contents)
{
QString info = "#EXTINF:" + QString::number(f->length()) + "," + formatter.format(f);
out.append(info);
@@ -75,7 +98,7 @@ QString M3UPlaylistFormat::encode(const QList<PlayListTrack*> & contents, const
else
out.append(f->url());
}
- return out.join("\n");
+ return out.join("\n").toUtf8();
}
Q_EXPORT_PLUGIN2(m3uplaylistformat,M3UPlaylistFormat)
diff --git a/src/plugins/PlayListFormats/m3u/m3uplaylistformat.h b/src/plugins/PlayListFormats/m3u/m3uplaylistformat.h
index 379ae063e..dd859c807 100644
--- a/src/plugins/PlayListFormats/m3u/m3uplaylistformat.h
+++ b/src/plugins/PlayListFormats/m3u/m3uplaylistformat.h
@@ -36,8 +36,8 @@ class M3UPlaylistFormat : public QObject, public PlayListFormat
Q_INTERFACES(PlayListFormat)
public:
const PlayListFormatProperties properties() const;
- QStringList decode(const QString& contents);
- QString encode(const QList<PlayListTrack*>& contents, const QString &path);
+ QList<PlayListTrack*> decode(const QByteArray &contents);
+ QByteArray encode(const QList<PlayListTrack*>& contents, const QString &path);
};
diff --git a/src/plugins/PlayListFormats/pls/plsplaylistformat.cpp b/src/plugins/PlayListFormats/pls/plsplaylistformat.cpp
index ac4954567..a4822c423 100644
--- a/src/plugins/PlayListFormats/pls/plsplaylistformat.cpp
+++ b/src/plugins/PlayListFormats/pls/plsplaylistformat.cpp
@@ -18,8 +18,9 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#include <QFileInfo>
#include <QtPlugin>
+#include <QRegExp>
+#include <qmmpui/metadataformatter.h>
#include "plsplaylistformat.h"
const PlayListFormatProperties PLSPlaylistFormat::properties() const
@@ -31,57 +32,111 @@ const PlayListFormatProperties PLSPlaylistFormat::properties() const
return p;
}
-QStringList PLSPlaylistFormat::decode(const QString & contents)
+QList<PlayListTrack *> PLSPlaylistFormat::decode(const QByteArray &contents)
{
- QStringList out;
- QStringList splitted = contents.split("\n");
- if (!splitted.isEmpty())
+ QList<PlayListTrack *> out;
+ QStringList splitted = QString::fromUtf8(contents).split("\n");
+
+ if(splitted.isEmpty())
{
- if (splitted.takeAt(0).toLower().contains("[playlist]"))
+ qWarning("PLSPlaylistFormat: error parsing PLS format");
+ return out;
+ }
+
+ if(!splitted.takeFirst().toLower().startsWith("[playlist]"))
+ {
+ qWarning("PLSPlaylistFormat: unknown playlist format");
+ return out;
+ }
+
+ QRegExp fileRegExp("^File(\\d+)=(.+)");
+ QRegExp fullTitleRegExp("^Title(\\d+)=(.+) - (.+)");
+ QRegExp titleRegExp("^Title(\\d+)=(.+)");
+ QRegExp lengthRegExp("^Length(\\d+)=(-{0,1}\\d+)");
+
+ int number = 0;
+ bool error = false;
+
+ foreach (QString line, splitted)
+ {
+ if(fileRegExp.indexIn(line) > -1)
{
- foreach(QString str, splitted)
+ if((number = fileRegExp.cap(1).toInt()) > 0)
{
- if (str.startsWith("File"))
- {
- QString unverified = str.remove(0,str.indexOf(QChar('=')) + 1);
- unverified = unverified.trimmed();
- if (unverified.startsWith("http://"))
- {
- out << unverified;
- }
- else /*if (QFileInfo(unverified).exists())*/
- out << QFileInfo(unverified).absoluteFilePath();
- /*else
- qWarning("File %s does not exist", qPrintable(unverified));*/
- }
+ while(number > out.count())
+ out << new PlayListTrack();
+ out[number - 1]->insert(Qmmp::URL, fileRegExp.cap(2));
}
- return out;
+ else
+ error = true;
+ }
+ else if(fullTitleRegExp.indexIn(line) > -1)
+ {
+ if((number = fullTitleRegExp.cap(1).toInt()) > 0)
+ {
+ while(number > out.count())
+ out << new PlayListTrack();
+ out[number - 1]->insert(Qmmp::ARTIST, fullTitleRegExp.cap(2));
+ out[number - 1]->insert(Qmmp::TITLE, fullTitleRegExp.cap(3));
+ }
+ else
+ error = true;
+ }
+ else if(titleRegExp.indexIn(line) > -1)
+ {
+ if((number = titleRegExp.cap(1).toInt()) > 0)
+ {
+ while(number > out.count())
+ out << new PlayListTrack();
+ out[number - 1]->insert(Qmmp::TITLE, titleRegExp.cap(2));
+ }
+ else
+ error = true;
+ }
+ else if(lengthRegExp.indexIn(line) > -1)
+ {
+ if((number = lengthRegExp.cap(1).toInt()) > 0)
+ {
+ while(number > out.count())
+ out << new PlayListTrack();
+ out[number - 1]->setLength(lengthRegExp.cap(2).toInt());
+ }
+ else
+ error = true;
+ }
+
+ if(error)
+ {
+ qWarning("PLSPlaylistFormat: error while parsing line: '%s'", qPrintable(line));
+ qDeleteAll(out);
+ out.clear();
+ break;
}
}
- else
- qWarning("Error parsing PLS format");
- return QStringList();
+ return out;
}
-QString PLSPlaylistFormat::encode(const QList<PlayListTrack *> & contents, const QString &path)
+QByteArray PLSPlaylistFormat::encode(const QList<PlayListTrack *> &contents, const QString &path)
{
Q_UNUSED(path);
+ MetaDataFormatter formatter("%if(%p,%p - %t,%t)%if(%p|%t,,%f)");
QStringList out;
out << QString("[playlist]");
int counter = 1;
- foreach(PlayListTrack* f,contents)
+ foreach(PlayListTrack *f, contents)
{
QString begin = "File" + QString::number(counter) + "=";
out.append(begin + f->url());
begin = "Title" + QString::number(counter) + "=";
- out.append(begin + f->value(Qmmp::TITLE));
+ out.append(begin + formatter.format(f));
begin = "Length" + QString::number(counter) + "=";
out.append(begin + QString::number(f->length()));
- counter ++;
+ counter++;
}
out << "NumberOfEntries=" + QString::number(contents.count());
- return out.join("\n");
+ out << "Version=2";
+ return out.join("\n").toUtf8();
}
Q_EXPORT_PLUGIN2(plsplaylistformat, PLSPlaylistFormat)
diff --git a/src/plugins/PlayListFormats/pls/plsplaylistformat.h b/src/plugins/PlayListFormats/pls/plsplaylistformat.h
index 7fed6d810..79bebf91c 100644
--- a/src/plugins/PlayListFormats/pls/plsplaylistformat.h
+++ b/src/plugins/PlayListFormats/pls/plsplaylistformat.h
@@ -36,8 +36,8 @@ class PLSPlaylistFormat : public QObject, public PlayListFormat
Q_INTERFACES(PlayListFormat)
public:
const PlayListFormatProperties properties() const;
- QStringList decode(const QString& contents);
- QString encode(const QList<PlayListTrack*>& contents, const QString &path);
+ QList<PlayListTrack*> decode(const QByteArray& contents);
+ QByteArray encode(const QList<PlayListTrack*> &contents, const QString &path);
};
diff --git a/src/plugins/PlayListFormats/xspf/xspfplaylistformat.cpp b/src/plugins/PlayListFormats/xspf/xspfplaylistformat.cpp
index d5ab21fb5..93d691d3c 100644
--- a/src/plugins/PlayListFormats/xspf/xspfplaylistformat.cpp
+++ b/src/plugins/PlayListFormats/xspf/xspfplaylistformat.cpp
@@ -37,11 +37,11 @@ const PlayListFormatProperties XSPFPlaylistFormat::XSPFPlaylistFormat::propertie
return p;
}
-QStringList XSPFPlaylistFormat::decode(const QString & contents)
+QList<PlayListTrack*> XSPFPlaylistFormat::decode(const QByteArray &contents)
{
- QStringList out;
+ QList<PlayListTrack*> out;
QString currentTag;
- QString contents_copy = contents;
+ QString contents_copy = QString::fromUtf8(contents);
//remove control symbols to avoid xml errors
for(int i = 0; i < contents_copy.size(); ++i)
@@ -54,24 +54,47 @@ QStringList XSPFPlaylistFormat::decode(const QString & contents)
}
QXmlStreamReader xml(contents_copy);
- while(!xml.atEnd())
+ while(!xml.atEnd() || !xml.hasError())
{
xml.readNext();
if (xml.isStartElement())
{
currentTag = xml.name().toString();
-
+ if(currentTag == "track")
+ out << new PlayListTrack();
}
else if (xml.isCharacters() && !xml.isWhitespace())
{
- if (currentTag == "location")
- {
+ if(out.isEmpty())
+ continue;
+ if(currentTag == "location")
+ {
QUrl url(xml.text().toString());
if (url.scheme() == "file") //remove scheme for local files only
- out << QUrl::fromPercentEncoding(url.toString().toLatin1()).remove("file://");
+ out.last()->insert(Qmmp::URL, QUrl::fromPercentEncoding(url.toString().toLatin1()).remove("file://"));
else
- out << QUrl::fromPercentEncoding(url.toString().toLatin1());
+ out.last()->insert(Qmmp::URL, QUrl::fromPercentEncoding(url.toString().toLatin1()));
+ }
+ else if(currentTag == "title")
+ {
+ out.last()->insert(Qmmp::TITLE, xml.text().toString());
+ }
+ else if(currentTag == "creator")
+ {
+ out.last()->insert(Qmmp::ARTIST, xml.text().toString());
+ }
+ else if(currentTag == "annotation")
+ {
+ out.last()->insert(Qmmp::COMMENT, xml.text().toString());
+ }
+ else if(currentTag == "album")
+ {
+ out.last()->insert(Qmmp::ALBUM, xml.text().toString());
+ }
+ else if(currentTag == "meta" && xml.attributes().value("rel") == "year")
+ {
+ out.last()->insert(Qmmp::YEAR, xml.text().toString());
}
else
xml.skipCurrentElement();
@@ -88,10 +111,10 @@ QStringList XSPFPlaylistFormat::decode(const QString & contents)
// Needs more work - it's better use libSpiff there and put it as plugin.
-QString XSPFPlaylistFormat::encode(const QList<PlayListTrack*> & files, const QString &path)
+QByteArray XSPFPlaylistFormat::encode(const QList<PlayListTrack*> &files, const QString &path)
{
- Q_UNUSED(path);
- QString out;
+ QString xspfDir = QFileInfo(path).canonicalPath();
+ QByteArray out;
QXmlStreamWriter xml(&out);
xml.setCodec("UTF-8");
xml.setAutoFormatting(true);
@@ -103,16 +126,27 @@ QString XSPFPlaylistFormat::encode(const QList<PlayListTrack*> & files, const QS
xml.writeStartElement("trackList");
int counter = 1;
- foreach(PlayListTrack* f,files)
+ foreach(PlayListTrack* f, files)
{
xml.writeStartElement("track");
QString url;
if (f->url().contains("://"))
+ {
url = QUrl::toPercentEncoding(f->url(), ":/");
- else //append protocol
- url = QUrl::toPercentEncoding(QString("file://") +
- QFileInfo(f->url()).absoluteFilePath(), ":/");
+ }
+ else if(f->url().startsWith(xspfDir)) //relative path
+ {
+ QString p = f->url();
+ p.remove(0, xspfDir.size());
+ if(p.startsWith("/"))
+ p.remove(0, 1);
+ url = QUrl::toPercentEncoding(p, ":/");
+ }
+ else //absolute path
+ {
+ url = QUrl::toPercentEncoding(QLatin1String("file://") + f->url(), ":/");
+ }
xml.writeTextElement("location", url);
xml.writeTextElement("title", f->value(Qmmp::TITLE));
@@ -133,7 +167,6 @@ QString XSPFPlaylistFormat::encode(const QList<PlayListTrack*> & files, const QS
xml.writeEndElement(); //playlist
xml.writeEndDocument();
return out;
-
}
Q_EXPORT_PLUGIN2(xspfplaylistformat,XSPFPlaylistFormat)
diff --git a/src/plugins/PlayListFormats/xspf/xspfplaylistformat.h b/src/plugins/PlayListFormats/xspf/xspfplaylistformat.h
index d3b03d3ca..dbd1325d5 100644
--- a/src/plugins/PlayListFormats/xspf/xspfplaylistformat.h
+++ b/src/plugins/PlayListFormats/xspf/xspfplaylistformat.h
@@ -36,8 +36,8 @@ class XSPFPlaylistFormat : public QObject, public PlayListFormat
Q_INTERFACES(PlayListFormat)
public:
const PlayListFormatProperties properties() const;
- QStringList decode(const QString& contents);
- QString encode(const QList<PlayListTrack*>& contents, const QString &path);
+ QList<PlayListTrack*> decode(const QByteArray &contents);
+ QByteArray encode(const QList<PlayListTrack*> &contents, const QString &path);
};
#endif