Skip to content

Commit

Permalink
Merge pull request #2200 from uklotzde/2.2_fix_playlist_import
Browse files Browse the repository at this point in the history
lp 16878282: Fix playlist import
  • Loading branch information
daschuer authored Jul 6, 2019
2 parents 7fa0d3f + 9d5ed3a commit 3ae5a7b
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 82 deletions.
40 changes: 19 additions & 21 deletions src/library/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,32 +38,30 @@ long Parser::countParsed() {
}

bool Parser::isBinary(QString filename) {
char firstByte;
QFile file(filename);

if (file.open(QIODevice::ReadOnly)) {
char c;
unsigned char uc;

if(!file.getChar(&c))
{
qDebug() << "Parser: Error reading stream on " << filename;
return true; //should this raise an exception?
if (file.open(QIODevice::ReadOnly) && file.getChar(&firstByte)) {
// If starting byte is not an ASCII character then the file
// probably contains binary data.
if (firstByte >= 32 && firstByte <= 126) {
// Valid ASCII character
return false;
}

uc = uchar(c);

if(!(33<=uc && uc<=127)) //Starting byte is no character
{
file.close();
// Check for UTF-8 BOM
if (firstByte == static_cast<char>(0xEF)) {
char nextChar;
if (file.getChar(&nextChar) &&
nextChar == static_cast<char>(0xBB) &&
file.getChar(&nextChar) &&
nextChar == static_cast<char>(0xBF)) {
// UTF-8 text file
return false;
}
return true;
}

} else{
qDebug() << "Parser: Could not open file: " << filename;
}
//qDebug(QString("Parser: textstream starting character is: %1").arg(i));
file.close();
return false;
qDebug() << "Parser: Error reading from" << filename;
return true; //should this raise an exception?
}

// The following public domain code is taken from
Expand Down
113 changes: 52 additions & 61 deletions src/library/parserm3u.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,84 +47,75 @@ ParserM3u::~ParserM3u()

}


QList<QString> ParserM3u::parse(QString sFilename)
{
clearLocations();

QFile file(sFilename);
QString basepath = sFilename.section('/', 0, -2);
if (isBinary(sFilename) || !file.open(QIODevice::ReadOnly)) {
qWarning()
<< "Failed to open playlist file"
<< sFilename;
return m_sLocations;
}

clearLocations();
//qDebug() << "ParserM3u: Starting to parse.";
if (file.open(QIODevice::ReadOnly) && !isBinary(sFilename)) {
/* Unfortunately, QT 4.7 does not handle <CR> (=\r or asci value 13) line breaks.
* This is important on OS X where iTunes, e.g., exports M3U playlists using <CR>
* rather that <LF>
*
* Using QFile::readAll() we obtain the complete content of the playlist as a ByteArray.
* We replace any '\r' with '\n' if applicaple
* This ensures that playlists from iTunes on OS X can be parsed
*/
QByteArray ba = file.readAll();
//detect encoding
bool isCRLF_encoded = ba.contains("\r\n");
bool isCR_encoded = ba.contains("\r");
if(isCR_encoded && !isCRLF_encoded)
ba.replace('\r','\n');
QTextStream textstream(ba.constData());

if (isUtf8(ba.constData())) {
textstream.setCodec("UTF-8");
} else {
textstream.setCodec("windows-1252");
}
// Unfortunately QTextStream does not handle <CR> (=\r or asci value 13) line breaks.
// This is important on OS X where iTunes, e.g., exports M3U playlists using <CR>
// rather that <LF>.
//
// Using QFile::readAll() we obtain the complete content of the playlist as a ByteArray.
// We replace any '\r' with '\n' if applicaple
// This ensures that playlists from iTunes on OS X can be parsed
QByteArray ba = file.readAll();
//detect encoding
bool isCRLF_encoded = ba.contains("\r\n");
bool isCR_encoded = ba.contains("\r");
if (isCR_encoded && !isCRLF_encoded) {
ba.replace('\r', '\n');
}

while (!textstream.atEnd()) {
QString sLine = getFilepath(&textstream, basepath);
if (sLine.isEmpty()) {
continue;
}
//qDebug() << "ParserM3u: parsed: " << (sLine);
m_sLocations.append(sLine);
}
QTextStream textstream(ba.constData());
if (isUtf8(ba.constData())) {
textstream.setCodec("UTF-8");
} else {
textstream.setCodec("windows-1252");
}

file.close();
return m_sLocations;
const QString basepath = sFilename.section('/', 0, -2);
while (!textstream.atEnd()) {
QString sLine = getFilepath(&textstream, basepath);
if (sLine.isEmpty()) {
continue;
}
m_sLocations.append(sLine);
}

file.close();
return QList<QString>(); //if we get here something went wrong
return m_sLocations;
}


QString ParserM3u::getFilepath(QTextStream* stream, QString basepath) {
QString textline = stream->readLine();

while (!textline.isEmpty()) {
//qDebug() << "Untransofrmed text: " << textline;
if (textline.isNull()) {
break;
QString textline;
while (!(textline = stream->readLine().trimmed()).isEmpty()) {
if (textline.startsWith("#")) {
// Skip comments
continue;
}

if (!textline.contains("#")) {
QString trackLocation = playlistEntrytoLocalFile(textline);
if(QFile::exists(trackLocation)) {
return trackLocation;
} else {
// Try relative to m3u dir
QString rel = QDir(basepath).filePath(trackLocation);
if (QFile::exists(rel)) {
return rel;
}
// We couldn't match this to a real file so ignore it
qWarning() << trackLocation << "not found";
QString trackLocation = playlistEntrytoLocalFile(textline);
if (QFileInfo::exists(trackLocation)) {
return trackLocation;
} else {
// Try relative to m3u dir
QString rel = QDir(basepath).filePath(trackLocation);
if (QFile::exists(rel)) {
return rel;
}
// We couldn't match this to a real file so ignore it
qWarning() << trackLocation << "not found";
}
textline = stream->readLine();
}

// Signal we reached the end
return 0;

return QString();
}

bool ParserM3u::writeM3UFile(const QString &file_str, QList<QString> &items, bool useRelativePath) {
Expand Down

0 comments on commit 3ae5a7b

Please sign in to comment.