![]() |
Mixxx
|
00001 // 00002 // C++ Implementation: parserpls 00003 // 00004 // Description: module to parse pls formated playlists 00005 // 00006 // 00007 // Author: Ingo Kossyk <kossyki@cs.tu-berlin.de>, (C) 2004 00008 // Author: Tobias Rafreider trafreider@mixxx.org, (C) 2011 00009 // 00010 // Copyright: See COPYING file that comes with this distribution 00011 // 00012 // 00013 #include "parser.h" 00014 #include "parserpls.h" 00015 #include <QDebug> 00016 #include <QTextStream> 00017 #include <QMessageBox> 00018 #include <QDir> 00019 #include <QFile> 00020 #include <QUrl> 00021 00032 ParserPls::ParserPls() : Parser() 00033 { 00034 } 00035 00036 ParserPls::~ParserPls() 00037 { 00038 } 00039 00040 QList<QString> ParserPls::parse(QString sFilename) 00041 { 00042 //long numEntries =0; 00043 QFile file(sFilename); 00044 QString basepath = sFilename.section('/', 0, -2); 00045 00046 clearLocations(); 00047 00048 if (file.open(QIODevice::ReadOnly) && !isBinary(sFilename) ) { 00049 00050 /* Unfortunately, QT 4.7 does not handle <CR> (=\r or asci value 13) line breaks. 00051 * This is important on OS X where iTunes, e.g., exports M3U playlists using <CR> 00052 * rather that <LF> 00053 * 00054 * Using QFile::readAll() we obtain the complete content of the playlist as a ByteArray. 00055 * We replace any '\r' with '\n' if applicaple 00056 * This ensures that playlists from iTunes on OS X can be parsed 00057 */ 00058 QByteArray ba = file.readAll(); 00059 //detect encoding 00060 bool isCRLF_encoded = ba.contains("\r\n"); 00061 bool isCR_encoded = ba.contains("\r"); 00062 if(isCR_encoded && !isCRLF_encoded) 00063 ba.replace('\r','\n'); 00064 QTextStream textstream(ba.data()); 00065 00066 while(!textstream.atEnd()) { 00067 QString psLine = getFilepath(&textstream, basepath); 00068 if(psLine.isNull()) { 00069 break; 00070 } else { 00071 m_sLocations.append(psLine); 00072 } 00073 00074 } 00075 00076 file.close(); 00077 00078 if(m_sLocations.count() != 0) 00079 return m_sLocations; 00080 else 00081 return QList<QString>(); // NULL pointer returned when no locations were found 00082 } 00083 00084 file.close(); 00085 return QList<QString>(); //if we get here something went wrong :D 00086 } 00087 00088 long ParserPls::getNumEntries(QTextStream *stream) 00089 { 00090 00091 QString textline; 00092 textline = stream->readLine(); 00093 00094 if(textline.contains("[playlist]")){ 00095 00096 while(!textline.contains("NumberOfEntries")) 00097 textline = stream->readLine(); 00098 00099 QString temp = textline.section("=",-1,-1); 00100 00101 return temp.toLong(); 00102 00103 } else{ 00104 qDebug() << "ParserPls: pls file is not a playlist! \n"; 00105 return 0; 00106 } 00107 00108 } 00109 00110 00111 QString ParserPls::getFilepath(QTextStream *stream, QString basepath) 00112 { 00113 QString textline,filename = ""; 00114 textline = stream->readLine(); 00115 while(!textline.isEmpty()){ 00116 if(textline.isNull()) 00117 break; 00118 00119 if(textline.contains("File")) { 00120 int iPos = textline.indexOf("=",0); 00121 ++iPos; 00122 00123 filename = textline.right(textline.length()-iPos); 00124 00125 //Rythmbox playlists starts with file://<path> 00126 //We remove the file protocol if found. 00127 filename.remove("file://"); 00128 QByteArray strlocbytes = filename.toUtf8(); 00129 QUrl location = QUrl::fromEncoded(strlocbytes); 00130 QString trackLocation = location.toString(); 00131 //qDebug() << trackLocation; 00132 00133 if(isFilepath(trackLocation)) { 00134 return trackLocation; 00135 } else { 00136 // Try relative to m3u dir 00137 QString rel = basepath + "/" + trackLocation; 00138 if (isFilepath(rel)) { 00139 return rel; 00140 } 00141 // We couldn't match this to a real file so ignore it 00142 } 00143 } 00144 textline = stream->readLine(); 00145 } 00146 00147 // Signal we reached the end 00148 return 0; 00149 00150 } 00151 bool ParserPls::writePLSFile(QString &file_str, QList<QString> &items, bool useRelativePath) 00152 { 00153 QFile file(file_str); 00154 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)){ 00155 QMessageBox::warning(NULL,tr("Playlist Export Failed"), 00156 tr("Could not create file")+" "+file_str); 00157 return false; 00158 } 00159 //Base folder of file 00160 QString base = file_str.section('/', 0, -2); 00161 QDir base_dir(base); 00162 00163 QTextStream out(&file); 00164 out << "[playlist]\n"; 00165 out << "NumberOfEntries=" << items.size() << "\n"; 00166 for(int i =0; i < items.size(); ++i){ 00167 //Write relative path if possible 00168 if(useRelativePath){ 00169 //QDir::relativePath() will return the absolutePath if it cannot compute the 00170 //relative Path 00171 out << "File" << i << "=" << base_dir.relativeFilePath(items.at(i)) << "\n"; 00172 } 00173 else 00174 out << "File" << i << "=" << items.at(i) << "\n"; 00175 } 00176 00177 return true; 00178 }