~shanx-shashank/mixxx/effects_ladspa

« back to all changes in this revision

Viewing changes to mixxx/src/library/parserm3u.cpp

  • Committer: shanxS
  • Date: 2013-06-16 07:42:19 UTC
  • Revision ID: shanx.shashank@gmail.com-20130616074219-wszmk0slwfa1z61q
Init Repository.
Starting with GUI of lp:~shanx-shashank/mixxx/effects_parametricEq as base

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// C++ Implementation: parserm3u
 
3
//
 
4
// Description: module to parse m3u(plaintext) formated playlists
 
5
//
 
6
//
 
7
// Author: Ingo Kossyk <kossyki@cs.tu-berlin.de>, (C) 2004
 
8
// Author: Tobias Rafreider trafreider@mixxx.org, (C) 2011
 
9
//
 
10
// Copyright: See COPYING file that comes with this distribution
 
11
//
 
12
//
 
13
#include <QTextStream>
 
14
#include <QDebug>
 
15
#include <QDir>
 
16
#include <QMessageBox>
 
17
#include "parserm3u.h"
 
18
#include <QUrl>
 
19
#include <QTextCodec>
 
20
 
 
21
/**
 
22
   @author Ingo Kossyk (kossyki@cs.tu-berlin.de)
 
23
 **/
 
24
 
 
25
/**
 
26
   ToDo:
 
27
    - parse ALL informations from the pls file if available ,
 
28
          not only the filepath;
 
29
 
 
30
          Userinformation :
 
31
          The M3U format is just a headerless plaintext format
 
32
          where every line of text either represents
 
33
          a file location or a comment. comments are being
 
34
          preceeded by a '#'. This parser will try to parse all
 
35
          file information from the given file and add the filepaths
 
36
          to the locations ptrlist when the file is existing locally
 
37
          or on a mounted harddrive.
 
38
 **/
 
39
 
 
40
ParserM3u::ParserM3u() : Parser()
 
41
{
 
42
}
 
43
 
 
44
ParserM3u::~ParserM3u()
 
45
{
 
46
 
 
47
}
 
48
 
 
49
 
 
50
QList<QString> ParserM3u::parse(QString sFilename)
 
51
{
 
52
    QFile file(sFilename);
 
53
    QString basepath = sFilename.section('/', 0, -2);
 
54
 
 
55
    clearLocations();
 
56
    //qDebug() << "ParserM3u: Starting to parse.";
 
57
    if (file.open(QIODevice::ReadOnly) && !isBinary(sFilename)) {
 
58
        /* Unfortunately, QT 4.7 does not handle <CR> (=\r or asci value 13) line breaks.
 
59
         * This is important on OS X where iTunes, e.g., exports M3U playlists using <CR>
 
60
         * rather that <LF>
 
61
         *
 
62
         * Using QFile::readAll() we obtain the complete content of the playlist as a ByteArray.
 
63
         * We replace any '\r' with '\n' if applicaple
 
64
         * This ensures that playlists from iTunes on OS X can be parsed
 
65
         */
 
66
        QByteArray ba = file.readAll();
 
67
        //detect encoding
 
68
        bool isCRLF_encoded = ba.contains("\r\n");
 
69
        bool isCR_encoded = ba.contains("\r");
 
70
        if(isCR_encoded && !isCRLF_encoded)
 
71
            ba.replace('\r','\n');
 
72
        QTextStream textstream(ba.data());
 
73
 
 
74
        if (isUtf8(ba.data())) {
 
75
            textstream.setCodec("UTF-8");
 
76
        } else {
 
77
            textstream.setCodec("windows-1252");
 
78
        }
 
79
 
 
80
        while(!textstream.atEnd()) {
 
81
            QString sLine = getFilepath(&textstream, basepath);
 
82
            if(sLine.isEmpty())
 
83
                break;
 
84
 
 
85
            //qDebug() << "ParserM3u: parsed: " << (sLine);
 
86
            m_sLocations.append(sLine);
 
87
        }
 
88
 
 
89
        file.close();
 
90
 
 
91
        if(m_sLocations.count() != 0)
 
92
            return m_sLocations;
 
93
        else
 
94
            return QList<QString>(); // NULL pointer returned when no locations were found
 
95
 
 
96
    }
 
97
 
 
98
    file.close();
 
99
    return QList<QString>(); //if we get here something went wrong
 
100
}
 
101
 
 
102
 
 
103
QString ParserM3u::getFilepath(QTextStream *stream, QString basepath)
 
104
{
 
105
    QString textline,filename = "";
 
106
 
 
107
    textline = stream->readLine();
 
108
 
 
109
    while(!textline.isEmpty()){
 
110
        //qDebug() << "Untransofrmed text: " << textline;
 
111
        if(textline.isNull())
 
112
            break;
 
113
 
 
114
        if(!textline.contains("#")){
 
115
            filename = textline;
 
116
            filename.remove("file://");
 
117
            QByteArray strlocbytes = filename.toUtf8();
 
118
            //qDebug() << "QByteArray UTF-8: " << strlocbytes;
 
119
            QUrl location = QUrl::fromEncoded(strlocbytes);
 
120
            //qDebug() << "QURL UTF-8: " << location;
 
121
            QString trackLocation = location.toString();
 
122
            //qDebug() << "UTF8 TrackLocation:" << trackLocation;
 
123
            if(isFilepath(trackLocation)) {
 
124
                return trackLocation;
 
125
            } else {
 
126
                // Try relative to m3u dir
 
127
                QString rel = basepath + "/" + trackLocation;
 
128
                if (isFilepath(rel)) {
 
129
                    return rel;
 
130
                }
 
131
                // We couldn't match this to a real file so ignore it
 
132
            }
 
133
        }
 
134
        textline = stream->readLine();
 
135
    }
 
136
 
 
137
    // Signal we reached the end
 
138
    return 0;
 
139
 
 
140
}
 
141
 
 
142
bool ParserM3u::writeM3UFile(const QString &file_str, QList<QString> &items, bool useRelativePath) {
 
143
    return writeM3UFile(file_str, items, useRelativePath, false);
 
144
}
 
145
 
 
146
bool ParserM3u::writeM3U8File(const QString &file_str, QList<QString> &items, bool useRelativePath) {
 
147
    return writeM3UFile(file_str, items, useRelativePath, true);
 
148
}
 
149
 
 
150
bool ParserM3u::writeM3UFile(const QString &file_str, QList<QString> &items, bool useRelativePath, bool useUtf8)
 
151
{
 
152
    // Important note:
 
153
    // On Windows \n will produce a <CR><CL> (=\r\n)
 
154
    // On Linux and OS X \n is <CR> (which remains \n)
 
155
 
 
156
    QTextCodec* codec;
 
157
    if (useUtf8) {
 
158
        codec = QTextCodec::codecForName("UTF-8");
 
159
    } else {
 
160
        // according to http://en.wikipedia.org/wiki/M3U the default encoding of m3u is Windows-1252
 
161
        // see also http://tools.ietf.org/html/draft-pantos-http-live-streaming-07
 
162
        // check if the all items can be properly encoded to Latin1.
 
163
        codec = QTextCodec::codecForName("windows-1252");
 
164
        for (int i = 0; i < items.size(); ++i) {
 
165
            if (!codec->canEncode(items.at(i))) {
 
166
                // filepath contains incompatible character
 
167
                QMessageBox::warning(NULL,tr("Playlist Export Failed"),
 
168
                                     tr("File path contains characters, not allowed in m3u playlists.\n") +
 
169
                                     tr("Export a m3u8 playlist instead!\n") +
 
170
                                     items.at(i));
 
171
                return false;
 
172
            }
 
173
        }
 
174
    }
 
175
 
 
176
    QFile file(file_str);
 
177
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
 
178
        QMessageBox::warning(NULL,tr("Playlist Export Failed"),
 
179
                             tr("Could not create file") + " " + file_str);
 
180
        return false;
 
181
    }
 
182
 
 
183
    // Base folder of file
 
184
    QString base = file_str.section('/', 0, -2);
 
185
    QDir base_dir(base);
 
186
 
 
187
    qDebug() << "Basepath: " << base;
 
188
    QTextStream out(&file);
 
189
    out.setCodec(codec);
 
190
    out << "#EXTM3U\n";
 
191
    for (int i = 0; i < items.size(); ++i) {
 
192
        out << "#EXTINF\n";
 
193
        // Write relative path if possible
 
194
        if (useRelativePath) {
 
195
            //QDir::relativePath() will return the absolutePath if it cannot compute the
 
196
            //relative Path
 
197
            out << base_dir.relativeFilePath(items.at(i)) << "\n";
 
198
        } else {
 
199
            out << items.at(i) << "\n";
 
200
        }
 
201
    }
 
202
    return true;
 
203
}