diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index bfab14c5e..f5911a830 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -91,6 +91,7 @@ set(SOURCES
playlist/songplaylistitem.cpp
playlistparsers/asxparser.cpp
+ playlistparsers/asxiniparser.cpp
playlistparsers/m3uparser.cpp
playlistparsers/parserbase.cpp
playlistparsers/playlistparser.cpp
@@ -207,6 +208,7 @@ set(HEADERS
playlist/songmimedata.h
playlistparsers/asxparser.h
+ playlistparsers/asxiniparser.h
playlistparsers/m3uparser.h
playlistparsers/parserbase.h
playlistparsers/playlistparser.h
diff --git a/src/core/songloader.cpp b/src/core/songloader.cpp
index 49f33506c..c571ee380 100644
--- a/src/core/songloader.cpp
+++ b/src/core/songloader.cpp
@@ -324,9 +324,19 @@ void SongLoader::ErrorMessageReceived(GstMessage* msg) {
qDebug() << error->message;
qDebug() << debugs;
+ QString message_str = error->message;
+
g_error_free(error);
free(debugs);
+ if (state_ == WaitingForType &&
+ message_str == "Could not determine type of stream.") {
+ // Don't give up - assume it's a playlist and see if one of our parsers can
+ // read it.
+ state_ = WaitingForMagic;
+ return;
+ }
+
StopTypefindAsync(false);
}
diff --git a/src/playlistparsers/asxiniparser.cpp b/src/playlistparsers/asxiniparser.cpp
new file mode 100644
index 000000000..f9ae5e972
--- /dev/null
+++ b/src/playlistparsers/asxiniparser.cpp
@@ -0,0 +1,60 @@
+/* This file is part of Clementine.
+
+ 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 "asxiniparser.h"
+
+#include
+#include
+
+AsxIniParser::AsxIniParser(QObject* parent)
+ : ParserBase(parent)
+{
+}
+
+bool AsxIniParser::TryMagic(const QByteArray &data) const {
+ return data.toLower().contains("[reference]");
+}
+
+SongList AsxIniParser::Load(QIODevice *device, const QDir &dir) const {
+ SongList ret;
+
+ while (!device->atEnd()) {
+ QString line = QString::fromUtf8(device->readLine()).trimmed();
+ int equals = line.indexOf('=');
+ QString key = line.left(equals).toLower();
+ QString value = line.mid(equals + 1);
+
+ if (key.startsWith("ref")) {
+ Song song;
+ if (!ParseTrackLocation(value, dir, &song))
+ qWarning() << "Failed to parse location: " << value;
+ ret << song;
+ }
+ }
+
+ return ret;
+}
+
+void AsxIniParser::Save(const SongList &songs, QIODevice *device, const QDir &dir) const {
+ QTextStream s(device);
+ s << "[Reference]" << endl;
+
+ int n = 1;
+ foreach (const Song& song, songs) {
+ s << "Ref" << n << "=" << MakeRelativeTo(song.filename(), dir) << endl;
+ ++n;
+ }
+}
diff --git a/src/playlistparsers/asxiniparser.h b/src/playlistparsers/asxiniparser.h
new file mode 100644
index 000000000..fb0b90c10
--- /dev/null
+++ b/src/playlistparsers/asxiniparser.h
@@ -0,0 +1,37 @@
+/* This file is part of Clementine.
+
+ 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 ASXINIPARSER_H
+#define ASXINIPARSER_H
+
+#include "parserbase.h"
+
+class AsxIniParser : public ParserBase {
+ Q_OBJECT
+
+public:
+ AsxIniParser(QObject* parent = 0);
+
+ QString name() const { return "ASX/INI"; }
+ QStringList file_extensions() const { return QStringList() << "asxini"; }
+
+ bool TryMagic(const QByteArray &data) const;
+
+ SongList Load(QIODevice *device, const QDir &dir = QDir()) const;
+ void Save(const SongList &songs, QIODevice *device, const QDir &dir = QDir()) const;
+};
+
+#endif // ASXINIPARSER_H
diff --git a/src/playlistparsers/playlistparser.cpp b/src/playlistparsers/playlistparser.cpp
index 33ad9e353..63cd01e15 100644
--- a/src/playlistparsers/playlistparser.cpp
+++ b/src/playlistparsers/playlistparser.cpp
@@ -19,6 +19,7 @@
#include "m3uparser.h"
#include "plsparser.h"
#include "asxparser.h"
+#include "asxiniparser.h"
#include
@@ -31,6 +32,7 @@ PlaylistParser::PlaylistParser(QObject *parent)
parsers_ << new XSPFParser(this);
parsers_ << new PLSParser(this);
parsers_ << new ASXParser(this);
+ parsers_ << new AsxIniParser(this);
}
QStringList PlaylistParser::file_extensions() const {
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index e11748cb5..a52fca962 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -7,6 +7,10 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../src)
include_directories(${QT_QTTEST_INCLUDE_DIR})
+if(LIBGPOD_FOUND)
+ include_directories(${LIBGPOD_INCLUDE_DIRS})
+endif(LIBGPOD_FOUND)
+
set(GTEST-SOURCES
../3rdparty/gmock/gtest/src/gtest.cc
../3rdparty/gmock/gtest/src/gtest-death-test.cc
@@ -87,6 +91,7 @@ endmacro (add_test_file)
#add_test_file(albumcoverfetcher_test.cpp false)
add_test_file(albumcovermanager_test.cpp true)
add_test_file(asxparser_test.cpp false)
+add_test_file(asxiniparser_test.cpp false)
add_test_file(database_test.cpp false)
add_test_file(fileformats_test.cpp false)
add_test_file(librarybackend_test.cpp false)
diff --git a/tests/asxiniparser_test.cpp b/tests/asxiniparser_test.cpp
new file mode 100644
index 000000000..3b6cbb95f
--- /dev/null
+++ b/tests/asxiniparser_test.cpp
@@ -0,0 +1,63 @@
+/* This file is part of Clementine.
+
+ 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 "test_utils.h"
+#include "gmock/gmock-matchers.h"
+#include "gtest/gtest.h"
+
+#include "playlistparsers/asxiniparser.h"
+#include "playlistparsers/playlistparser.h"
+
+#include
+
+class AsxIniParserTest : public ::testing::Test {
+protected:
+ AsxIniParser parser_;
+};
+
+TEST_F(AsxIniParserTest, ParsesBasicTrackList) {
+ QFile file(":/testdata/test.asxini");
+ file.open(QIODevice::ReadOnly);
+
+ SongList songs = parser_.Load(&file, QDir());
+ ASSERT_EQ(2, songs.length());
+ EXPECT_EQ("http://195.245.168.21/antena3?MSWMExt=.asf", songs[0].filename());
+ EXPECT_EQ("http://195.245.168.21:80/antena3?MSWMExt=.asf", songs[1].filename());
+ EXPECT_TRUE(songs[0].is_valid());
+ EXPECT_TRUE(songs[1].is_valid());
+}
+
+TEST_F(AsxIniParserTest, Magic) {
+ QFile file(":/testdata/test.asxini");
+ file.open(QIODevice::ReadOnly);
+
+ EXPECT_TRUE(parser_.TryMagic(file.read(PlaylistParser::kMagicSize)));
+}
+
+TEST_F(AsxIniParserTest, WritesBasicTrackList) {
+ QByteArray data;
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::WriteOnly);
+
+ Song song;
+ song.set_filename("http://www.example.com/foo.mp3");
+
+ SongList songs;
+ songs << song;
+
+ parser_.Save(songs, &buffer);
+ EXPECT_EQ("[Reference]\nRef1=http://www.example.com/foo.mp3\n", QString(data));
+}
diff --git a/tests/data/test.asxini b/tests/data/test.asxini
new file mode 100644
index 000000000..5e2f7ecd3
--- /dev/null
+++ b/tests/data/test.asxini
@@ -0,0 +1,3 @@
+[Reference]
+Ref1=http://195.245.168.21/antena3?MSWMExt=.asf
+Ref2=http://195.245.168.21:80/antena3?MSWMExt=.asf
diff --git a/tests/data/testdata.qrc b/tests/data/testdata.qrc
index 4ca45e0e0..d2e1bf0cd 100644
--- a/tests/data/testdata.qrc
+++ b/tests/data/testdata.qrc
@@ -14,5 +14,6 @@
test.asx
secretagent.asx
secretagent.pls
+ test.asxini