PageRenderTime 314ms CodeModel.GetById 40ms app.highlight 234ms RepoModel.GetById 28ms app.codeStats 0ms

/src/libtomahawk/utils/JspfLoader.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 231 lines | 168 code | 45 blank | 18 comment | 22 complexity | b6244219c2715e8169b237f8f0dcbe2b MD5 | raw file
  1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2 *
  3 *   Copyright 2010-2011, Leo Franchi <lfranchi@kde.org
  4 *   Copyright 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  5 *
  6 *   Tomahawk is free software: you can redistribute it and/or modify
  7 *   it under the terms of the GNU General Public License as published by
  8 *   the Free Software Foundation, either version 3 of the License, or
  9 *   (at your option) any later version.
 10 *
 11 *   Tomahawk is distributed in the hope that it will be useful,
 12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14 *   GNU General Public License for more details.
 15 *
 16 *   You should have received a copy of the GNU General Public License
 17 *   along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 18 */
 19
 20
 21#include "JspfLoader.h"
 22
 23#include "utils/Json.h"
 24#include "utils/Logger.h"
 25#include "utils/NetworkReply.h"
 26#include "utils/TomahawkUtils.h"
 27#include "utils/NetworkAccessManager.h"
 28
 29#include "Playlist.h"
 30#include "SourceList.h"
 31#include "Track.h"
 32
 33#include <QApplication>
 34#include <QDomDocument>
 35#include <QMessageBox>
 36
 37using namespace Tomahawk;
 38
 39
 40JSPFLoader::JSPFLoader( bool autoCreate, QObject* parent )
 41    : QObject( parent )
 42    , m_autoCreate( autoCreate )
 43    , m_autoDelete( true )
 44{
 45}
 46
 47
 48JSPFLoader::~JSPFLoader()
 49{
 50}
 51
 52
 53QList< Tomahawk::query_ptr >
 54JSPFLoader::entries() const
 55{
 56    return m_entries;
 57}
 58
 59
 60void
 61JSPFLoader::load( const QUrl& url )
 62{
 63    QNetworkRequest request( url );
 64
 65    Q_ASSERT( Tomahawk::Utils::nam() != 0 );
 66    NetworkReply* reply = new NetworkReply( Tomahawk::Utils::nam()->get( request ) );
 67
 68    connect( reply, SIGNAL( finished() ), SLOT( networkLoadFinished() ) );
 69    connect( reply, SIGNAL( error( QNetworkReply::NetworkError ) ), SLOT( networkError( QNetworkReply::NetworkError ) ) );
 70}
 71
 72
 73void
 74JSPFLoader::load( QFile& file )
 75{
 76    if ( file.open( QFile::ReadOnly ) )
 77    {
 78        m_body = file.readAll();
 79        gotBody();
 80    }
 81    else
 82    {
 83        tLog() << "Failed to open jspf file";
 84        reportError();
 85    }
 86}
 87
 88
 89void
 90JSPFLoader::reportError()
 91{
 92    emit failed();
 93
 94    if ( m_autoDelete )
 95        deleteLater();
 96}
 97
 98
 99void
100JSPFLoader::networkLoadFinished()
101{
102    NetworkReply* r = qobject_cast<NetworkReply*>( sender() );
103    r->deleteLater();
104
105    if ( r->reply()->error() == QNetworkReply::NoError )
106    {
107        m_body = r->reply()->readAll();
108        gotBody();
109    }
110}
111
112
113void
114JSPFLoader::networkError( QNetworkReply::NetworkError e )
115{
116    Q_UNUSED( e );
117
118    reportError();
119
120    NetworkReply* r = qobject_cast<NetworkReply*>( sender() );
121    r->deleteLater();
122}
123
124
125void
126JSPFLoader::gotBody()
127{
128    bool retOk;
129    QVariantMap wrapper = TomahawkUtils::parseJson( m_body, &retOk ).toMap();
130
131    if ( !retOk )
132    {
133        tLog() << "Failed to parse jspf json: " << m_body;
134        return;
135    }
136
137    if ( !wrapper.contains( "playlist" ) )
138    {
139        tLog() << "No playlist element in JSPF!";
140        return;
141    }
142
143    QVariantMap pl = wrapper.value( "playlist" ).toMap();
144    QString origTitle = pl.value( "title" ).toString();
145    m_info = pl.value( "info" ).toString();
146    m_creator = pl.value( "creator" ).toString();
147
148    m_title = origTitle;
149    if ( m_title.isEmpty() )
150        m_title = tr( "New Playlist" );
151    if ( !m_overrideTitle.isEmpty() )
152        m_title = m_overrideTitle;
153
154    if ( pl.contains( "track" ) )
155    {
156        QVariantList tracks = pl.value( "track" ).toList();
157
158        bool shownError = false;
159        foreach ( const QVariant& currentTrack, tracks )
160        {
161            QVariantMap tM = currentTrack.toMap();
162            QString artist, album, track, duration, annotation, url;
163
164            artist = tM.value( "creator" ).toString();
165            album = tM.value( "album" ).toString();
166            track = tM.value( "title" ).toString();
167            duration = tM.value( "duration" ).toString();
168            annotation = tM.value( "annotation" ).toString();
169            if ( tM.value( "location" ).toList().size() > 0 )
170                url = tM.value( "location" ).toList().first().toString();
171
172            if ( artist.isEmpty() || track.isEmpty() )
173            {
174                if ( !shownError )
175                {
176                    QMessageBox::warning( 0, tr( "Failed to save tracks" ), tr( "Some tracks in the playlist do not contain an artist and a title. They will be ignored." ), QMessageBox::Ok );
177                    shownError = true;
178                }
179                continue;
180            }
181
182            track_ptr t = Tomahawk::Track::get( artist, track, album, QString(), duration.toInt() / 1000 );
183            query_ptr q = Tomahawk::Query::get( t );
184            if ( !q )
185                continue;
186
187            if ( !url.isEmpty() )
188            {
189                q->setResultHint( url );
190                q->setSaveHTTPResultHint( true );
191            }
192
193            m_entries << q;
194        }
195    }
196
197    if ( origTitle.isEmpty() && m_entries.isEmpty() )
198    {
199        if ( m_autoCreate )
200        {
201            QMessageBox::critical( 0, tr( "XSPF Error" ), tr( "This is not a valid XSPF playlist." ) );
202            return;
203        }
204        else
205        {
206            emit failed();
207            return;
208        }
209    }
210
211    if ( m_autoCreate )
212    {
213        m_playlist = Playlist::create( SourceList::instance()->getLocal(),
214                                       uuid(),
215                                       m_title,
216                                       m_info,
217                                       m_creator,
218                                       false,
219                                       m_entries );
220        emit ok( m_playlist );
221    }
222    else
223    {
224        if ( !m_entries.isEmpty() )
225            emit tracks( m_entries );
226    }
227
228
229    if ( m_autoDelete )
230        deleteLater();
231}