Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/library/parserpls.cpp

Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines