Make M3U parser grab tags from file.

This commit is contained in:
John Maguire 2010-03-07 14:04:17 +00:00
parent 4219dfa718
commit 08416e2c51
3 changed files with 40 additions and 47 deletions

View File

@ -27,17 +27,16 @@ const QList<Song>& M3UParser::Parse() {
}
}
} else {
// Track location.
QUrl url;
if (!ParseTrackLocation(line, &url)) {
qWarning() << "Failed to parse location: " << line;
continue;
}
Song song;
song.set_title(current_metadata_.title);
song.set_artist(current_metadata_.artist);
song.set_length(current_metadata_.length);
song.set_filename(url.toString());
// Track location.
QString location;
if (!ParseTrackLocation(line, &song)) {
qWarning() << "Failed to parse location: " << line;
continue;
}
songs_ << song;
current_metadata_.artist.clear();
current_metadata_.title.clear();
@ -73,12 +72,12 @@ bool M3UParser::ParseMetadata(const QString& line, M3UParser::Metadata* metadata
return true;
}
bool M3UParser::ParseTrackLocation(const QString& line, QUrl* url) const {
bool M3UParser::ParseTrackLocation(const QString& line, Song* song) const {
if (line.contains(QRegExp("^[a-z]+://"))) {
// Looks like a url.
QUrl temp(line);
if (temp.isValid()) {
*url = temp;
song->set_filename(temp.toString());
return true;
} else {
return false;
@ -90,21 +89,12 @@ bool M3UParser::ParseTrackLocation(const QString& line, QUrl* url) const {
// Absolute path.
// Fix windows \, eg. C:\foo -> C:/foo.
QString proper_path = QDir::fromNativeSeparators(line);
// C:/foo -> /C:/foo.
if (!proper_path.startsWith('/')) {
proper_path.prepend("/");
}
*url = "file://" + proper_path;
return true;
song->set_filename(proper_path);
} else {
// Relative path.
QString proper_path = QDir::fromNativeSeparators(line);
QString absolute_path = directory_.absoluteFilePath(proper_path);
// C:/foo -> /C:/foo.
if (!absolute_path.startsWith('/')) {
absolute_path.prepend("/");
}
*url = "file://" + absolute_path;
return true;
song->set_filename(absolute_path);
}
song->InitFromFile(song->filename(), -1);
}

View File

@ -34,7 +34,7 @@ class M3UParser : public QObject {
};
bool ParseMetadata(const QString& line, Metadata* metadata) const;
bool ParseTrackLocation(const QString& line, QUrl* url) const;
bool ParseTrackLocation(const QString& line, Song* song) const;
FRIEND_TEST(M3UParserTest, ParsesMetadata);
FRIEND_TEST(M3UParserTest, ParsesTrackLocation);

View File

@ -1,5 +1,6 @@
#include "gtest/gtest.h"
#include "test_utils.h"
#include "mock_taglib.h"
#include "m3uparser.h"
@ -7,11 +8,16 @@
class M3UParserTest : public ::testing::Test {
protected:
static void SetUpTestCase() {
testing::DefaultValue<TagLib::String>::Set("foobarbaz");
}
M3UParserTest()
: parser_(NULL) {
}
M3UParser parser_;
MockFileRefFactory taglib_;
};
TEST_F(M3UParserTest, ParsesMetadata) {
@ -24,43 +30,40 @@ TEST_F(M3UParserTest, ParsesMetadata) {
}
TEST_F(M3UParserTest, ParsesTrackLocation) {
taglib_.ExpectCall("/foo/bar.mp3", "foo", "bar", "baz");
Song song(&taglib_);
QString line("/foo/bar.mp3");
QUrl url;
ASSERT_TRUE(parser_.ParseTrackLocation(line, &url));
EXPECT_EQ(QUrl("file:///foo/bar.mp3"), url);
ASSERT_TRUE(parser_.ParseTrackLocation(line, &song));
EXPECT_EQ("/foo/bar.mp3", song.filename());
EXPECT_EQ("foo", song.title());
EXPECT_EQ("bar", song.artist());
EXPECT_EQ("baz", song.album());
}
TEST_F(M3UParserTest, ParsesTrackLocationRelative) {
taglib_.ExpectCall("/tmp/foo/bar.mp3", "foo", "bar", "baz");
M3UParser parser(NULL, QDir("/tmp"));
QString line("foo/bar.mp3");
QUrl url;
ASSERT_TRUE(parser.ParseTrackLocation(line, &url));
EXPECT_EQ(QUrl("file:///tmp/foo/bar.mp3"), url);
Song song(&taglib_);
ASSERT_TRUE(parser.ParseTrackLocation(line, &song));
EXPECT_EQ("/tmp/foo/bar.mp3", song.filename());
EXPECT_EQ("foo", song.title());
}
TEST_F(M3UParserTest, ParsesTrackLocationHttp) {
QString line("http://example.com/foo/bar.mp3");
QUrl url;
ASSERT_TRUE(parser_.ParseTrackLocation(line, &url));
EXPECT_EQ(QUrl("http://example.com/foo/bar.mp3"), url);
Song song;
ASSERT_TRUE(parser_.ParseTrackLocation(line, &song));
EXPECT_EQ("http://example.com/foo/bar.mp3", song.filename());
}
#ifdef Q_OS_WIN32
TEST_F(M3UParserTest, ParsesTrackLocationAbsoluteWindows) {
QString line("c:/foo/bar.mp3");
QUrl url;
ASSERT_TRUE(parser_.ParseTrackLocation(line, &url));
EXPECT_EQ(QUrl("file:///c:/foo/bar.mp3"), url);
}
#endif // Q_OS_WIN32
TEST_F(M3UParserTest, ParsesSongsFromDevice) {
QByteArray data = "#EXTM3U\n"
"#EXTINF:123,Some Artist - Some Title\n"
"foo/bar/somefile.mp3\n";
"http://foo.com/bar/somefile.mp3\n";
QBuffer buffer(&data);
buffer.open(QIODevice::ReadOnly);
M3UParser parser(&buffer, QDir("somedir"));
M3UParser parser(&buffer);
const QList<Song>& songs = parser.Parse();
ASSERT_EQ(1, songs.size());
Song s = songs[0];
@ -68,21 +71,21 @@ TEST_F(M3UParserTest, ParsesSongsFromDevice) {
EXPECT_EQ("Some Title", s.title());
EXPECT_EQ(123, s.length());
EXPECT_PRED_FORMAT2(::testing::IsSubstring,
"somedir/foo/bar/somefile.mp3", s.filename().toStdString());
"http://foo.com/bar/somefile.mp3", s.filename().toStdString());
}
TEST_F(M3UParserTest, ParsesNonExtendedM3U) {
QByteArray data = "foo/bar/somefile.mp3\n"
"baz/thing.mp3\n";
QByteArray data = "http://foo.com/bar/somefile.mp3\n"
"http://baz.com/thing.mp3\n";
QBuffer buffer(&data);
buffer.open(QIODevice::ReadOnly);
M3UParser parser(&buffer, QDir("somedir"));
const QList<Song>& songs = parser.Parse();
ASSERT_EQ(2, songs.size());
EXPECT_PRED_FORMAT2(::testing::IsSubstring,
"somedir/foo/bar/somefile.mp3", songs[0].filename().toStdString());
"http://foo.com/bar/somefile.mp3", songs[0].filename().toStdString());
EXPECT_PRED_FORMAT2(::testing::IsSubstring,
"somedir/baz/thing.mp3", songs[1].filename().toStdString());
"http://baz.com/thing.mp3", songs[1].filename().toStdString());
EXPECT_EQ(-1, songs[0].length());
EXPECT_EQ(-1, songs[1].length());
EXPECT_TRUE(songs[0].artist().isEmpty());